blob: 690274473fff1914040a20d15800d1b0047f3ce7 [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;
Vadim Yanitskiy5eb06a32022-06-23 18:39:46 +070024friend module BSC_Tests_CBSP;
Vadim Yanitskiy3cc065b2023-01-06 21:35:12 +070025friend module BSC_Tests_LCLS;
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020026
Neels Hofmeyr4f118412020-06-04 15:25:10 +020027import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010028import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010029import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010030import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010031import from IPL4asp_Types all;
32
Harald Welte6f521d82017-12-11 19:52:02 +010033import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020034import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020035import from BSSAP_LE_Adapter all;
36import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020037import from BSSAP_LE_Types all;
38import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010039import from BSSAP_CodecPort all;
40import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010041import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010042import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010043import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020044import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010045import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010046import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010047import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010048import from MGCP_Templates all;
49import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020050import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010051
Harald Welte96c94412017-12-09 03:12:45 +010052import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010053import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010054import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010055
Daniel Willmannebdecc02020-08-12 15:30:17 +020056import from StatsD_Types all;
57import from StatsD_CodecPort all;
58import from StatsD_CodecPort_CtrlFunct all;
59import from StatsD_Checker all;
60
Harald Weltebc03c762018-02-12 18:09:38 +010061import from Osmocom_VTY_Functions all;
62import from TELNETasp_PortType all;
63
Harald Welte6f521d82017-12-11 19:52:02 +010064import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010065import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010066import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010067import from L3_Templates all;
68import from GSM_RR_Types all;
69
Stefan Sperlingc307e682018-06-14 15:15:46 +020070import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010071import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020072import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010073
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010074import from SCCPasp_Types all;
75
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020076import from GSM_SystemInformation all;
77import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020078import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020079
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060080const integer NUM_TRX := 4;
Harald Welte5d1a2202017-12-13 19:51:29 +010081const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020082const integer NUM_BTS_CFG := 4; /* we have 4 BTS in the osmo-bsc.cfg (for inter-BSC HO tests) but use only 3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060083const integer NUM_TRX_CFG := 1; /* we support up to 4 TRX per BTS, but have only 1 TRX per BTS in osmo-bsc.cfg */
Neels Hofmeyrf246a922020-05-13 02:27:10 +020084const integer NUM_MSC := 3;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020085const integer NUM_MGW := 2;
Harald Welteae026692017-12-09 01:03:01 +010086const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010087
Harald Welte799c97b2017-12-14 17:50:30 +010088/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020089const integer NUM_TCHH_PER_BTS := 2;
90const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020091const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010092
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060093friend type record BtsTrxIdx {
94 uint8_t bts,
95 uint8_t trx
96}
97
98private type record BtsParams {
99 integer trx_num,
100 integer tsc
101}
102
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200103/* Default Training Sequence Code expected for bts[i]:
104 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
105 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
106 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
107 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
108 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600109private const BtsParams c_BtsParams[NUM_BTS_CFG] := {
110 /* BTS0 */ { trx_num := 1, tsc := 2 },
111 /* BTS1 */ { trx_num := 1, tsc := 3 },
Vadim Yanitskiy7a3d2932022-05-29 20:37:46 +0600112 /* BTS2 */ { trx_num := 4, tsc := 4 },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600113 /* BTS3 */ { trx_num := 1, tsc := 4 }
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200114}
Harald Welte4003d112017-12-09 22:35:39 +0100115
Vadim Yanitskiy59494702022-09-14 15:29:04 +0700116private const RSL_IE_Body c_mr_conf_5_90 :=
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +0200117 valueof(RSL_IE_Body:{multirate_cfg := ts_RSL_MultirateCfg(true, 0, '00000100'B /* 5,90k */)});
118
Harald Welte21b46bd2017-12-17 19:46:32 +0100119/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100120type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100121 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100122 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100123}
124
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200125/* Default list of counters for an 'msc' entity. */
126const CounterNameVals counternames_msc_mscpool := {
127 { "mscpool:subscr:new", 0 },
128 { "mscpool:subscr:known", 0 },
129 { "mscpool:subscr:reattach", 0 },
130 { "mscpool:subscr:attach_lost", 0 },
131 { "mscpool:subscr:paged", 0 }
132};
133
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000134/* List of global mscpool counters, not related to a specific 'msc' entity. */
135const CounterNameVals counternames_bsc_mscpool := {
136 { "mscpool:subscr:no_msc", 0 }
137};
138
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000139/* Default list of counters for 'bsc' and 'bts' entities. */
140const CounterNameVals counternames_bsc_bts_handover := {
141 { "assignment:attempted", 0 },
142 { "assignment:completed", 0 },
143 { "assignment:stopped", 0 },
144 { "assignment:no_channel", 0 },
145 { "assignment:timeout", 0 },
146 { "assignment:failed", 0 },
147 { "assignment:error", 0 },
148
149 { "handover:attempted", 0 },
150 { "handover:completed", 0 },
151 { "handover:stopped", 0 },
152 { "handover:no_channel", 0 },
153 { "handover:timeout", 0 },
154 { "handover:failed", 0 },
155 { "handover:error", 0 },
156
157 { "intra_cell_ho:attempted", 0 },
158 { "intra_cell_ho:completed", 0 },
159 { "intra_cell_ho:stopped", 0 },
160 { "intra_cell_ho:no_channel", 0 },
161 { "intra_cell_ho:timeout", 0 },
162 { "intra_cell_ho:failed", 0 },
163 { "intra_cell_ho:error", 0 },
164
165 { "intra_bsc_ho:attempted", 0 },
166 { "intra_bsc_ho:completed", 0 },
167 { "intra_bsc_ho:stopped", 0 },
168 { "intra_bsc_ho:no_channel", 0 },
169 { "intra_bsc_ho:timeout", 0 },
170 { "intra_bsc_ho:failed", 0 },
171 { "intra_bsc_ho:error", 0 },
172
173 { "interbsc_ho_out:attempted", 0 },
174 { "interbsc_ho_out:completed", 0 },
175 { "interbsc_ho_out:stopped", 0 },
176 { "interbsc_ho_out:timeout", 0 },
177 { "interbsc_ho_out:failed", 0 },
178 { "interbsc_ho_out:error", 0 },
179
180 { "interbsc_ho_in:attempted", 0 },
181 { "interbsc_ho_in:completed", 0 },
182 { "interbsc_ho_in:stopped", 0 },
183 { "interbsc_ho_in:no_channel", 0 },
184 { "interbsc_ho_in:timeout", 0 },
185 { "interbsc_ho_in:failed", 0 },
186 { "interbsc_ho_in:error", 0 }
187};
188
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100189const CounterNameVals counternames_bts_handover := {
190 { "incoming_intra_bsc_ho:attempted", 0 },
191 { "incoming_intra_bsc_ho:completed", 0 },
192 { "incoming_intra_bsc_ho:stopped", 0 },
193 { "incoming_intra_bsc_ho:no_channel", 0 },
194 { "incoming_intra_bsc_ho:timeout", 0 },
195 { "incoming_intra_bsc_ho:failed", 0 },
196 { "incoming_intra_bsc_ho:error", 0 }
197};
198
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200199/* Set of all System Information received during one RSL port's startup.
200 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
201 * broadcast that SI type. That will be reflected as 'omit' here.
202 */
203type record SystemInformationConfig {
204 SystemInformationType1 si1 optional,
205 SystemInformationType2 si2 optional,
206 SystemInformationType2bis si2bis optional,
207 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200208 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200209 SystemInformationType3 si3 optional,
210 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100211 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200212 SystemInformationType5 si5 optional,
213 SystemInformationType5bis si5bis optional,
214 SystemInformationType5ter si5ter optional,
215 SystemInformationType6 si6 optional
216};
217
218const SystemInformationConfig SystemInformationConfig_omit := {
219 si1 := omit,
220 si2 := omit,
221 si2bis := omit,
222 si2ter := omit,
223 si2quater := omit,
224 si3 := omit,
225 si4 := omit,
226 si13 := omit,
227 si5 := omit,
228 si5bis := omit,
229 si5ter := omit,
230 si6 := omit
231};
232
233/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
234template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
235 template uint3_t meas_bw := 3)
236:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
237 meas_bw_presence := '1'B,
238 meas_bw := meas_bw);
239
240/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200241template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200242 template uint3_t prio := 3,
243 template (present) uint5_t thresh_high := 20,
244 template uint5_t thresh_low := 10,
245 template uint5_t qrxlevmin := 22)
246:= tr_EUTRAN_NeighbourCells(
247 cell_desc_list := cell_desc_list,
248 prio_presence := '1'B,
249 prio := prio,
250 thresh_high := thresh_high,
251 thresh_low_presence := '1'B,
252 thresh_low := thresh_low,
253 qrxlevmin_presence := '1'B,
254 qrxlevmin := qrxlevmin);
255
256template SystemInformationConfig SystemInformationConfig_default := {
257 si1 := {
258 cell_chan_desc := '8FB38000000000000000000000000000'O,
259 rach_control := {
260 max_retrans := RACH_MAX_RETRANS_7,
261 tx_integer := '1001'B,
262 cell_barr_access := false,
263 re_not_allowed := true,
264 acc := '0000010000000000'B
265 },
266 rest_octets := ?
267 },
268 si2 := {
269 bcch_freq_list := '00000000000000000000000000000000'O,
270 ncc_permitted := '11111111'B,
271 rach_control := {
272 max_retrans := RACH_MAX_RETRANS_7,
273 tx_integer := '1001'B,
274 cell_barr_access := false,
275 re_not_allowed := true,
276 acc := '0000010000000000'B
277 }
278 },
279 si2bis := omit,
280 si2ter := {
281 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
282 rest_octets := ?
283 },
284 si2quater := {
285 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
286 },
287 si3 := {
288 cell_id := 0,
289 lai := {
290 mcc_mnc := '001F01'H,
291 lac := 1
292 },
293 ctrl_chan_desc := {
294 msc_r99 := true,
295 att := true,
296 bs_ag_blks_res := 1,
297 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
298 si22ind := false,
299 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
300 spare := '00'B,
301 bs_pa_mfrms := 3,
302 t3212 := 30
303 },
304 cell_options := {
305 dn_ind := false,
306 pwrc := false,
307 dtx := MS_SHALL_USE_UL_DTX,
308 radio_link_tout_div4 := 7
309 },
310 cell_sel_par := {
311 cell_resel_hyst_2dB := 2,
312 ms_txpwr_max_cch := 7,
313 acs := '0'B,
314 neci := true,
315 rxlev_access_min := 0
316 },
317 rach_control := {
318 max_retrans := RACH_MAX_RETRANS_7,
319 tx_integer := '1001'B,
320 cell_barr_access := false,
321 re_not_allowed := true,
322 acc := '0000010000000000'B
323 },
324 rest_octets := {
325 sel_params := {
326 presence := '0'B,
327 params := omit
328 },
329 pwr_offset := {
330 presence := '0'B,
331 offset := omit
332 },
333 si_2ter_ind := '1'B,
334 early_cm_ind := '0'B,
335 sched_where := {
336 presence := '0'B,
337 where := omit
338 },
339 gprs_ind := {
340 presence := '1'B,
341 ind := {
342 ra_colour := 0,
343 si13_pos := '0'B
344 }
345 },
346 umts_early_cm_ind := '1'B,
347 si2_quater_ind := {
348 presence := '1'B,
349 ind := '0'B
350 },
351 iu_mode_ind := omit,
352 si21_ind := {
353 presence := '0'B,
354 pos := omit
355 }
356 }
357 },
358 si4 := {
359 lai := {
360 mcc_mnc := '001F01'H,
361 lac := 1
362 },
363 cell_sel_par := {
364 cell_resel_hyst_2dB := 2,
365 ms_txpwr_max_cch := 7,
366 acs := '0'B,
367 neci := true,
368 rxlev_access_min := 0
369 },
370 rach_control := {
371 max_retrans := RACH_MAX_RETRANS_7,
372 tx_integer := '1001'B,
373 cell_barr_access := false,
374 re_not_allowed := true,
375 acc := '0000010000000000'B
376 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200377 cbch_chan_desc := {
378 iei := '64'O,
379 v := {
380 chan_nr := {
381 u := {
382 sdcch4 := {
383 tag := '001'B,
384 sub_chan := 2
385 }
386 },
387 tn := 0
388 },
389 tsc := 2,
390 h := false,
391 arfcn := 871,
392 maio_hsn := omit
393 }
394 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200395 cbch_mobile_alloc := omit,
396 rest_octets := {
397 sel_params := {
398 presence := '0'B,
399 params := omit
400 },
401 pwr_offset := {
402 presence := '0'B,
403 offset := omit
404 },
405 gprs_ind := {
406 presence := '1'B,
407 ind := {
408 ra_colour := 0,
409 si13_pos := '0'B
410 }
411 },
412 s_presence := '0'B,
413 s := omit
414 }
415 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100416 si13 := {
417 rest_octets := {
418 presence := '1'B,
419 bcch_change_mark := ?,
420 si_change_field := '0000'B,
421 presence2 := '0'B,
422 si13_change_mark := omit,
423 gprs_ma := omit,
424 zero := '0'B, /* PBCCH not present in cell */
425 rac := 0,
426 spgc_ccch_sup := '0'B,
427 priority_access_thr := '110'B,
428 network_control_order := '00'B,
429 gprs_cell_opts := {
430 nmo := '01'B,
431 t3168 := '011'B,
432 t3192 := '010'B,
433 drx_timer_max := '011'B,
434 access_burst_type := '0'B,
435 control_ack_type := '1'B,
436 bs_cv_max := 15,
437 pan_presence := '1'B,
438 pan_dec := 1,
439 pan_inc := 1,
440 pan_max := '111'B,
441 ext_info_presence := ?,
442 ext_info_length := *,
443 ext_info := *
444 },
445 gprs_pwr_ctrl_params := {
446 alpha := 0,
447 t_avg_w := '10000'B,
448 t_avg_t := '10000'B,
449 pc_meas_chan := '0'B,
450 n_avg_i := '1000'B
451 }
452 }
453 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200454 si5 := {
455 bcch_freq_list := '10000000000000000000000000000000'O
456 },
457 si5bis := omit,
458 si5ter := {
459 extd_bcch_freq_list := '9E050020000000000000000000000000'O
460 },
461 si6 := {
462 cell_id := 0,
463 lai := {
464 mcc_mnc := '001F01'H,
465 lac := 1
466 },
467 cell_options := {
468 dtx_ext := '1'B,
469 pwrc := false,
470 dtx := '01'B,
471 radio_link_timeout := '0111'B
472 },
473 ncc_permitted := '11111111'B,
Vadim Yanitskiy348b07c2022-03-10 17:11:22 +0300474 rest_octets := {
475 pch_nch_info := ?,
476 vbs_vgcs_options := ?,
477 dtm_support := '0'B,
478 rac := omit,
479 max_lapdm := omit,
480 band_ind := '0'B /* C0 ARFCN indicates 1800 band */
481 }
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200482 }
483 };
484
485
486/* List of all the System Information received on all RSL ports */
487type record of SystemInformationConfig SystemInformationConfig_list;
488
489function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
490{
491 var RSL_IE_Body sysinfo_type_ie;
492 var RSL_IE_SysinfoType si_type;
493 var octetstring data;
494
495 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
496 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
497 mtc.stop;
498 }
499 si_type := sysinfo_type_ie.sysinfo_type;
500
501 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
502 var RSL_IE_Body bcch_ie;
503 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
504 data := bcch_ie.other.payload;
505 }
506 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
507 var RSL_IE_Body l3_ie;
508 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
509 data := l3_ie.l3_info.payload;
510 }
511 } else {
512 setverdict(fail, "Don't understand this System Information message");
513 mtc.stop;
514 }
515
516 var boolean handled := false;
517
518 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
519 handled := true;
520
521 if (si_type == RSL_SYSTEM_INFO_1) {
522 if (not isbound(data)) {
523 si.si1 := omit;
524 } else {
525 si.si1 := dec_SystemInformation(data).payload.si1;
526 }
527 } else if (si_type == RSL_SYSTEM_INFO_2) {
528 if (not isbound(data)) {
529 si.si2 := omit;
530 } else {
531 si.si2 := dec_SystemInformation(data).payload.si2;
532 }
533 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
534 if (not isbound(data)) {
535 si.si2bis := omit;
536 } else {
537 si.si2bis := dec_SystemInformation(data).payload.si2bis;
538 }
539 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
540 if (not isbound(data)) {
541 si.si2ter := omit;
542 } else {
543 si.si2ter := dec_SystemInformation(data).payload.si2ter;
544 }
545 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
546 if (not isbound(data)) {
547 si.si2quater := {};
548 } else {
549 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
550 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
551 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
552 }
553 } else if (si_type == RSL_SYSTEM_INFO_3) {
554 if (not isbound(data)) {
555 si.si3 := omit;
556 } else {
557 si.si3 := dec_SystemInformation(data).payload.si3;
558 }
559 } else if (si_type == RSL_SYSTEM_INFO_4) {
560 if (not isbound(data)) {
561 si.si4 := omit;
562 } else {
563 si.si4 := dec_SystemInformation(data).payload.si4;
564 }
565 } else if (si_type == RSL_SYSTEM_INFO_13) {
566 if (not isbound(data)) {
567 si.si13 := omit;
568 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100569 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200570 }
571 } else {
572 handled := false;
573 }
574 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
575 handled := true;
576
577 if (si_type == RSL_SYSTEM_INFO_5) {
578 if (not isbound(data)) {
579 si.si5 := omit;
580 } else {
581 si.si5 := dec_SystemInformation(data).payload.si5;
582 }
583 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
584 if (not isbound(data)) {
585 si.si5bis := omit;
586 } else {
587 si.si5bis := dec_SystemInformation(data).payload.si5bis;
588 }
589 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
590 if (not isbound(data)) {
591 si.si5ter := omit;
592 } else {
593 si.si5ter := dec_SystemInformation(data).payload.si5ter;
594 }
595 } else if (si_type == RSL_SYSTEM_INFO_6) {
596 if (not isbound(data)) {
597 si.si6 := omit;
598 } else {
599 si.si6 := dec_SystemInformation(data).payload.si6;
600 }
601 } else {
602 handled := false;
603 }
604 }
605
606 if (not handled) {
607 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
608 }
609}
610
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +0100611friend function gen_l3_valid_payload(hexstring imsi := ''H) return octetstring {
612 var octetstring l3_payload;
613 if (lengthof(imsi) == 0) {
614 imsi := f_rnd_imsi('00101'H);
615 }
616 l3_payload := enc_PDU_ML3_MS_NW(valueof(ts_LU_REQ(LU_Type_IMSI_Attach, ts_MI_LV(ts_MI_IMSI(imsi)))));
617 return l3_payload;
618}
619
Harald Weltea4ca4462018-02-09 00:17:14 +0100620type component test_CT extends CTRL_Adapter_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600621 /* Array of per-BTS/TRX state */
622 var BTS_State bts[NUM_BTS][NUM_TRX];
Harald Welte89ab1912018-02-23 18:56:29 +0100623 /* RSL common Channel Port (for RSL_Emulation) */
624 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600625 /* array of per-BTS/TRX RSL test ports */
626 port IPA_RSL_PT IPA_RSL[NUM_BTS][NUM_TRX];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100627 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200628 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
629 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200630 /* Configure/manage IPA_Emulation per-BTS/TRX port: */
631 port IPA_CFG_PT IPA_CFG_PORT[NUM_BTS][NUM_TRX];
Harald Weltea5d2ab22017-12-09 14:21:42 +0100632
Pau Espin Pedrol3c630532022-10-20 19:00:11 +0200633 var MGCP_Emulation_CT vc_MGCP[NUM_MGW];
634 var integer g_nr_mgw; /* number of vc_MGCP to initialize */
Harald Weltebc03c762018-02-12 18:09:38 +0100635 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100636
Daniel Willmannebdecc02020-08-12 15:30:17 +0200637 /* StatsD */
638 var StatsD_Checker_CT vc_STATSD;
639
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200640 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200641 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100642 /* for old legacy-tests only */
643 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200644 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100645
Harald Welte21b46bd2017-12-17 19:46:32 +0100646 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100647 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100648
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200649 /* Osmux is enabled through VTY */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200650 var boolean g_osmux_enabled_cn := false;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +0200651 var boolean g_osmux_enabled_bts := false;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200652
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100653 /*Configure T(tias) over VTY, seconds */
654 var integer g_bsc_sccp_timer_ias := 7 * 60;
655 /*Configure T(tiar) over VTY, seconds */
656 var integer g_bsc_sccp_timer_iar := 15 * 60;
657
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200658 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100659 timer T_guard := 30.0;
660
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200661 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000662 var CounterNameValsList g_ctr_bsc;
663 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200664
665 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
666 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100667}
668
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200669type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100670modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100671 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100672 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100673 /* port number to which to establish the IPA OML connections */
674 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100675 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100676 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100677 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100678 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200679 /* port number to which to listen for STATSD metrics */
680 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100681 /* IP address at which the test binds */
682 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100683
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200684 RAN_Configurations mp_bssap_cfg := {
685 {
686 transport := BSSAP_TRANSPORT_AoIP,
687 sccp_service_type := "mtp3_itu",
688 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
689 own_pc := 185, /* 0.23.1 first MSC emulation */
690 own_ssn := 254,
691 peer_pc := 187, /* 0.23.3 osmo-bsc */
692 peer_ssn := 254,
693 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200694 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200695 },
696 {
697 transport := BSSAP_TRANSPORT_AoIP,
698 sccp_service_type := "mtp3_itu",
699 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
700 own_pc := 2, /* 0.0.2 second MSC emulation */
701 own_ssn := 254,
702 peer_pc := 187, /* 0.23.3 osmo-bsc */
703 peer_ssn := 254,
704 sio := '83'O,
705 rctx := 2
706 },
707 {
708 transport := BSSAP_TRANSPORT_AoIP,
709 sccp_service_type := "mtp3_itu",
710 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
711 own_pc := 3, /* 0.0.3 third MSC emulation */
712 own_ssn := 254,
713 peer_pc := 187, /* 0.23.3 osmo-bsc */
714 peer_ssn := 254,
715 sio := '83'O,
716 rctx := 3
717 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100718 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200719
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200720 /* Must match per BTS config in osmo-bsc.cfg */
721 phys_chan_configs phys_chan_config := {
722 "CCCH+SDCCH4+CBCH",
723 "TCH/F",
724 "TCH/F",
725 "TCH/F",
726 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600727 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200728 "PDCH",
729 "PDCH"
730 };
731
Harald Welte47cd0e32020-08-21 12:39:11 +0200732 BSSAP_LE_Configuration mp_bssap_le_cfg := {
733 sccp_service_type := "mtp3_itu",
734 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200735 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200736 own_ssn := 252, /* SMLC side SSN */
737 peer_pc := 187, /* 0.23.3 osmo-bsc */
738 peer_ssn := 250, /* BSC side SSN */
739 sio := '83'O,
740 rctx := 6
741 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200742 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200743
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100744 /* Value set in osmo-bsc.cfg "ms max power" */
745 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600746
747 /* Whether to check for memory leaks */
748 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100749}
750
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200751friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200752
753 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200754 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200755 pars.aoip := true;
756 } else {
757 pars.aoip := false;
758 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100759 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200760 pars.mscpool.bssap_idx := bssap_idx;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600761 pars.expect_tsc := c_BtsParams[0].tsc;
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300762 pars.imsi := f_rnd_imsi('00101'H);
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +0100763 pars.imei := f_rnd_imei('00101'H);
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300764
765 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200766
Philipp Maier48604732018-10-09 15:00:37 +0200767 return pars;
768}
769
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200770/* Convenience functions for rate counters using g_ctr_msc. */
771
772private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
773 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
774 log("initial msc rate counters: ", g_ctr_msc);
775}
776
777private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200778 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200779}
780
781/* f_ctrs_msc_init();
782 * f_do_thing(on_msc := 0);
783 * f_do_thing(on_msc := 0);
784 * f_do_other(on_msc := 1);
785 * f_ctrs_msc_add(0, "thing", 2);
786 * f_ctrs_msc_add(1, "other");
787 * f_ctrs_msc_verify();
788 */
789private function f_ctrs_msc_verify() runs on test_CT {
790 log("verifying msc rate counters: ", g_ctr_msc);
791 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
792}
793
794/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
795 * f_ctrs_msc_init();
796 * f_do_thing(on_msc := 0);
797 * f_do_thing(on_msc := 0);
798 * f_do_thing(on_msc := 0);
799 * f_ctrs_msc_expect(0, "thing", 3);
800 */
801private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
802 f_ctrs_msc_add(msc_nr, countername, val);
803 f_ctrs_msc_verify();
804}
805
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000806/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
807
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100808private 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 +0000809 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100810 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100811}
812
813function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
814 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000815 f_ctrs_bsc_init(counternames);
816}
817
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100818private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
819 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100820 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100821 f_ctrs_bsc_init(counternames_bsc_bts_handover);
822}
823
824private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000825 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100826}
827
828private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
829 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000830 f_ctrs_bsc_add(countername, val);
831}
832
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100833function f_ctrs_bts_verify() runs on test_CT {
834 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
835}
836
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000837/* f_ctrs_bsc_and_bts_init();
838 * f_do_thing(on_bts := 0);
839 * f_do_thing(on_bts := 0);
840 * f_do_other(on_bts := 1);
841 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
842 * f_ctrs_bsc_and_bts_add(1, "other");
843 * f_ctrs_bsc_and_bts_verify();
844 */
845private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100846 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000847 f_ctrs_bsc_verify();
848}
849
850/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
851 * f_ctrs_bsc_and_bts_init();
852 * f_do_thing(on_bts := 0);
853 * f_do_thing(on_bts := 0);
854 * f_do_thing(on_bts := 0);
855 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
856 */
857private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
858 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
859 f_ctrs_bsc_and_bts_verify();
860}
861
862
863/* Convenience functions for rate counters using g_ctr_bsc. */
864
865private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
866 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
867 log("initial bsc rate counters: ", g_ctr_bsc);
868}
869
870private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
871 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
872}
873
874/* f_ctrs_bsc_init();
875 * f_do_thing();
876 * f_do_thing();
877 * f_do_other();
878 * f_ctrs_bsc_add("thing", 2);
879 * f_ctrs_bsc_add("other");
880 * f_ctrs_bsc_verify();
881 */
882private function f_ctrs_bsc_verify() runs on test_CT {
883 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
884}
885
886/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
887 * f_ctrs_bsc_init();
888 * f_do_thing();
889 * f_ctrs_bsc_expect("thing", 1);
890 */
891private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
892 f_ctrs_bsc_add(countername, val);
893 f_ctrs_bsc_verify();
894}
895
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200896
Oliver Smith39f53072022-10-27 14:44:04 +0200897friend function f_shutdown_helper(boolean ho := false) runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100898 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600899 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100900 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
901 }
902
Oliver Smith39f53072022-10-27 14:44:04 +0200903 /* Reset handover related configuration */
904 if (ho) {
905 f_bts_0_cfg(BSCVTY,
906 {"no neighbors",
907 "neighbor-list mode manual-si5",
908 "neighbor-list add arfcn 100",
909 "neighbor-list add arfcn 200",
910 "si5 neighbor-list add arfcn 10",
911 "si5 neighbor-list add arfcn 20",
912 "handover algorithm 1"});
913 }
914
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200915 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100916 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200917 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100918}
919
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200920private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100921 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200922 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100923 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200924 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200925 ts_BSSMAP_Reset(0, g_osmux_enabled_cn)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100926 T.start;
927 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200928 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200929 tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200930 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100931 }
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200932 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200933 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100934 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200935 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200936 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100937 repeat;
938 }
939 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200940 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200941 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200942 /* If we received a RESET after ours was sent, it
943 may be a race condition where the other peer beacame
944 available after we sent it, but we are in a desired
945 state anyway, so go forward. */
946 if (not reset_received) {
947 setverdict(fail);
948 }
949 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100950 }
Harald Welte28d943e2017-11-25 15:00:50 +0100951}
952
Harald Welteae026692017-12-09 01:03:01 +0100953type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100954 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100955 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100956 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100957 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100958 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100959 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100960 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100961 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100962}
963
Harald Welte21b46bd2017-12-17 19:46:32 +0100964/*! Start the IPA/RSL related bits for one IPA_Client.
965 * \param clnt IPA_Client for which to establish
966 * \param bsc_host IP address / hostname of the BSC
967 * \param bsc_port TCP port number of the BSC
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600968 * \param idx BTS/TRX index values
Harald Welte21b46bd2017-12-17 19:46:32 +0100969 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600970function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port,
971 BtsTrxIdx idx := {0, 0}, boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100972runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100973 timer T := 10.0;
974
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600975 clnt.id := "IPA-BTS" & int2str(idx.bts) & "-TRX" & int2str(idx.trx) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100976 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100977 clnt.ccm_pars := c_IPA_default_ccm_pars;
978 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600979 clnt.ccm_pars.unit_id := int2str(1234 + idx.bts) & "/0/" & int2str(idx.trx);
Harald Welte624f9632017-12-16 19:26:04 +0100980 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100981 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600982 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[idx.bts]);
Harald Welte624f9632017-12-16 19:26:04 +0100983 }
Harald Welteae026692017-12-09 01:03:01 +0100984
985 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200986 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100987 if (handler_mode) {
988 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
989 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600990 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100991 }
Harald Welteae026692017-12-09 01:03:01 +0100992
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600993 var integer local_port := 10000 + idx.bts * 1000 + idx.trx;
994 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", local_port, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100995 if (handler_mode) {
996 clnt.vc_RSL.start(RSL_Emulation.main());
997 return;
998 }
Harald Welteae026692017-12-09 01:03:01 +0100999
1000 /* wait for IPA RSL link to connect and send ID ACK */
1001 T.start;
1002 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001003 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +01001004 T.stop;
Harald Welteae026692017-12-09 01:03:01 +01001005 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001006 [] IPA_RSL[idx.bts][idx.trx].receive(ASP_IPA_Event:?) { repeat }
1007 [] IPA_RSL[idx.bts][idx.trx].receive { repeat }
Harald Welteae026692017-12-09 01:03:01 +01001008 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +01001009 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001010 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +01001011 }
1012 }
1013}
1014
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001015function f_ipa_rsl_stop(inout IPA_Client clnt, BtsTrxIdx idx := {0, 0}) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001016 var IPL4asp_Types.Result res := {
1017 errorCode := omit,
1018 connId := omit,
1019 os_error_code := omit,
1020 os_error_text := omit
1021 };
1022
Harald Welte12055472018-03-17 20:10:08 +01001023 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
1024 return;
1025 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001026
1027 /* Alive components don't finish sockets (TCP FIN) when they are
1028 * stopped. Hence, we need to manually call close() on them to make sure
1029 * the IUT knows about it. */
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001030 f_ipa_cfg_disconnect(IPA_CFG_PORT[idx.bts][idx.trx], res);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001031
Harald Welte12055472018-03-17 20:10:08 +01001032 clnt.vc_IPA.stop;
1033 if (isbound(clnt.vc_RSL)) {
1034 clnt.vc_RSL.stop;
1035 }
1036}
1037
Harald Welte21b46bd2017-12-17 19:46:32 +01001038/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +01001039function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1040 timer T := secs_max;
1041 T.start;
1042 while (true) {
1043 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1044 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001045 /* the 'degraded' state exists from OML connection time, and we have to wait
1046 * until all MO's are initialized */
1047 T.start(1.0);
1048 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001049 return;
1050 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001051 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001052 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001053 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001054 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001055 }
1056 }
1057}
1058
Harald Welte21b46bd2017-12-17 19:46:32 +01001059/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001060altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001061 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001062 [] T_guard.timeout {
1063 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001064 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001065 }
Harald Welte60e823a2017-12-10 14:10:59 +01001066 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001067 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001068 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001069 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Harald Welte69c1c262017-12-13 21:02:08 +01001070 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001071 }
Harald Welte28d943e2017-11-25 15:00:50 +01001072}
1073
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001074altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001075 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001076 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001077 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001078 }
1079}
1080
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001081function f_init_mgcp(integer mgw_nr, charstring id) runs on test_CT {
1082 id := id & "-MGCP-" & int2str(mgw_nr);
Daniel Willmann191e0d92018-01-17 12:44:35 +01001083
1084 var MGCPOps ops := {
1085 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1086 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1087 };
1088 var MGCP_conn_parameters mgcp_pars := {
1089 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001090 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001091 mgw_ip := mp_test_ip,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001092 mgw_udp_port := 2427 + mgw_nr,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001093 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
Pau Espin Pedrol36eeaf72022-10-20 16:50:31 +02001094 the one with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001095 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001096 };
1097
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001098 vc_MGCP[mgw_nr] := MGCP_Emulation_CT.create(id) alive;
1099 vc_MGCP[mgw_nr].start(MGCP_Emulation.main(ops, mgcp_pars, id));
Daniel Willmann191e0d92018-01-17 12:44:35 +01001100}
1101
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001102/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1103 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1104 * OsmuxCID IE.
1105 */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001106private function f_vty_allow_osmux_cn(boolean allow) runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001107 f_vty_enter_cfg_msc(BSCVTY, 0);
1108 if (allow) {
1109 f_vty_transceive(BSCVTY, "osmux on");
1110 } else {
1111 f_vty_transceive(BSCVTY, "osmux off");
1112 }
1113 f_vty_transceive(BSCVTY, "exit");
1114 f_vty_transceive(BSCVTY, "exit");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001115}
1116
Max2253c0b2018-11-06 19:28:05 +01001117function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001118 if (BSCVTY.checkstate("Mapped")) {
1119 /* skip initialization if already executed once */
1120 return;
1121 }
Harald Weltebc03c762018-02-12 18:09:38 +01001122 map(self:BSCVTY, system:BSCVTY);
1123 f_vty_set_prompts(BSCVTY);
1124 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001125 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1126 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001127}
1128
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001129friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001130{
1131 // log on TTCN3 log output
1132 log(log_msg);
1133 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001134 if (pt.checkstate("Mapped")) {
1135 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1136 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001137}
1138
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001139private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1140{
1141 if (rsl_idx >= lengthof(g_system_information)) {
1142 g_system_information[rsl_idx] := SystemInformationConfig_omit
1143 }
1144 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1145}
1146
1147altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1148 var ASP_RSL_Unitdata rx_rsl_ud;
1149
1150 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001151 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001152 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1153 repeat;
1154 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001155 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001156 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1157 repeat;
1158 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001159 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001160 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1161 repeat;
1162 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001163 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001164 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1165 repeat;
1166 }
1167
1168 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1169 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1170 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1171 repeat;
1172 }
1173 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1174 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1175 repeat;
1176 }
1177 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1178 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1179 repeat;
1180 }
1181 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1182 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1183 repeat;
1184 }
1185}
1186
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001187/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1188private type record of boolean my_BooleanList;
1189
1190private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1191{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001192 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1193
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001194 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001195 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1196 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1197 * stepping into that config node. */
1198 log("msc ", msc_nr, " is not configured, skipping");
1199 continue;
1200 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001201 f_vty_enter_cfg_msc(pt, msc_nr);
1202 if (allow_attach_list[msc_nr]) {
1203 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1204 f_vty_transceive(pt, "allow-attach", strict := false);
1205 } else {
1206 f_vty_transceive(pt, "no allow-attach", strict := false);
1207 }
1208 f_vty_transceive(pt, "exit");
1209 f_vty_transceive(pt, "exit");
1210 }
1211}
1212
Harald Welte21b46bd2017-12-17 19:46:32 +01001213/* global initialization function
1214 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001215 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1216 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1217 */
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001218function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001219 integer nr_msc := 1, integer nr_mgw := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001220 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001221
Harald Welteae026692017-12-09 01:03:01 +01001222 if (g_initialized) {
1223 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001224 }
Harald Welteae026692017-12-09 01:03:01 +01001225 g_initialized := true;
1226
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001227 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001228 activate(as_Tguard());
1229
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001230 f_init_vty("VirtMSC");
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001231 f_vty_allow_osmux_cn(g_osmux_enabled_cn);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001232
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001233 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001234 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1235
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001236 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1237 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1238 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1239 }
1240
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001241 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001242 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001243 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1244 * MSC-side BSSAP emulation */
1245 if (handler_mode) {
1246 var RanOps ranops := MSC_RanOps;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001247 ranops.use_osmux := g_osmux_enabled_cn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001248 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1249 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1250 f_ran_adapter_start(g_bssap[bssap_idx]);
1251 } else {
1252 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1253 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1254 f_ran_adapter_start(g_bssap[bssap_idx]);
1255 f_legacy_bssap_reset();
1256 }
Harald Welte67089ee2018-01-17 22:19:03 +01001257 }
Harald Welted5833a82018-05-27 16:52:56 +02001258
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001259 if (mp_enable_lcs_tests) {
1260 if (handler_mode) {
1261 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1262 } else {
1263 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1264 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1265 }
1266 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001267 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001268
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001269 /* start the test with exactly all enabled MSCs allowed to attach */
1270 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1271
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001272 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001273
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001274 g_nr_mgw := nr_mgw;
1275 for (var integer i := 0; i < g_nr_mgw; i := i+1) {
1276 f_init_mgcp(i, "VirtMGW");
1277 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01001278
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001279 for (var integer i := 0; i < nr_bts; i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001280 f_init_bts(i, c_BtsParams[i].trx_num, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001281 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001282
1283 /* Emit a marker to appear in the SUT's own logging output */
1284 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001285}
Harald Welte696ddb62017-12-08 14:01:43 +01001286
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001287function f_init_bts(integer bts_idx := 0,
1288 integer trx_num := NUM_TRX_CFG,
1289 boolean handler_mode := false)
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001290runs on test_CT {
1291 /* wait until osmo-bts-omldummy has respawned */
1292 f_wait_oml(bts_idx, "degraded", 5.0);
1293
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001294 /* start RSL connection(s) */
1295 for (var integer trx_idx := 0; trx_idx < trx_num; trx_idx := trx_idx + 1) {
1296 f_ipa_rsl_start(bts[bts_idx][trx_idx].rsl,
1297 mp_bsc_ip, mp_bsc_rsl_port,
1298 {bts_idx, trx_idx}, handler_mode);
1299 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001300 /* wait until BSC tells us "connected" */
1301 f_wait_oml(bts_idx, "connected", 5.0);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001302
1303 /* Set up BTS with VTY commands: */
Vadim Yanitskiy4d852082022-09-14 14:07:20 +07001304 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
1305 f_vty_enter_cfg_bts(BSCVTY, bts_idx);
1306 if (g_osmux_enabled_bts) {
1307 f_vty_transceive(BSCVTY, "osmux on");
1308 } else {
1309 f_vty_transceive(BSCVTY, "osmux off");
1310 }
1311 f_vty_transceive(BSCVTY, "end");
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001312 }
Harald Welte28d943e2017-11-25 15:00:50 +01001313}
1314
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001315function f_init_bts_and_check_sysinfo(integer bts_idx := 0,
1316 integer trx_num := NUM_TRX_CFG,
1317 boolean handler_mode := false,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001318 template SystemInformationConfig expect_si)
1319runs on test_CT {
1320 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1321
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001322 f_init_bts(bts_idx, trx_num, handler_mode);
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001323
1324 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1325 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1326 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1327 */
1328 f_sleep(5.0);
1329 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1330
1331 deactivate(sysinfo);
1332
1333 if (match(g_system_information[bts_idx], expect_si)) {
1334 setverdict(pass);
1335 } else {
1336 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1337 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1338 setverdict(fail, "received SI does not match expectations");
1339 return;
1340 }
1341}
1342
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001343/* expect to receive a RSL message matching a specified template on a given BTS / TRX */
1344function f_exp_ipa_rx(template (present) RSL_Message t_rx,
1345 BtsTrxIdx idx := {0, 0},
1346 float Tval := 2.0)
Harald Welteae026692017-12-09 01:03:01 +01001347runs on test_CT return RSL_Message {
1348 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001349 timer T := Tval;
Harald Welteae026692017-12-09 01:03:01 +01001350
1351 T.start;
1352 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001353 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001354 T.stop;
1355 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001356 [] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001357 [] T.timeout {
1358 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001359 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001360 }
Harald Welteae026692017-12-09 01:03:01 +01001361 }
1362 return rx_rsl_ud.rsl;
1363}
1364
Harald Welte21b46bd2017-12-17 19:46:32 +01001365/* helper function to transmit RSL on a given BTS/stream */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001366function f_ipa_tx(template (value) RSL_Message t_tx,
1367 BtsTrxIdx idx := {0, 0},
1368 IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001369runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001370 IPA_RSL[idx.bts][idx.trx].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001371}
1372
1373
Harald Welte4003d112017-12-09 22:35:39 +01001374/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001375testcase TC_chan_act_noreply() runs on test_CT {
1376 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001377 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001378
Harald Welte89d42e82017-12-17 16:42:41 +01001379 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001380
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001381 f_ipa_tx(ts_RSL_CHAN_RQD('23'O, 23));
1382 rsl_unused := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001383 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001384}
1385
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001386const CounterNameVals counternames_bts_chreq := {
1387 { "chreq:total", 0 },
1388 { "chreq:attempted_emerg", 0 },
1389 { "chreq:attempted_call", 0 },
1390 { "chreq:attempted_location_upd", 0 },
1391 { "chreq:attempted_pag", 0 },
1392 { "chreq:attempted_pdch", 0 },
1393 { "chreq:attempted_other", 0 },
1394 { "chreq:attempted_unknown", 0 },
1395 { "chreq:successful", 0 },
1396 { "chreq:successful_emerg", 0 },
1397 { "chreq:successful_call", 0 },
1398 { "chreq:successful_location_upd", 0 },
1399 { "chreq:successful_pag", 0 },
1400 { "chreq:successful_pdch", 0 },
1401 { "chreq:successful_other", 0 },
1402 { "chreq:successful_unknown", 0 },
1403 { "chreq:no_channel", 0 },
1404 { "chreq:max_delay_exceeded", 0 }
1405};
1406
1407/* verify the "chreq:*" counters */
1408private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1409{
1410 var GsmFrameNumber fn := 23;
1411
1412 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1413
1414 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001415 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn));
1416 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001417 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1418
1419 f_ctrs_bts_add(0, "chreq:total");
1420 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1421 f_ctrs_bts_verify();
1422
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001423 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1424 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001425
1426 f_ctrs_bts_add(0, "chreq:successful");
1427 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1428 f_ctrs_bts_verify();
1429
1430 /* test is done, release RSL Conn Fail Ind to clean up */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001431 f_ipa_tx(ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1432 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
1433 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001434 f_sleep(1.0);
1435}
1436
Harald Welte4003d112017-12-09 22:35:39 +01001437testcase TC_chan_act_counter() runs on test_CT {
1438 var BSSAP_N_UNITDATA_ind ud_ind;
1439 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001440 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001441
Harald Welte89d42e82017-12-17 16:42:41 +01001442 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001443
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001444 f_vty_allow_emerg_bts(true, 0);
1445
1446 f_ctrs_bts_init(1, counternames_bts_chreq);
1447
1448 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1449 f_chan_act_counter('a3'O, "emerg");
1450
1451 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1452 f_chan_act_counter('43'O, "call");
1453
1454 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1455 f_chan_act_counter('03'O, "location_upd");
1456
1457 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1458 f_chan_act_counter('23'O, "pag");
1459 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1460 f_chan_act_counter('33'O, "pag");
1461
1462 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1463 /* no PCU, so PDCH not allowed. Skip this test for now. */
1464 /* f_chan_act_counter('7b'O, "pdch"); */
1465
1466 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1467 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001468
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001469 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001470}
1471
Harald Welteae026692017-12-09 01:03:01 +01001472/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001473private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001474 var RSL_Message rx_rsl;
1475
Harald Welteae026692017-12-09 01:03:01 +01001476 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001477 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001478
1479 /* expect BSC to disable the channel again if there's no RLL EST IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001480 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := T3101_MAX);
Harald Welteae026692017-12-09 01:03:01 +01001481
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001482 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001483}
1484
Philipp Maier9c60a622020-07-09 15:08:46 +02001485/* Normal variant */
1486testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001487 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001488 f_TC_chan_act_ack_noest();
1489}
1490
1491/* Emergency call variant */
1492testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1493 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001494 f_init(1);
1495 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001496 f_TC_chan_act_ack_noest(ra := 'A5'O);
1497}
1498
Philipp Maier606f07d2020-08-12 17:21:58 +02001499/* Emergency call variant, but emergency calls are not allowed */
1500testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1501 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1502
1503 var RSL_Message rx_rsl;
1504 var GsmRrMessage rr;
1505
1506 f_init(1);
1507 f_vty_allow_emerg_bts(false, 0);
1508
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001509 IPA_RSL[0][0].clear;
1510 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier606f07d2020-08-12 17:21:58 +02001511
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001512 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Philipp Maier606f07d2020-08-12 17:21:58 +02001513 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1514 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1515 setverdict(pass);
1516 } else {
1517 setverdict(fail, "immediate assignment not rejected");
1518 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001519
1520 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001521}
1522
Harald Welteae026692017-12-09 01:03:01 +01001523/* Test behavior if MSC never answers to CR */
1524testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001525 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1526 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001527 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001528 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001529 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001530
Harald Welte89d42e82017-12-17 16:42:41 +01001531 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001532
1533 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001534 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001535
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001536 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001537
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001538 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload)));
Harald Welteae026692017-12-09 01:03:01 +01001539
1540 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001541 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001542 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001543 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001544}
1545
1546/* Test behavior if MSC answers with CREF to CR */
1547testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1548 var BSSAP_N_CONNECT_ind rx_c_ind;
1549 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001550 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001551
Harald Welte89d42e82017-12-17 16:42:41 +01001552 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001553
1554 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001555 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001556
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001557 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001558
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001559 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Harald Welteae026692017-12-09 01:03:01 +01001560 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1561
1562 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001563 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001564 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001565}
1566
Harald Welte618ef642017-12-14 14:58:20 +01001567/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1568testcase TC_chan_act_nack() runs on test_CT {
1569 var RSL_Message rx_rsl;
1570 var integer chact_nack;
1571
Harald Welte89d42e82017-12-17 16:42:41 +01001572 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001573
1574 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1575
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001576 f_ipa_tx(ts_RSL_CHAN_RQD('33'O, 33));
1577 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte618ef642017-12-14 14:58:20 +01001578 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1579
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001580 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte618ef642017-12-14 14:58:20 +01001581
1582 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1583 f_sleep(0.5);
1584
1585 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1586
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001587 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001588}
1589
Harald Welte799c97b2017-12-14 17:50:30 +01001590/* Test for channel exhaustion due to RACH overload */
1591testcase TC_chan_exhaustion() runs on test_CT {
1592 var ASP_RSL_Unitdata rsl_ud;
1593 var integer i;
1594 var integer chreq_total, chreq_nochan;
1595
Harald Welte89d42e82017-12-17 16:42:41 +01001596 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001597
1598 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1599 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1600
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001601 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001602 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1603 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001604 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 +01001605 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001606 }
1607
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001608 IPA_RSL[0][0].clear;
Harald Welte799c97b2017-12-14 17:50:30 +01001609
Harald Weltedd8cbf32018-01-28 12:07:52 +01001610 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001611 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001612
1613 /* now expect additional channel activations to fail */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001614 f_ipa_tx(ts_RSL_CHAN_RQD('42'O, 42));
Harald Welte799c97b2017-12-14 17:50:30 +01001615
1616 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001617 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001618 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1619 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001620 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001621 var GsmRrMessage rr;
1622 /* match on IMM ASS REJ */
1623 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1624 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1625 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001626 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001627 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1628 chreq_nochan+1);
1629 setverdict(pass);
1630 } else {
1631 repeat;
1632 }
1633 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001634 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte799c97b2017-12-14 17:50:30 +01001635 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001636 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001637}
1638
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001639/* Test channel deactivation due to silence from MS */
1640testcase TC_chan_deact_silence() runs on test_CT {
1641 var RslChannelNr chan_nr;
1642
1643 f_init(1);
1644
1645 /* Request for a dedicated channel */
1646 chan_nr := f_chreq_act_ack('23'O);
1647
1648 /* Wait some time until the channel is released */
1649 f_sleep(2.0);
1650
1651 /* Expect CHANnel RELease */
1652 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001653 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001654 log("Received CHANnel RELease");
1655 setverdict(pass);
1656 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001657 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001658 /* See OS#3709, OsmoBSC should not send Immediate
1659 * Assignment Reject since a dedicated channel was
1660 * already allocated, and Immediate Assignment was
1661 * already sent. */
1662 setverdict(fail, "Unexpected Immediate Assignment!");
1663 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001664 [] IPA_RSL[0][0].receive {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001665 setverdict(fail, "Unexpected RSL message!");
1666 }
1667 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001668 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001669}
1670
Harald Weltecfe2c962017-12-15 12:09:32 +01001671/***********************************************************************
1672 * Assignment Testing
1673 ***********************************************************************/
1674
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001675/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1676 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001677testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001678 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001679
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001680 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1681 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001682 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001683 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001684}
1685
Harald Welte16a4adf2017-12-14 18:54:01 +01001686/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001687testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001688 var BSSAP_N_CONNECT_ind rx_c_ind;
1689 var RSL_Message rx_rsl;
1690 var DchanTuple dt;
1691
Harald Welte89d42e82017-12-17 16:42:41 +01001692 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001693
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001694 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001695 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001696 /* send assignment without AoIP IEs */
1697 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1698 } else {
Pau Espin Pedrol35609792023-01-03 16:56:59 +01001699 /* Send assignment without CIC in IPA case */
Harald Welte17b27da2018-05-25 20:33:53 +02001700 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1701 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1702 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1703 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001704 alt {
1705 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1706 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1707 }
Harald Welte235ebf12017-12-15 14:18:16 +01001708 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001709 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1710 setverdict(pass);
1711 }
1712 [] BSSAP.receive { repeat; }
1713 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001714 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001715 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001716}
1717
Harald Welteed848512018-05-24 22:27:58 +02001718/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001719function 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 +02001720 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001721 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001722 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001723 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001724 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001725 if (osmux_enabled) {
1726 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1727 } else {
1728 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1729 }
Harald Welteed848512018-05-24 22:27:58 +02001730 } else {
1731 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001732 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001733 }
1734 return ass_cmd;
1735}
1736
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001737function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001738 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001739 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1740 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001741 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001742
1743 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1744 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001745 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1746 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001747 if (ispresent(enc)) {
1748 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001749 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1750 if (ispresent(v_enc.enc_alg_chosen)) {
1751 chosenEncryptionAlgorithm := valueof(
1752 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1753 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1754 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001755 if (ispresent(v_enc.enc_kc128)) {
1756 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1757 }
1758 }
1759
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001760 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001761 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001762 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001763 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1764 cell_id_source := cell_id_source,
1765 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001766 encryptionInformation := encryptionInformation,
1767 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001768 kC128 := kc128,
1769 /* on AoIP, allow "all" codecs (until we add more concise
1770 * tests) */
1771 codecList := ts_BSSMAP_IE_CodecList(
1772 {ts_CodecAMR_F, ts_CodecAMR_H,
1773 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001774 } else {
1775 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001776 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1777 cell_id_source := cell_id_source,
1778 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001779 encryptionInformation := encryptionInformation,
1780 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1781 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001782 }
1783 return ho_req;
1784}
1785
Harald Welteed848512018-05-24 22:27:58 +02001786/* generate an assignment complete template for either AoIP or SCCPlite */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001787function f_gen_exp_compl(integer bssap_idx := 0)
1788runs on MSC_ConnHdlr return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001789 var template PDU_BSSAP exp_compl;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001790 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001791 var template BSSMAP_IE_Osmo_OsmuxCID exp_osmux_cid := omit;
1792 if (g_pars.use_osmux_cn) {
1793 var template (present) INT1 exp_cid := ?;
1794 if (isbound(g_media.mgcp_conn[0].local_osmux_cid) and isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1795 exp_cid := (g_media.mgcp_conn[0].local_osmux_cid, g_media.mgcp_conn[1].local_osmux_cid);
1796 } else if (isbound(g_media.mgcp_conn[0].local_osmux_cid)) {
1797 exp_cid := g_media.mgcp_conn[0].local_osmux_cid;
1798 } else if (isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1799 exp_cid := g_media.mgcp_conn[1].local_osmux_cid;
1800 }
1801 exp_osmux_cid := tr_OsmuxCID(exp_cid);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001802 }
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001803 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, exp_osmux_cid);
Harald Welteed848512018-05-24 22:27:58 +02001804 } else {
1805 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001806 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit, omit);
Harald Welteed848512018-05-24 22:27:58 +02001807 }
1808 return exp_compl;
1809}
1810
Harald Welte235ebf12017-12-15 14:18:16 +01001811/* Run everything required up to sending a caller-specified assignment command and expect response */
1812function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001813runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001814 var BSSAP_N_CONNECT_ind rx_c_ind;
1815 var RSL_Message rx_rsl;
1816 var DchanTuple dt;
1817
Harald Welte89d42e82017-12-17 16:42:41 +01001818 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001819
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001820 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte235ebf12017-12-15 14:18:16 +01001821 /* send assignment without AoIP IEs */
1822 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1823 alt {
1824 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1825 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1826 setverdict(pass);
1827 } else {
1828 setverdict(fail, fail_text);
1829 }
1830 }
1831 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1832 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1833 setverdict(pass);
1834 } else {
1835 setverdict(fail, fail_text);
1836 }
1837 }
1838 [] BSSAP.receive { repeat; }
1839 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001840 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001841}
1842testcase TC_assignment_csd() runs on test_CT {
1843 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001844 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001845 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1846 //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 +01001847 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1848 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001849 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001850}
1851
1852testcase TC_assignment_ctm() runs on test_CT {
1853 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001854 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001855 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1856 //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 +01001857 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1858 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001859 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001860}
1861
Harald Welte4003d112017-12-09 22:35:39 +01001862type record DchanTuple {
1863 integer sccp_conn_id,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001864 RslChannelNr rsl_chan_nr,
1865 BtsTrxIdx idx
Harald Weltea5d2ab22017-12-09 14:21:42 +01001866}
1867
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001868type record of DchanTuple DchanTuples;
1869
Harald Welted6939652017-12-13 21:02:46 +01001870/* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001871private function f_chreq_act_ack(OCT1 ra := '23'O,
1872 GsmFrameNumber fn := 23,
1873 BtsTrxIdx idx := {0, 0})
Harald Welted6939652017-12-13 21:02:46 +01001874runs on test_CT return RslChannelNr {
1875 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001876 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
1877 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Harald Welted6939652017-12-13 21:02:46 +01001878 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001879 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10), idx);
1880 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Harald Welted6939652017-12-13 21:02:46 +01001881 return chan_nr;
1882}
1883
Harald Welte4003d112017-12-09 22:35:39 +01001884/* helper function to establish a dedicated channel via BTS and MSC */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001885function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1886 BtsTrxIdx idx := {0, 0})
Harald Welte4003d112017-12-09 22:35:39 +01001887runs on test_CT return DchanTuple {
1888 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001889 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001890
Harald Welte4003d112017-12-09 22:35:39 +01001891 /* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001892 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn, idx);
Harald Welte4003d112017-12-09 22:35:39 +01001893
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001894 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3), idx);
Harald Welte4003d112017-12-09 22:35:39 +01001895
1896 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1897 dt.sccp_conn_id := rx_c_ind.connectionId;
1898 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1899
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001900 dt.idx := idx;
Harald Welte4003d112017-12-09 22:35:39 +01001901 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001902}
1903
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001904/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001905function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1906 BtsTrxIdx idx := {0, 0})
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001907runs on test_CT return DchanTuple {
1908 var BSSAP_N_CONNECT_ind rx_c_ind;
1909 var DchanTuple dt;
1910
1911 /* Send CHAN RQD */
1912 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001913 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001914
1915 /* The dyn TS first deactivates PDCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001916 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), idx, Tval := T3101_MAX);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001917 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001918 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001919
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001920 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001921 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1922
1923 /* Now activates the signalling channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001924 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10), idx);
1925 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001926
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001927 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001928
1929 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1930 dt.sccp_conn_id := rx_c_ind.connectionId;
1931 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1932
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001933 dt.idx := idx;
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001934 return dt;
1935}
1936
Harald Welte641fcbe2018-06-14 10:58:35 +02001937/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001938private function f_exp_chan_rel_and_clear(DchanTuple dt)
1939runs on test_CT {
Harald Welte641fcbe2018-06-14 10:58:35 +02001940 var RSL_Message rx_rsl;
1941 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001942 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), dt.idx, Tval := T3101_MAX);
Harald Welte641fcbe2018-06-14 10:58:35 +02001943 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001944 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), dt.idx);
Harald Welte641fcbe2018-06-14 10:58:35 +02001945
1946 /* expect Clear Complete from BSC */
1947 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1948
1949 /* MSC disconnects as instructed. */
1950 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1951}
1952
Harald Welte4003d112017-12-09 22:35:39 +01001953/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1954testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001955 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001956 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001957
Harald Welte89d42e82017-12-17 16:42:41 +01001958 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001959
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001960 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01001961
1962 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001963 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Harald Welte4003d112017-12-09 22:35:39 +01001964
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001965 /* expect Clear Request on MSC side */
1966 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1967
1968 /* Instruct BSC to clear channel */
1969 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1970 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1971
Harald Welte4003d112017-12-09 22:35:39 +01001972 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001973 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001974
1975 /* wait for SCCP emulation to do its job */
1976 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001977
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001978 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001979}
1980
1981/* Test behavior of channel release after CONN FAIL IND from BTS */
1982testcase TC_chan_rel_conn_fail() runs on test_CT {
1983 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001984 var DchanTuple dt;
1985
Harald Welte89d42e82017-12-17 16:42:41 +01001986 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001987
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001988 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01001989
Vadim Yanitskiy01d0a902022-12-14 22:41:42 +07001990 /* Sending CONN FAIL IND immediately may trigger a race condition.
1991 * Give the BSC some time to process a new SCCP connection (OS#5823). */
1992 f_sleep(0.2);
1993
Harald Welte4003d112017-12-09 22:35:39 +01001994 /* simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001995 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001996 /* TODO: different cause values? */
1997
Harald Welte4003d112017-12-09 22:35:39 +01001998 /* expect Clear Request from BSC */
1999 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
2000
2001 /* Instruct BSC to clear channel */
2002 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
2003 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2004
Harald Welte6ff76ea2018-01-28 13:08:01 +01002005 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002006 f_exp_chan_rel_and_clear(dt);
Harald Welte4003d112017-12-09 22:35:39 +01002007
2008 /* wait for SCCP emulation to do its job */
2009 f_sleep(1.0);
2010
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002011 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002012}
2013
Harald Welte99f3ca02018-06-14 13:40:29 +02002014/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
2015/* See also https://www.osmocom.org/issues/3182 */
2016testcase TC_early_conn_fail() runs on test_CT {
2017 var RSL_Message rx_rsl;
2018 var DchanTuple dt;
2019
2020 f_init(1);
2021
2022 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02002023 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02002024
2025 /* BTS->BSC: simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002026 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002027
2028 /* BTS->BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002029 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002030
2031 /* BTS<-BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002032 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002033
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002034 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002035}
2036
2037/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
2038/* See also https://www.osmocom.org/issues/3182 */
2039testcase TC_late_conn_fail() runs on test_CT {
2040 var RSL_Message rx_rsl;
2041 var DchanTuple dt;
2042
2043 f_init(1);
2044
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002045 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99f3ca02018-06-14 13:40:29 +02002046
2047 /* BSC<-MSC: Instruct BSC to clear connection */
2048 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
2049
2050 /* BTS->BSC: expect BSC to deactivate SACCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002051 rx_rsl := f_exp_ipa_rx(tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002052
2053 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002054 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002055
2056 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002057 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002058 /* BTS->BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002059 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002060
2061 /* BSC->MSC: expect Clear Complete from BSC */
2062 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2063
2064 /* BSC<-MSC: MSC disconnects as requested. */
2065 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2066
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002067 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002068}
2069
Oliver Smithaf03bef2021-08-24 15:34:51 +02002070private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
2071 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
2072 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2073
2074 f_statsd_reset();
2075
2076 /* Establish SDCCH */
2077 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
2078 f_establish_fully(ass_cmd, exp_fail);
2079
2080 /* Expect stats to be 0 */
2081 var StatsDExpects expect := {
2082 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
2083 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
2084 };
2085 f_statsd_expect(expect);
2086
2087 /* Simulate CONN FAIL IND on SDCCH */
2088 RSL.send(ts_ASP_RSL_UD(
2089 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2090 IPAC_PROTO_RSL_TRX0));
2091
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002092 f_sleep(1.0);
2093
Oliver Smithaf03bef2021-08-24 15:34:51 +02002094 /* Expect stats to be 1 */
2095 expect := {
2096 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2097 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2098 };
2099 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002100 BSSAP.receive(tr_BSSMAP_ClearRequest);
2101 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002102}
2103testcase TC_stats_conn_fail() runs on test_CT {
2104 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2105 var MSC_ConnHdlr vc_conn;
2106
2107 f_init(1, true);
2108 f_sleep(1.0);
2109
2110 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2111 vc_conn.done;
2112
2113 f_shutdown_helper();
2114}
2115
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002116function f_expect_chan_rel(RslChannelNr rsl_chan_nr,
2117 BtsTrxIdx idx := {0, 0},
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002118 boolean expect_deact_sacch := true,
2119 boolean expect_rr_chan_rel := true,
2120 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002121 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002122 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002123 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002124 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002125
2126 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002127 var boolean got_deact_sacch := false;
2128 var boolean got_rr_chan_rel := false;
2129 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002130 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002131 var RSL_IE_Body l3_ie;
2132 var PDU_ML3_NW_MS l3;
2133 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002134 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2135 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002136 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002137 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002138 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002139 repeat;
2140 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002141 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) -> value ud {
Harald Welte99787102019-02-04 10:41:36 +01002142 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002143
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002144 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2145 setverdict(fail, "cannot find L3");
2146 mtc.stop;
2147 }
2148 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2149
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002150 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002151 var CellSelIndValue cells := dec_CellSelIndValue(
2152 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2153
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002154 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2155 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002156 setverdict(pass);
2157 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002158 log("EXPECTED CELLS: ", expect_cells);
2159 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002160 }
2161 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002162
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002163 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2164 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2165 if (match(got_cause, expect_rr_cause)) {
2166 setverdict(pass);
2167 } else {
2168 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2169 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002170 }
Harald Welte99787102019-02-04 10:41:36 +01002171 repeat;
2172 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002173 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002174 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002175 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002176 if (handle_rll_rel) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002177 f_ipa_tx(ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002178 }
Harald Welte91d54a52018-01-28 15:35:07 +01002179 repeat;
2180 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002181 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002182 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002183 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
Harald Welte91d54a52018-01-28 15:35:07 +01002184 }
2185 /* ignore any user data */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002186 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002187 repeat;
2188 }
2189 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002190
2191 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2192 " got_rll_rel_req=", got_rll_rel_req);
2193
2194 if (expect_deact_sacch != got_deact_sacch) {
2195 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2196 }
2197 if (expect_rr_chan_rel != got_rr_chan_rel) {
2198 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2199 }
2200 if (expect_rll_rel_req != got_rll_rel_req) {
2201 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2202 }
Harald Welte91d54a52018-01-28 15:35:07 +01002203}
2204
Harald Welte4003d112017-12-09 22:35:39 +01002205/* Test behavior of channel release after hard Clear Command from MSC */
2206testcase TC_chan_rel_hard_clear() runs on test_CT {
2207 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002208 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002209
Harald Welte89d42e82017-12-17 16:42:41 +01002210 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002211
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002212 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01002213
2214 /* Instruct BSC to clear channel */
2215 var BssmapCause cause := 0;
2216 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2217
2218 /* expect Clear Complete from BSC on A */
2219 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2220 /* release the SCCP connection */
2221 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2222 }
2223
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002224 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002225 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002226}
2227
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002228function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2229 var BSSAP_N_DATA_ind rx_di;
2230 var DchanTuple dt;
2231
2232 f_init(1);
2233
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002234 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002235 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2236 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2237 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2238
2239 /* Instruct BSC to clear channel */
2240 var BssmapCause cause := 0;
2241 if (tx_csfb_ind) {
2242 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2243 } else {
2244 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2245 }
2246
2247 /* expect Clear Complete from BSC on A */
2248 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2249 /* release the SCCP connection */
2250 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2251 }
2252
2253 /* 1 neighbor is added by default in osmo-bts.cfg and
2254 SystemInformationConfig_default, use that: */
2255 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2256
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002257 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002258 f_shutdown_helper();
2259}
2260
2261/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2262 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2263 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2264 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2265 Indicator or not shouldn't matter at all. */
2266testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2267 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2268}
2269
2270/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2271 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2272 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2273 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2274testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2275 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2276}
2277
2278/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2279 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2280 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2281 CSFB Indicator should not be used anymore, and hence, there should be no
2282 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2283 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002284testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2285 var BSSAP_N_DATA_ind rx_di;
2286 var DchanTuple dt;
2287
2288 f_init(1);
2289
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002290 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99787102019-02-04 10:41:36 +01002291
2292 /* Instruct BSC to clear channel */
2293 var BssmapCause cause := 0;
2294 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2295
2296 /* expect Clear Complete from BSC on A */
2297 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2298 /* release the SCCP connection */
2299 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2300 }
2301
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002302 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002303 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002304}
2305
Harald Welted8c36cd2017-12-09 23:05:31 +01002306/* Test behavior of channel release after hard RLSD from MSC */
2307testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002308 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002309
Harald Welte89d42e82017-12-17 16:42:41 +01002310 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002311
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002312 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welted8c36cd2017-12-09 23:05:31 +01002313
2314 /* release the SCCP connection */
2315 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2316
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002317 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002318 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002319}
2320
Harald Welte550daf92018-06-11 19:22:13 +02002321/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2322testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2323 var DchanTuple dt;
2324
2325 f_init(1);
2326
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002327 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte550daf92018-06-11 19:22:13 +02002328
2329 /* release the SCCP connection */
2330 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2331
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002332 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002333 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002334}
2335
Harald Welte85804d42017-12-10 14:11:58 +01002336/* Test behavior of channel release after BSSMAP RESET from MSC */
2337testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002338 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002339
Harald Welte89d42e82017-12-17 16:42:41 +01002340 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002341
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002342 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte85804d42017-12-10 14:11:58 +01002343
2344 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002345 IPA_RSL[0][0].clear;
Harald Welte85804d42017-12-10 14:11:58 +01002346
2347 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002348 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_cn)));
Harald Welte85804d42017-12-10 14:11:58 +01002349 interleave {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002350 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) { }
Harald Welte85804d42017-12-10 14:11:58 +01002351 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2352 }
2353
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002354 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002355 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002356}
2357
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002358/* Verify T(iar) triggers and releases the channel */
2359testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2360 var DchanTuple dt;
2361
2362 /* Set T(iar) in BSC low enough that it will trigger before other side
2363 has time to keep alive with a T(ias). Keep recommended ratio of
2364 T(iar) >= T(ias)*2 */
2365 g_bsc_sccp_timer_ias := 2;
2366 g_bsc_sccp_timer_iar := 5;
2367
2368 f_init(1);
2369
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002370 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002371 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002372 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002373}
2374
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002375private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2376 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002377runs on test_CT
2378{
2379 var DchanTuple dt;
2380
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002381 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002382 var BssmapCause cause := 0;
2383 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2384 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2385 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2386 }
2387
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002388 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_rr_cause := expect_rr_cause);
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002389}
2390
2391/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2392testcase TC_chan_rel_rr_cause() runs on test_CT {
2393 f_init(1);
2394
2395 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2396 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2397 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2398 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2399 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2400 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002401
2402 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002403}
2404
Harald Welte5cd20ed2017-12-13 21:03:20 +01002405/* Test behavior if RSL EST IND for non-active channel */
2406testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2407 timer T := 2.0;
2408
Harald Welte89d42e82017-12-17 16:42:41 +01002409 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002410
Harald Welte5cd20ed2017-12-13 21:03:20 +01002411 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002412 var octetstring l3_payload := gen_l3_valid_payload();
2413 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002414
2415 T.start;
2416 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002417 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002418 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2419 }
2420 [] BSSAP.receive {}
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002421 [] IPA_RSL[0][0].receive {}
Harald Welte5cd20ed2017-12-13 21:03:20 +01002422 [] T.timeout {}
2423 }
2424
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002425 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002426}
2427
2428/* Test behavior if RSL EST IND for invalid SAPI */
2429testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2430 var RslChannelNr chan_nr;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002431 var octetstring l3_payload;
Harald Welte5cd20ed2017-12-13 21:03:20 +01002432
Harald Welte89d42e82017-12-17 16:42:41 +01002433 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002434
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002435 chan_nr := f_chreq_act_ack();
2436 l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002437
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002438 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002439
2440 timer T := 2.0;
2441 T.start;
2442 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002443 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002444 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2445 }
2446 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002447 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002448 [] T.timeout {}
2449 }
2450
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002451 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002452}
2453
2454/* Test behavior if RSL EST IND for invalid SAPI */
2455testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2456 timer T := 2.0;
2457
Harald Welte89d42e82017-12-17 16:42:41 +01002458 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002459
2460 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002461 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002462
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002463 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002464
2465 T.start;
2466 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002467 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002468 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2469 }
2470 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002471 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002472 [] T.timeout {}
2473 }
2474
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002475 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002476}
2477
2478/* Test behavior if RSL EST IND for invalid SACCH */
2479testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2480 timer T := 2.0;
2481
Harald Welte89d42e82017-12-17 16:42:41 +01002482 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002483
2484 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002485 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002486
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002487 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002488
2489 T.start;
2490 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002491 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002492 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2493 }
2494 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002495 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002496 [] T.timeout {}
2497 }
2498
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002499 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002500}
2501
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002502/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2503private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2504 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2505 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2506
2507 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2508 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2509
2510 f_establish_fully(ass_cmd, exp_compl);
2511
2512 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2513 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2514 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2515 BSSAP.receive(PDU_BSSAP:{
2516 discriminator := '1'B,
2517 spare := '0000000'B,
2518 dlci := 'C3'O,
2519 lengthIndicator := ?,
2520 pdu := { dtap := '0904'O }
2521 });
2522
2523 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2524 for (var integer i := 0; i < 32; i := i + 1) {
2525 var octetstring l3 := '09'O & f_rnd_octstring(14);
2526 var template (value) RslLinkId link_id;
2527 var template (value) OCT1 dlci;
2528
2529 if (i mod 2 == 0) {
2530 /* SAPI0 on FACCH or SDCCH */
2531 link_id := ts_RslLinkID_DCCH(0);
2532 dlci := '80'O;
2533 } else {
2534 /* SAPI3 on SACCH */
2535 link_id := ts_RslLinkID_SACCH(3);
2536 dlci := 'C3'O;
2537 }
2538
2539 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002540 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002541 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002542 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002543 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002544 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002545}
2546testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2547 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2548 var MSC_ConnHdlr vc_conn;
2549
2550 f_init(1, true);
2551 f_sleep(1.0);
2552
2553 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2554 vc_conn.done;
2555
2556 f_shutdown_helper();
2557}
2558
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002559private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002560 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002561 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002562 float T_val := 2.0)
2563runs on test_CT {
2564 var BSSAP_N_DATA_ind rx_di;
2565 timer T;
2566
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002567 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2568 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002569
2570 T.start(T_val);
2571 alt {
2572 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2573 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2574 if (not match(rx_cause, tr_cause)) {
2575 setverdict(fail, "Rx unexpected Cause IE: ",
2576 rx_cause, " vs expected ", tr_cause);
2577 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002578
2579 /* Who ever on the earth decided to define this field as two separate bits?!? */
2580 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2581 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2582 if (not match(rx_cc, cc)) {
2583 setverdict(fail, "Rx unexpected Control Channel type: ",
2584 rx_cc, " vs expected ", cc);
2585 }
2586
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002587 setverdict(pass);
2588 }
2589 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2590 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2591 }
2592 [] T.timeout {
2593 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2594 }
2595 }
2596}
2597
2598/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2599testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002600 var RSL_Message rx_rsl;
2601 var DchanTuple dt;
2602
2603 f_init(1);
2604
2605 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002606 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002607
2608 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002609 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002610 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002611 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002612
2613 /* MS sends unexpected RELease INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002614 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002615 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2616 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2617
2618 /* Clean up the connection */
2619 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002620 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002621
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002622 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002623}
2624
2625/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2626testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002627 var RSL_Message rx_rsl;
2628 var DchanTuple dt;
2629
2630 f_init(1);
2631
2632 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002633 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002634
2635 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002636 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002637 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002638 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002639
2640 /* BTS sends unexpected ERROR INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002641 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002642 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2643 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2644
2645 /* Clean up the connection */
2646 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002647 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002648
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002649 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002650}
2651
2652/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2653testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002654 var RSL_Message rx_rsl;
2655 var DchanTuple dt;
2656
2657 f_init(1);
2658
2659 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002660 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002661
2662 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002663 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002664 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002665 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002666
2667 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2668 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2669
2670 /* Clean up the connection */
2671 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002672 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002673
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002674 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002675}
2676
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002677/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2678testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002679 var RSL_Message rx_rsl;
2680 var DchanTuple dt;
2681
2682 f_init(1);
2683
2684 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002685 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002686
2687 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002688 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002689 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002690 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002691
2692 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002693 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002694 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002695
2696 /* Clean up the connection */
2697 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002698 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002699
2700 f_shutdown_helper();
2701}
2702
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002703testcase TC_si_default() runs on test_CT {
2704 f_init(0);
2705 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002706 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002707}
Harald Welte4003d112017-12-09 22:35:39 +01002708
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002709/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2710 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2711private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2712{
2713 select (earfcn_index) {
2714 case (0) {
2715 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2716 return 111;
2717 }
2718 case (1) {
2719 return 1;
2720 }
2721 case (2) {
2722 return 0;
2723 }
2724 case (3) {
2725 return 65535;
2726 }
2727 case else {
2728 return 23 * (earfcn_index - 3);
2729 }
2730 }
2731}
2732
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002733function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2734 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002735
2736 f_init(0);
2737
2738 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2739 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002740 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2741 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002742 }
2743
2744 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2745
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002746 if (not istemplatekind(expect_cells, "omit")) {
2747 /* Also check that RR Channel Release contains these EARFCNs.
2748 * (copied code from TC_chan_rel_hard_clear_csfb) */
2749 var BSSAP_N_DATA_ind rx_di;
2750 var DchanTuple dt;
2751
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002752 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002753 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2754 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2755 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002756
2757 /* Instruct BSC to clear channel */
2758 var BssmapCause cause := 0;
2759 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2760
2761 /* expect Clear Complete from BSC on A */
2762 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2763 /* release the SCCP connection */
2764 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2765 }
2766
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002767 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002768 }
2769
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002770 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002771 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 +02002772 }
2773}
2774
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002775private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2776{
2777 var template SI2quaterRestOctetsList si2quater := {};
2778 var integer si2quater_count := (count + 2) / 3;
2779
2780 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002781 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002782 var integer index := i / 3;
2783 var integer earfcn_index := i mod 3;
2784 if (index >= lengthof(si2quater)) {
2785 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2786 }
2787 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);
2788 }
2789
2790 return si2quater;
2791}
2792
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002793private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2794{
2795 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2796
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002797 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002798 for (var integer i := 0; i < count; i := i + 1) {
2799 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002800 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002801 }
2802
2803 return tr_CellSelIndValue_EUTRAN(cells);
2804}
2805
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002806private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2807{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002808 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002809 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002810 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2811 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002812}
2813
2814testcase TC_si2quater_2_earfcns() runs on test_CT {
2815 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002816 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002817}
2818
2819testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002820 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002821 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002822}
2823
2824testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002825 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002826 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002827}
2828
2829testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002830 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002831 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002832}
2833
2834testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002835 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002836 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002837}
2838
2839testcase TC_si2quater_12_earfcns() runs on test_CT {
2840 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002841 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002842}
2843
2844testcase TC_si2quater_23_earfcns() runs on test_CT {
2845 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002846 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002847}
2848
2849testcase TC_si2quater_32_earfcns() runs on test_CT {
2850 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002851 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002852}
2853
2854testcase TC_si2quater_33_earfcns() runs on test_CT {
2855 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002856 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002857}
2858
2859testcase TC_si2quater_42_earfcns() runs on test_CT {
2860 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002861 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002862}
2863
2864testcase TC_si2quater_48_earfcns() runs on test_CT {
2865 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002866 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002867}
2868
2869/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2870 * 48 EARFCNs. */
2871testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002872 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002873 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2874 f_init(0);
2875
2876 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002877 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2878 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002879 }
2880
2881 /* The 49th EARFCN no longer fits, expect VTY error */
2882 f_vty_enter_cfg_bts(BSCVTY, 0);
2883 var charstring vty_error;
2884 vty_error := f_vty_transceive_ret(BSCVTY,
2885 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2886 f_vty_transceive(BSCVTY, "end");
2887
2888 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2889 log("Got expected VTY error: ", vty_error);
2890 setverdict(pass);
2891 } else {
2892 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2893 }
2894
2895 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2896
2897 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002898 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 +02002899 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002900 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002901}
2902
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002903private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2904{
2905 var uint8_t count := 0;
2906 for (var integer i := 5; i < 16; i := i + 1) {
2907 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2908 count := count + 1;
2909 }
2910 }
2911 return count;
2912}
2913
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002914private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2915{
2916 var ASP_RSL_Unitdata rx_rsl_ud;
2917 var SystemInformationType1 last_si1;
2918
2919 timer T := 30.0;
2920 T.start;
2921 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002922 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2923 tr_RSL_BCCH_INFO,
2924 tr_RSL_NO_SACCH_FILL,
2925 tr_RSL_SACCH_FILL))) -> value rx_rsl_ud {
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002926 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2927 if (g_system_information[rsl_idx].si1 == omit) {
2928 repeat;
2929 }
2930 last_si1 := g_system_information[rsl_idx].si1;
2931 g_system_information[rsl_idx].si1 := omit;
2932 T.stop;
2933 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002934 [] IPA_RSL[rsl_idx][0].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002935 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2936 }
2937 return last_si1;
2938}
2939
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002940/* verify ACC rotate feature */
2941testcase TC_si_acc_rotate() runs on test_CT {
2942 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002943 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002944 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002945 var uint8_t count;
2946 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2947
2948 f_init(0, guard_timeout := 60.0);
2949
2950 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2951 "access-control-class-rotate 3",
2952 "access-control-class-rotate-quantum 1"});
2953
2954 /* Init and get first sysinfo */
2955 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2956
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002957 for (var integer i:= 0; i < 20; i := i + 1) {
2958 last_si1 := f_recv_next_si1(0);
2959 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002960 count := f_acc09_count_allowed(acc);
2961 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2962
2963 if (count != 3) {
2964 log("RSL: EXPECTED SI ACC len=3");
2965 setverdict(fail, "received SI does not match expectations");
2966 break;
2967 }
2968
2969 for (var integer j := 0; j < 10; j := j + 1) {
2970 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2971 times_allowed[j] := times_allowed[j] + 1;
2972 }
2973 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002974 }
2975
2976 for (var integer j := 0; j < 10; j := j + 1) {
2977 log("ACC", j, " allowed ", times_allowed[j], " times" );
2978 if (j != 5 and times_allowed[j] < 3) {
2979 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2980 } else if (j == 5 and times_allowed[j] > 0) {
2981 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2982 }
2983 }
2984
2985 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2986 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002987 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002988}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002989
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002990/* verify ACC startup ramp+rotate feature */
2991testcase TC_si_acc_ramp_rotate() runs on test_CT {
2992 var template SystemInformationConfig sic := SystemInformationConfig_default;
2993 var SystemInformationType1 last_si1;
2994 var AccessControlClass acc;
2995 var ASP_RSL_Unitdata rx_rsl_ud;
2996 var uint8_t count;
2997 var uint8_t prev_count;
2998 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2999
3000 f_init(0, guard_timeout := 80.0);
3001
3002 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
3003 "access-control-class-rotate 0",
3004 "access-control-class-rotate-quantum 1",
3005 "access-control-class-ramping",
3006 "access-control-class-ramping-step-interval 5",
3007 "access-control-class-ramping-step-size 5"});
3008
3009 /* Init and get first sysinfo */
3010 f_init_bts_and_check_sysinfo(0, expect_si := ?);
3011 last_si1 := g_system_information[0].si1;
3012 acc := last_si1.rach_control.acc;
3013 count := f_acc09_count_allowed(acc);
3014 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
3015 while (count > 0) {
3016 last_si1 := f_recv_next_si1(0);
3017 acc := last_si1.rach_control.acc;
3018 count := f_acc09_count_allowed(acc);
3019 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
3020 }
3021
3022 /* Increase adm subset size, we should see ramping start up */
3023 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
3024 prev_count := 0;
3025 while (true) {
3026 last_si1 := f_recv_next_si1(0);
3027 acc := last_si1.rach_control.acc;
3028 count := f_acc09_count_allowed(acc);
3029 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
3030
3031 if (prev_count > count) {
3032 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
3033 break;
3034 }
3035
3036 if (count == 9) {
3037 break; /* Maximum reached (10 - 1 perm barred), done here */
3038 }
3039
3040 prev_count := count;
3041 }
3042
3043 setverdict(pass);
3044
3045 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
3046 "rach access-control-class 4 allowed",
3047 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003048 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003049}
3050
Harald Welte4003d112017-12-09 22:35:39 +01003051testcase TC_ctrl_msc_connection_status() runs on test_CT {
3052 var charstring ctrl_resp;
3053
Harald Welte89d42e82017-12-17 16:42:41 +01003054 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003055
3056 /* See https://osmocom.org/issues/2729 */
3057 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003058 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01003059}
3060
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003061testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3062 var charstring ctrl_resp;
3063
3064 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003065
3066 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003067 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003068}
3069
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003070/* Verify correct stats on the number of configured and connected MSCs */
3071private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3072 g_pars := f_gen_test_hdlr_pars();
3073 var StatsDExpects expect := {
3074 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3075 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3076 };
3077 f_statsd_expect(expect);
3078}
3079
3080private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3081{
3082 var MSC_ConnHdlr vc_conn;
3083
3084 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3085 f_sleep(1.0);
3086 vc_conn := f_start_handler(tc_fn);
3087 vc_conn.done;
3088
3089 /* Also verify stat exposed on CTRL interface */
3090 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3091 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3092
3093 f_shutdown_helper();
3094}
3095
3096/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3097private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3098 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3099}
3100testcase TC_stat_num_msc_connected_1() runs on test_CT {
3101 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3102}
3103
3104/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3105private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3106 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3107}
3108testcase TC_stat_num_msc_connected_2() runs on test_CT {
3109 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3110}
3111
3112/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3113private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3114 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3115}
3116testcase TC_stat_num_msc_connected_3() runs on test_CT {
3117 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3118}
3119
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003120/* Verify correct stats on the number of configured and connected MSCs */
3121private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003122 var integer num_trx_connected := 0;
3123 var integer num_trx_total := 0;
3124
3125 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3126 var integer trx_num := c_BtsParams[i].trx_num;
3127 num_trx_total := num_trx_total + trx_num;
3128 if (i < expect_num_bts_connected) {
3129 num_trx_connected := num_trx_connected + trx_num;
3130 }
3131 }
3132
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003133 var StatsDExpects expect := {
3134 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3135 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3136 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003137 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := num_trx_connected, max := num_trx_connected },
3138 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := num_trx_total, max := num_trx_total }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003139 };
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003140
3141 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003142 f_statsd_expect(expect);
3143}
3144
3145private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003146 var integer num_trx_connected := 0;
3147 var integer num_trx_total := 0;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003148 var MSC_ConnHdlr vc_conn;
3149
3150 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3151 f_sleep(1.0);
3152 vc_conn := f_start_handler(tc_fn);
3153 vc_conn.done;
3154
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003155 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3156 var integer trx_num := c_BtsParams[i].trx_num;
3157 num_trx_total := num_trx_total + trx_num;
3158 if (i < nr_bts) {
3159 num_trx_connected := num_trx_connected + trx_num;
3160 }
3161 }
3162
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003163 /* Also verify stat exposed on CTRL interface */
3164 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3165 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003166 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(num_trx_connected));
3167 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(num_trx_total));
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003168
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003169 /* Verify rf_states exposed on CTRL interface */
3170 var charstring expect_net_rf_states := "";
3171 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003172 var charstring expect_bts_rf_states := "";
3173
3174 for (var integer j := 0; j < c_BtsParams[i].trx_num; j := j + 1) {
3175 expect_bts_rf_states := expect_bts_rf_states &
3176 int2str(i) & "," & int2str(j) & ",";
3177 if (i < NUM_BTS) {
3178 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3179 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3180 } else {
3181 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3182 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3183 }
3184 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3185 expect_bts_rf_states := expect_bts_rf_states & "on,";
3186 if (i < nr_bts) {
3187 /* For BTS where RSL is connected, the RSL state will be "up" */
3188 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3189 } else {
3190 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3191 }
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003192 }
3193
3194 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3195 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3196 }
3197 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3198
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003199 f_shutdown_helper();
3200}
3201
3202/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3203private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3204 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3205}
3206testcase TC_stat_num_bts_connected_1() runs on test_CT {
3207 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3208}
3209
3210/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3211private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3212 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3213}
3214testcase TC_stat_num_bts_connected_2() runs on test_CT {
3215 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3216}
3217
3218/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3219private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3220 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3221}
3222testcase TC_stat_num_bts_connected_3() runs on test_CT {
3223 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3224}
3225
Harald Welte4003d112017-12-09 22:35:39 +01003226testcase TC_ctrl() runs on test_CT {
3227 var charstring ctrl_resp;
3228
Harald Welte89d42e82017-12-17 16:42:41 +01003229 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003230
3231 /* all below values must match the osmo-bsc.cfg config file used */
3232
Harald Welte6a129692018-03-17 17:30:14 +01003233 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3234 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003235 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003236
3237 var integer bts_nr := 0;
3238 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3239 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3240 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3241 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3242 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3243 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3244 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3245
3246 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3247 f_sleep(2.0);
3248 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3249 setverdict(fail, "oml-uptime not incrementing as expected");
3250 }
3251 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3252
3253 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3254
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003255 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003256}
3257
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003258/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3259 "location-state" over the SCCPlite IPA conn */
3260testcase TC_ctrl_location() runs on test_CT {
3261 var MSC_ConnHdlr vc_conn;
3262 var integer bts_nr := 0;
3263
3264 f_init(1, true);
3265 f_sleep(1.0);
3266
3267 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3268 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3269 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3270
3271 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3272 f_sleep(2.0);
3273
3274 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3275 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3276 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3277
3278 /* should match the one from config */
3279 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3280
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003281 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003282}
3283
Harald Welte6f521d82017-12-11 19:52:02 +01003284
3285/***********************************************************************
3286 * Paging Testing
3287 ***********************************************************************/
3288
3289type record Cell_Identity {
3290 GsmMcc mcc,
3291 GsmMnc mnc,
3292 GsmLac lac,
3293 GsmCellId ci
3294};
Harald Welte24135bd2018-03-17 19:27:53 +01003295private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003296private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003297
Harald Welte5d1a2202017-12-13 19:51:29 +01003298type set of integer BtsIdList;
3299
3300private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3301 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3302 if (bts_id == bts_ids[j]) {
3303 return true;
3304 }
3305 }
3306 return false;
3307}
Harald Welte6f521d82017-12-11 19:52:02 +01003308
3309/* core paging test helper function; used by most paging test cases */
3310private function f_pageing_helper(hexstring imsi,
3311 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003312 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003313 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003314 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003315{
3316 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003317 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003318 var RSL_Message rx_rsl;
3319 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003320 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003321
3322 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003323
3324 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003325 for (i := 0; i < NUM_BTS; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003326 IPA_RSL[i][0].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003327 }
Harald Welte6f521d82017-12-11 19:52:02 +01003328
3329 if (isvalue(rsl_chneed)) {
3330 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3331 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3332 } else {
3333 bssmap_chneed := omit;
3334 }
3335
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003336 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3337 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003338
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003339 if (not istemplatekind(tmsi, "omit")) {
3340 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003341 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003342 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003343 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003344
Harald Welte5d1a2202017-12-13 19:51:29 +01003345 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003346 rx_rsl := f_exp_ipa_rx(tr_RSL_PAGING_CMD(mi), idx := {bts_ids[i], 0});
Harald Welte5d1a2202017-12-13 19:51:29 +01003347 /* check channel type, paging group */
3348 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3349 setverdict(fail, "Paging for wrong paging group");
3350 }
3351 if (ispresent(rsl_chneed) and
3352 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3353 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3354 }
Harald Welte6f521d82017-12-11 19:52:02 +01003355 }
Harald Welte2fccd982018-01-31 15:48:19 +01003356 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003357 /* do a quick check on all not-included BTSs if they received paging */
3358 for (i := 0; i < NUM_BTS; i := i + 1) {
3359 timer T := 0.1;
3360 if (f_bts_in_list(i, bts_ids)) {
3361 continue;
3362 }
3363 T.start;
3364 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003365 [] IPA_RSL[i][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003366 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3367 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003368 [] IPA_RSL[i][0].receive { repeat; }
Harald Welte5d1a2202017-12-13 19:51:29 +01003369 [] T.timeout { }
3370 }
Harald Welte6f521d82017-12-11 19:52:02 +01003371 }
3372
3373 setverdict(pass);
3374}
3375
Harald Welte5d1a2202017-12-13 19:51:29 +01003376const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003377const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003378const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3379const BtsIdList c_BtsId_LAC2 := { 2 };
3380
Harald Welte6f521d82017-12-11 19:52:02 +01003381/* PAGING by IMSI + TMSI */
3382testcase TC_paging_imsi_nochan() runs on test_CT {
3383 var BSSMAP_FIELD_CellIdentificationList cid_list;
3384 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003385 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003386 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003387}
3388
3389/* PAGING by IMSI + TMSI */
3390testcase TC_paging_tmsi_nochan() runs on test_CT {
3391 var BSSMAP_FIELD_CellIdentificationList cid_list;
3392 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003393 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003394 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003395}
3396
3397/* Paging with different "channel needed' values */
3398testcase TC_paging_tmsi_any() runs on test_CT {
3399 var BSSMAP_FIELD_CellIdentificationList cid_list;
3400 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003401 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003402 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003403}
3404testcase TC_paging_tmsi_sdcch() runs on test_CT {
3405 var BSSMAP_FIELD_CellIdentificationList cid_list;
3406 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003407 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003408 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003409}
3410testcase TC_paging_tmsi_tch_f() runs on test_CT {
3411 var BSSMAP_FIELD_CellIdentificationList cid_list;
3412 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003413 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003414 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003415}
3416testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3417 var BSSMAP_FIELD_CellIdentificationList cid_list;
3418 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003419 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003420 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003421}
3422
3423/* Paging by CGI */
3424testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3425 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3426 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003427 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003428 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003429}
3430
3431/* Paging by LAC+CI */
3432testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3433 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3434 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003435 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003436 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003437}
3438
3439/* Paging by CI */
3440testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3441 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3442 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003443 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003444 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003445}
3446
3447/* Paging by LAI */
3448testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3449 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3450 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003451 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003452 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003453}
3454
3455/* Paging by LAC */
3456testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3457 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3458 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003459 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003460 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003461}
3462
3463/* Paging by "all in BSS" */
3464testcase TC_paging_imsi_nochan_all() runs on test_CT {
3465 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3466 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003467 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003468 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003469}
3470
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003471/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003472testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3473 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3474 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 +01003475 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003476 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003477}
Harald Welte6f521d82017-12-11 19:52:02 +01003478
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003479/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003480testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3481 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3482 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003483 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003484 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003485}
3486
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003487/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003488testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3489 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3490 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003491 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003492 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003493}
3494
Harald Welte6f521d82017-12-11 19:52:02 +01003495/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003496testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3497 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3498 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3499 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003500 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003501}
3502
3503/* Paging on empty list: Verify none of them page */
3504testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3505 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3506 cid_list := { cIl_LAC := { } };
3507 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003508 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003509}
3510
Stefan Sperling049a86e2018-03-20 15:51:00 +01003511/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3512testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3513 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3514 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3515 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3516 f_shutdown_helper();
3517}
3518
Pau Espin Pedrol07657ae2023-01-03 12:08:05 +01003519/* Send paging response containing invalid (wrongly formatted) MobileIdentity IE. */
3520testcase TC_paging_imsi_nochan_ci_resp_invalid_mi() runs on test_CT {
3521 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3522 var BSSAP_N_CONNECT_ind rx_c_ind;
3523 var DchanTuple dt;
3524 var octetstring rr_pag_resp := '06270003535992617965720000'O;
3525 /* { 06 27 } is { GSM48_PDISC_RR, GSM48_MT_RR_PAG_RESP }
3526 * see 3GPP TS 44.018, table 9.1.25.1
3527 * { 00 } or { 01 } is CKSN + Spare Half Octet, not important
3528 * { 03 53 59 92 } is Mobile Station Classmark
3529 * { 61 79 65 72 00 00 } is the invalid Mobile Identity IE (3GPP TS 24.008, 10.5.1.4),
3530 * Length is 0x61 (97 in decimal).
3531 */
3532
3533 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
3534 f_pageing_helper('001010000000008'H, cid_list, { 0 });
3535
3536 /* Send CHAN RQD and wait for allocation; acknowledge it */
3537 dt.rsl_chan_nr := f_chreq_act_ack();
3538 dt.idx := {0, 0};
3539
3540 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3541 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), rr_pag_resp));
3542
3543 /* Expevct a CR with a matching Paging response on the A-Interface */
3544 timer T := 5.0;
3545 T.start;
3546 alt {
3547 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
3548 setverdict(pass);
3549 dt.sccp_conn_id := rx_c_ind.connectionId;
3550 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
3551 }
3552 [] BSSAP.receive {
3553 setverdict(fail, "Received unexpected message on A-Interface!");
3554 }
3555 [] T.timeout {
3556 setverdict(fail, "Received nothing on A-Interface!");
3557 }
3558 }
3559
3560 f_perform_clear_test_ct(dt);
3561 f_shutdown_helper();
3562}
3563
Harald Welte6f521d82017-12-11 19:52:02 +01003564/* Verify paging retransmission interval + count */
3565/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003566/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003567
Harald Weltee65d40e2017-12-13 00:09:06 +01003568/* Verify PCH load */
3569testcase TC_paging_imsi_load() runs on test_CT {
3570 var BSSMAP_FIELD_CellIdentificationList cid_list;
3571 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003572 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003573 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003574 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003575
3576 /* tell BSC there is no paging space anymore */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003577 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003578 f_sleep(0.2);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003579 IPA_RSL[0][0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003580
3581 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3582 * there would be 8 retransmissions during 4 seconds */
3583 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003584 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003585 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003586 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003587 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003588 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003589 }
Harald Welte2caa1062018-03-17 18:19:05 +01003590 [] T_retrans.timeout {
3591 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003592 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte2caa1062018-03-17 18:19:05 +01003593 T_retrans.start;
3594 repeat;
3595 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003596 [] T.timeout {
3597 setverdict(pass);
3598 }
3599 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003600
3601 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003602}
3603
Harald Welte235ebf12017-12-15 14:18:16 +01003604/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003605testcase TC_paging_counter() runs on test_CT {
3606 var BSSMAP_FIELD_CellIdentificationList cid_list;
3607 timer T := 4.0;
3608 var integer i;
3609 var integer paging_attempted_bsc;
3610 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003611 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003612 var integer paging_expired_bts[NUM_BTS];
3613 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3614
3615 f_init();
3616
3617 /* read counters before paging */
3618 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003619 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3620 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3621 }
Harald Welte1ff69992017-12-14 12:31:17 +01003622 for (i := 0; i < NUM_BTS; i := i+1) {
3623 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3624 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3625 }
3626
3627 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3628
3629 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3630 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3631 for (i := 0; i < NUM_BTS; i := i+1) {
3632 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3633 paging_attempted_bts[i]+1);
3634 }
3635
3636 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3637 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003638 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3639 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3640 }
Harald Welte1ff69992017-12-14 12:31:17 +01003641 for (i := 0; i < NUM_BTS; i := i+1) {
3642 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3643 paging_expired_bts[i]+1);
3644 }
Harald Welte1ff69992017-12-14 12:31:17 +01003645
Philipp Maier282ca4b2018-02-27 17:17:00 +01003646 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003647}
3648
3649
Harald Welte10985002017-12-12 09:29:15 +01003650/* Verify paging stops after A-RESET */
3651testcase TC_paging_imsi_a_reset() runs on test_CT {
3652 var BSSMAP_FIELD_CellIdentificationList cid_list;
3653 timer T := 3.0;
3654 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003655 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003656
3657 /* Perform a BSSMAP Reset and wait for ACK */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003658 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_cn)));
Harald Welte10985002017-12-12 09:29:15 +01003659 alt {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003660 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) { }
Harald Welte10985002017-12-12 09:29:15 +01003661 [] BSSAP.receive { repeat; }
3662 }
3663
Daniel Willmanncbef3982018-07-30 09:22:40 +02003664 /* Wait to avoid a possible race condition if a paging message is
3665 * received right before the reset ACK. */
3666 f_sleep(0.2);
3667
Harald Welte10985002017-12-12 09:29:15 +01003668 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003669 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003670 IPA_RSL[i][0].clear;
Philipp Maier1e6b4422018-02-23 14:02:13 +01003671 }
Harald Welte10985002017-12-12 09:29:15 +01003672
3673 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3674 T.start;
3675 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003676 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003677 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003678 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003679 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003680 [] IPA_RSL[1][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003681 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003682 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003683 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003684 [] IPA_RSL[2][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003685 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003686 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003687 }
Harald Welte10985002017-12-12 09:29:15 +01003688 [] T.timeout {
3689 setverdict(pass);
3690 }
3691 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003692
3693 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003694}
Harald Welteae026692017-12-09 01:03:01 +01003695
Philipp Maierf45824a2019-08-14 14:44:10 +02003696/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3697 * paging response we can not know which MSC is in charge, so we will blindly
3698 * pick the first configured MSC. This behavior is required in order to make
3699 * MT-CSFB calls working because in those cases the BSC can not know that the
3700 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3701 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003702 */
3703testcase TC_paging_resp_unsol() runs on test_CT {
3704
3705 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003706 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003707
3708 var BSSAP_N_CONNECT_ind rx_c_ind;
3709 var DchanTuple dt;
3710 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003711 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003712
3713 /* Send CHAN RQD and wait for allocation; acknowledge it */
3714 dt.rsl_chan_nr := f_chreq_act_ack();
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003715 dt.idx := {0, 0};
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003716
3717 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
Pau Espin Pedrole8a51012023-01-03 11:59:59 +01003718 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), rr_pag_resp));
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003719
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003720
Philipp Maierf45824a2019-08-14 14:44:10 +02003721 /* Expevct a CR with a matching Paging response on the A-Interface */
3722 T.start;
3723 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003724 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003725 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003726 dt.sccp_conn_id := rx_c_ind.connectionId;
3727 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003728 }
3729 [] BSSAP.receive {
3730 setverdict(fail, "Received unexpected message on A-Interface!");
3731 }
3732 [] T.timeout {
3733 setverdict(fail, "Received nothing on A-Interface!");
3734 }
3735 }
3736
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003737 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003738 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003739}
3740
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003741/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3742function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003743 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003744 var Hexstrings imsis := {};
3745 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003746 var integer rx_paging_num := 0;
3747 var integer i;
3748 timer T_rx := 60.0;
3749 timer T_load_ind := 1.0;
3750
3751 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003752 imsis := imsis & {f_gen_imsi(i)};
3753 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003754 }
3755
3756 f_init(1, guard_timeout := 100.0);
3757
3758 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003759 IPA_RSL[0][0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003760 if (send_pag_load_ind) {
3761 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003762 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(65535));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003763 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003764
3765 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003766 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003767 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003768 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3769 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003770 }
3771
3772 T_rx.start;
3773 T_load_ind.start;
3774 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003775 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?), IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003776 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3777 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3778 var charstring imsi_str := hex2str(imsi_suffix);
3779 var integer imsi_idx := str2int(imsi_str);
3780 if (rx_paging_done[imsi_idx] == false) {
3781 rx_paging_done[imsi_idx] := true;
3782 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003783 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003784 setverdict(fail, "Retrans of ", imsi_str, " happened before Rx initial trans for all reqs. rx_paging_num=", rx_paging_num);
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003785 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003786 }
3787 if (rx_paging_num < num_subscribers) {
3788 repeat;
3789 }
3790 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003791 [] IPA_RSL[0][0].receive { repeat; }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003792 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003793 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3794 if (send_pag_load_ind) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003795 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(40));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003796 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003797 T_load_ind.start;
3798 repeat;
3799 }
3800 [] T_rx.timeout {
3801 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3802 mtc.stop;
3803 }
3804 }
3805
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003806 /* Drop OML connection to have all paging requests flushed: */
3807 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3808
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003809 f_shutdown_helper();
3810}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003811/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3812testcase TC_paging_500req() runs on test_CT {
3813 f_TC_paging_Nreq(500, true);
3814}
3815/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3816 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3817 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3818 * for current config yields ~8req/sec, so 480req/min maximum. */
3819testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3820 f_TC_paging_Nreq(450, false);
3821}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003822
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003823/* Test RSL link drop causes counter increment */
3824testcase TC_rsl_drop_counter() runs on test_CT {
3825 var integer rsl_fail;
3826
Harald Welte89d42e82017-12-17 16:42:41 +01003827 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003828
3829 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3830
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003831 f_ipa_rsl_stop(bts[0][0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003832
3833 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3834
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003835 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003836}
3837
3838/* TODO: Test OML link drop causes counter increment */
3839
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003840/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3841function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003842 var IPA_Client client;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003843 timer T := 10.0;
3844
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003845 client.id := "IPA-BTS0-TRX0-RSL";
3846 client.vc_IPA := IPA_Emulation_CT.create(client.id & "-IPA") alive;
3847 client.ccm_pars := c_IPA_default_ccm_pars;
3848 client.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
3849 client.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003850
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003851 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003852
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003853 f_init_mgcp(0, "VirtMGW");
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003854
3855 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003856 map(client.vc_IPA:IPA_PORT, system:IPA);
3857 connect(client.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0][0]);
3858 client.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, client.ccm_pars));
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003859
3860 /* wait for IPA OML link to connect and then disconnect */
3861 T.start;
3862 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003863 [] IPA_RSL[0][0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003864 T.stop;
3865 return true;
3866 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003867 [] IPA_RSL[0][0].receive { repeat }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003868 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003869 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003870 }
3871 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003872 return false;
3873}
3874
3875/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3876testcase TC_rsl_unknown_unit_id() runs on test_CT {
3877 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3878 setverdict(pass);
3879 } else {
3880 setverdict(fail, "Timeout RSL waiting for connection to close");
3881 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003882 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003883}
3884
3885
3886/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3887testcase TC_oml_unknown_unit_id() runs on test_CT {
3888 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3889 setverdict(pass);
3890 } else {
3891 setverdict(fail, "Timeout OML waiting for connection to close");
3892 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003893 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003894}
3895
3896
Harald Weltec1a2fff2017-12-17 11:06:19 +01003897/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003898 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003899 ***********************************************************************/
3900
Harald Welte6811d102019-04-14 22:23:14 +02003901import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003902import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003903import from RSL_Emulation all;
3904import from MSC_ConnectionHandler all;
3905
3906type function void_fn(charstring id) runs on MSC_ConnHdlr;
3907
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003908/* helper function to create and connect a MSC_ConnHdlr component
3909 * TODO: allow connecting to TRX1..N, not only TRX0 */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003910private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0, integer mgwpool_idx := 0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003911 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003912 connect(vc_conn:RSL, bts[0][0].rsl.vc_RSL:CLIENT_PT);
3913 connect(vc_conn:RSL_PROC, bts[0][0].rsl.vc_RSL:RSL_PROC);
3914 if (isvalue(bts[1][0])) {
3915 connect(vc_conn:RSL1, bts[1][0].rsl.vc_RSL:CLIENT_PT);
3916 connect(vc_conn:RSL1_PROC, bts[1][0].rsl.vc_RSL:RSL_PROC);
Philipp Maier956a92f2018-02-16 10:58:07 +01003917 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003918 if (isvalue(bts[2][0])) {
3919 connect(vc_conn:RSL2, bts[2][0].rsl.vc_RSL:CLIENT_PT);
3920 connect(vc_conn:RSL2_PROC, bts[2][0].rsl.vc_RSL:RSL_PROC);
Neels Hofmeyr91401012019-07-11 00:42:35 +02003921 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003922 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003923 if (mp_enable_lcs_tests) {
3924 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3925 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3926 }
Daniel Willmannebdecc02020-08-12 15:30:17 +02003927 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003928 connect(vc_conn:MGCP_PROC, vc_MGCP[mgwpool_idx]:MGCP_PROC);
3929 connect(vc_conn:MGCP, vc_MGCP[mgwpool_idx]:MGCP_CLIENT);
3930 connect(vc_conn:MGCP_MULTI, vc_MGCP[mgwpool_idx]:MGCP_CLIENT_MULTI);
Harald Welte336820c2018-05-31 20:34:52 +02003931}
3932
Neels Hofmeyrda436782021-07-20 22:09:06 +02003933function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003934runs on test_CT return MSC_ConnHdlr {
3935 var charstring id := testcasename();
3936 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003937 var integer bssap_idx := 0;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003938 var integer mgwpool_idx := 0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003939 if (isvalue(pars)) {
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003940 var TestHdlrParams pars_val := valueof(pars);
3941 bssap_idx := pars_val.mscpool.bssap_idx;
3942 mgwpool_idx := pars_val.mgwpool_idx;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003943 }
Harald Welte336820c2018-05-31 20:34:52 +02003944 vc_conn := MSC_ConnHdlr.create(id);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003945 f_connect_handler(vc_conn, bssap_idx, mgwpool_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003946 return vc_conn;
3947}
3948
3949function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3950runs on test_CT return MSC_ConnHdlr {
3951 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003952 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003953 return vc_conn;
3954}
3955
Neels Hofmeyrda436782021-07-20 22:09:06 +02003956function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3957runs on test_CT return MSC_ConnHdlr {
3958 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3959}
3960
Harald Weltea0630032018-03-20 21:09:55 +01003961/* first function inside ConnHdlr component; sets g_pars + starts function */
3962private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3963runs on MSC_ConnHdlr {
3964 if (isvalue(pars)) {
3965 g_pars := valueof(pars);
3966 }
3967 fn.apply(id);
3968}
3969
Oliver Smith26a3db72021-07-09 13:51:29 +02003970private function f_vty_encryption_a5(charstring options) runs on test_CT {
3971 f_vty_transceive(BSCVTY, "configure terminal");
3972 f_vty_transceive(BSCVTY, "network");
3973 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3974 f_vty_transceive(BSCVTY, "exit");
3975 f_vty_transceive(BSCVTY, "exit");
3976}
3977
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003978const charstring VTY_A5_DEFAULT := "0 1 3";
3979
Oliver Smith26a3db72021-07-09 13:51:29 +02003980private function f_vty_encryption_a5_reset() runs on test_CT {
3981 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003982 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003983}
3984
Harald Welte3c86ea02018-05-10 22:28:05 +02003985/* Establish signalling channel (non-assignment case) followed by cipher mode */
3986private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003987 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3988 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003989 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003990 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3991 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3992 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3993 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003994
Philipp Maier23000732018-05-18 11:25:37 +02003995 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003996 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003997}
3998testcase TC_ciph_mode_a5_0() runs on test_CT {
3999 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004000 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004001 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
4002
4003 f_init(1, true);
4004 f_sleep(1.0);
4005 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4006 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004007 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004008}
4009testcase TC_ciph_mode_a5_1() runs on test_CT {
4010 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004011 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004012 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
4013
4014 f_init(1, true);
4015 f_sleep(1.0);
4016 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4017 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004018 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004019}
Oliver Smith50b98122021-07-09 15:00:28 +02004020/* OS#4975: verify that A5/2 is preferred over A5/0 */
4021testcase TC_ciph_mode_a5_2_0() runs on test_CT {
4022 var MSC_ConnHdlr vc_conn;
4023 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4024
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01004025 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02004026
4027 f_init(1, true);
4028 f_vty_encryption_a5("0 1 2 3");
4029 f_sleep(1.0);
4030 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4031 vc_conn.done;
4032 f_vty_encryption_a5_reset();
4033 f_shutdown_helper();
4034}
Oliver Smith1dff88d2021-07-09 08:45:51 +02004035/* OS#4975: verify that A5/1 is preferred over A5/2 */
4036testcase TC_ciph_mode_a5_2_1() runs on test_CT {
4037 var MSC_ConnHdlr vc_conn;
4038 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4039
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01004040 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02004041
4042 f_init(1, true);
4043 f_vty_encryption_a5("1 2");
4044 f_sleep(1.0);
4045 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4046 vc_conn.done;
4047 f_vty_encryption_a5_reset();
4048 f_shutdown_helper();
4049}
Harald Welte3c86ea02018-05-10 22:28:05 +02004050testcase TC_ciph_mode_a5_3() runs on test_CT {
4051 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004052 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004053 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
4054
4055 f_init(1, true);
4056 f_sleep(1.0);
4057 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4058 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004059 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004060}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004061/* Establish a Signalling channel with A5/4 encryption. */
4062testcase TC_ciph_mode_a5_4() runs on test_CT {
4063 var MSC_ConnHdlr vc_conn;
4064 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4065 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02004066
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004067 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02004068 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004069 f_sleep(1.0);
4070 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4071 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02004072 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004073 f_shutdown_helper();
4074}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004075/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
4076private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
4077 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4078 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
4079 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4080 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4081
4082 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004083 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004084}
4085testcase TC_assignment_aoip_tla_v6() runs on test_CT {
4086 var MSC_ConnHdlr vc_conn;
4087 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4088
4089 f_init(1, true);
4090 f_sleep(1.0);
4091 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
4092 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004093 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004094}
4095
Harald Welte3c86ea02018-05-10 22:28:05 +02004096
4097/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02004098private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004099 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4100 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004101
Harald Welte552620d2017-12-16 23:21:36 +01004102 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4103 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01004104
Harald Weltea0630032018-03-20 21:09:55 +01004105 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004106 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004107}
Harald Welte552620d2017-12-16 23:21:36 +01004108testcase TC_assignment_fr_a5_0() runs on test_CT {
4109 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004110 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004111 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01004112
Harald Welte89d42e82017-12-17 16:42:41 +01004113 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004114 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004115 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004116 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004117 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004118}
Harald Welte552620d2017-12-16 23:21:36 +01004119testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01004120 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004121 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004122 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004123
Harald Welte89d42e82017-12-17 16:42:41 +01004124 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004125 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004126 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4127 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004128 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02004129}
4130testcase TC_assignment_fr_a5_3() runs on test_CT {
4131 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004132 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004133 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004134
Harald Welte651fcdc2018-05-10 20:23:16 +02004135 f_init(1, true);
4136 f_sleep(1.0);
4137 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004138 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004139 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004140}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004141/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
4142testcase TC_assignment_fr_a5_4() runs on test_CT {
4143 var MSC_ConnHdlr vc_conn;
4144 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4145 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
4146
4147 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004148 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004149 f_sleep(1.0);
4150 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4151 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02004152 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004153 f_shutdown_helper();
4154}
Harald Weltec1a2fff2017-12-17 11:06:19 +01004155
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02004156/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
4157testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
4158 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4159 var MSC_ConnHdlr vc_conn;
4160
4161 f_init(1, true);
4162 f_sleep(1.0);
4163
4164 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4165 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4166 vc_conn.done;
4167 f_shutdown_helper();
4168}
4169
Harald Welte552620d2017-12-16 23:21:36 +01004170/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4171private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004172 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004173 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004174 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004175
4176 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004177 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4178
Harald Weltea0630032018-03-20 21:09:55 +01004179 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004180 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004181}
Harald Welte552620d2017-12-16 23:21:36 +01004182testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4183 var MSC_ConnHdlr vc_conn;
4184
Harald Welte89d42e82017-12-17 16:42:41 +01004185 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004186 f_sleep(1.0);
4187
Harald Welte8863fa12018-05-10 20:15:27 +02004188 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004189 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004190 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004191}
4192
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004193private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4194 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4195 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004196
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004197 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4198 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4199
4200 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4201
4202 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004203
4204 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4205 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4206
4207 f_create_chan_and_exp();
4208 /* we should now have a COMPL_L3 at the MSC */
4209
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004210 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004211 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004212 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004213}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004214testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4215 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004216 var MSC_ConnHdlr vc_conn;
4217
Harald Welte89d42e82017-12-17 16:42:41 +01004218 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004219 f_sleep(1.0);
4220
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004221 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004222 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004223 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004224 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004225}
4226
4227
Harald Welte4532e0a2017-12-23 02:05:44 +01004228private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004229 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004230 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004231 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004232 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004233
4234 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004235 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004236
4237 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004238 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4239 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004240 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4241 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4242 };
4243 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004244 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004245}
4246
4247testcase TC_assignment_sign() runs on test_CT {
4248 var MSC_ConnHdlr vc_conn;
4249
4250 f_init(1, true);
4251 f_sleep(1.0);
4252
Harald Welte8863fa12018-05-10 20:15:27 +02004253 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004254 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004255 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004256}
4257
Harald Welte60aa5762018-03-21 19:33:13 +01004258/***********************************************************************
4259 * Codec (list) testing
4260 ***********************************************************************/
4261
4262/* check if the given rsl_mode is compatible with the a_elem */
4263private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4264return boolean {
4265 select (a_elem.codecType) {
4266 case (GSM_FR) {
4267 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4268 return true;
4269 }
4270 }
4271 case (GSM_HR) {
4272 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4273 return true;
4274 }
4275 }
4276 case (GSM_EFR) {
4277 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4278 return true;
4279 }
4280 }
4281 case (FR_AMR) {
4282 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4283 return true;
4284 }
4285 }
4286 case (HR_AMR) {
4287 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4288 return true;
4289 }
4290 }
4291 case else { }
4292 }
4293 return false;
4294}
4295
4296/* check if the given rsl_mode is compatible with the a_list */
4297private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4298return boolean {
4299 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4300 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4301 return true;
4302 }
4303 }
4304 return false;
4305}
4306
4307/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004308function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004309return BSSMAP_IE_ChannelType {
4310 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4311 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4312 select (a_elem.codecType) {
4313 case (GSM_FR) {
4314 ret.channelRateAndType := ChRate_TCHF;
4315 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4316 }
4317 case (GSM_HR) {
4318 ret.channelRateAndType := ChRate_TCHH;
4319 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4320 }
4321 case (GSM_EFR) {
4322 ret.channelRateAndType := ChRate_TCHF;
4323 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4324 }
4325 case (FR_AMR) {
4326 ret.channelRateAndType := ChRate_TCHF;
4327 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4328 }
4329 case (HR_AMR) {
4330 ret.channelRateAndType := ChRate_TCHH;
4331 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4332 }
4333 case else {
4334 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004335 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004336 }
4337 }
4338 return ret;
4339}
4340
Harald Weltea63b9102018-03-22 20:36:16 +01004341private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4342return template RSL_IE_Body {
4343 var template RSL_IE_Body mode_ie := {
4344 chan_mode := {
4345 len := ?,
4346 reserved := ?,
4347 dtx_d := ?,
4348 dtx_u := ?,
4349 spd_ind := RSL_SPDI_SPEECH,
4350 ch_rate_type := -,
4351 coding_alg_rate := -
4352 }
4353 }
4354
4355 select (a_elem.codecType) {
4356 case (GSM_FR) {
4357 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4358 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4359 }
4360 case (GSM_HR) {
4361 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4362 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4363 }
4364 case (GSM_EFR) {
4365 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4366 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4367 }
4368 case (FR_AMR) {
4369 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4370 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4371 }
4372 case (HR_AMR) {
4373 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4374 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4375 }
4376 }
4377 return mode_ie;
4378}
4379
Harald Welte60aa5762018-03-21 19:33:13 +01004380type record CodecListTest {
4381 BSSMAP_IE_SpeechCodecList codec_list,
4382 charstring id
4383}
4384type record of CodecListTest CodecListTests
4385
4386private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004387 f_assignment_codec(id);
4388}
4389
4390private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02004391 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02004392 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Harald Welte60aa5762018-03-21 19:33:13 +01004393
4394 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004395 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004396 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4397 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4398 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004399 if (isvalue(g_pars.expect_mr_s0_s7)) {
4400 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4401 g_pars.expect_mr_s0_s7;
4402 }
Harald Welte79f3f542018-05-25 20:02:37 +02004403 }
Harald Welte60aa5762018-03-21 19:33:13 +01004404 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4405 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004406 log("expecting ASS COMPL like this: ", exp_compl);
4407
4408 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004409
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004410 if (not g_pars.expect_channel_mode_modify) {
4411 /* Verify that the RSL-side activation actually matches our expectations */
4412 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004413
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004414 var RSL_IE_Body mode_ie;
4415 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4416 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004417 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004418 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004419 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4420 if (not match(mode_ie, t_mode_ie)) {
4421 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4422 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004423 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004424
4425 var RSL_IE_Body mr_conf;
4426 if (g_pars.expect_mr_conf_ie != omit) {
4427 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4428 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4429 mtc.stop;
4430 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004431 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004432
4433 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
Vadim Yanitskiy8b189372022-09-14 17:31:17 +07004434 setverdict(fail, "RSL MR CONFIG IE does not match expectation. ",
4435 "Expected: ", g_pars.expect_mr_conf_ie, ", got: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004436 }
4437 } else {
4438 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4439 log("found RSL MR CONFIG IE: ", mr_conf);
4440 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4441 mtc.stop;
4442 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004443 }
4444 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004445
4446 if (do_perform_clear) {
4447 f_perform_clear();
4448 }
Harald Welte60aa5762018-03-21 19:33:13 +01004449}
4450
Philipp Maierd0e64b02019-03-13 14:15:23 +01004451private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4452
4453 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4454 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4455
4456 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004457 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004458 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4459 }
4460 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4461 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4462 log("expecting ASS FAIL like this: ", exp_fail);
4463
4464 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004465 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004466}
4467
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004468const CounterNameVals counternames_bsc_bts_assignment := {
4469 { "assignment:attempted", 0 },
4470 { "assignment:completed", 0 },
4471 { "assignment:stopped", 0 },
4472 { "assignment:no_channel", 0 },
4473 { "assignment:timeout", 0 },
4474 { "assignment:failed", 0 },
4475 { "assignment:error", 0 }
4476};
4477
4478const CounterNameVals counternames_bts_assignment := {
4479 { "assignment:attempted_sign", 0 },
4480 { "assignment:attempted_speech", 0 },
4481 { "assignment:completed_sign", 0 },
4482 { "assignment:completed_speech", 0 },
4483 { "assignment:stopped_sign", 0 },
4484 { "assignment:stopped_speech", 0 },
4485 { "assignment:no_channel_sign", 0 },
4486 { "assignment:no_channel_speech", 0 },
4487 { "assignment:timeout_sign", 0 },
4488 { "assignment:timeout_speech", 0 },
4489 { "assignment:failed_sign", 0 },
4490 { "assignment:failed_speech", 0 },
4491 { "assignment:error_sign", 0 },
4492 { "assignment:error_speech", 0 }
4493};
4494
4495function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4496 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4497 f_ctrs_bts_init(bts_count, bts_names);
4498 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4499}
4500
Harald Welte60aa5762018-03-21 19:33:13 +01004501testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004502 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004503 var MSC_ConnHdlr vc_conn;
4504
4505 f_init(1, true);
4506 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004507 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004508
4509 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004510 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004511 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004512
4513 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4514 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4515 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4516 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4517 f_ctrs_bts_verify();
4518
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004519 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004520}
4521
4522testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004523 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004524 var MSC_ConnHdlr vc_conn;
4525
4526 f_init(1, true);
4527 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004528 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004529
4530 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004531 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004532 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004533
4534 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4535 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4536 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4537 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4538 f_ctrs_bts_verify();
4539
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004540 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004541}
4542
4543testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004544 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004545 var MSC_ConnHdlr vc_conn;
4546
4547 f_init(1, true);
4548 f_sleep(1.0);
4549
4550 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004551 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004552 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004553 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004554}
4555
Philipp Maierd0e64b02019-03-13 14:15:23 +01004556/* Allow 5,90k only (current default config) */
4557private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004558 f_vty_cfg_msc(BSCVTY, 0, {
4559 "amr-config 12_2k forbidden",
4560 "amr-config 10_2k forbidden",
4561 "amr-config 7_95k forbidden",
4562 "amr-config 7_40k forbidden",
4563 "amr-config 6_70k forbidden",
4564 "amr-config 5_90k allowed",
4565 "amr-config 5_15k forbidden",
4566 "amr-config 4_75k forbidden"
4567 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004568}
4569
4570/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4571 * ("Config-NB-Code = 1") */
4572private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004573 f_vty_cfg_msc(BSCVTY, 0, {
4574 "amr-config 12_2k allowed",
4575 "amr-config 10_2k forbidden",
4576 "amr-config 7_95k forbidden",
4577 "amr-config 7_40k allowed",
4578 "amr-config 6_70k forbidden",
4579 "amr-config 5_90k allowed",
4580 "amr-config 5_15k forbidden",
4581 "amr-config 4_75k allowed"
4582 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004583}
4584
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004585private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4586 var charstring tch;
4587 if (fr) {
4588 tch := "tch-f";
4589 } else {
4590 tch := "tch-h";
4591 }
4592 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4593}
4594
4595/* Set the AMR start-mode for this TCH back to the default configuration. */
4596private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4597 f_vty_amr_start_mode_set(fr, "auto");
4598}
4599
Harald Welte60aa5762018-03-21 19:33:13 +01004600testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004601 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004602 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004603
4604 /* Note: This setups the codec configuration. The parameter payload in
4605 * mr_conf must be consistant with the parameter codecElements in pars
4606 * and also must match the amr-config in osmo-bsc.cfg! */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004607 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004608 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004609 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004610 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004611
Harald Welte60aa5762018-03-21 19:33:13 +01004612 f_init(1, true);
4613 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004614 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004615 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004616
Harald Welte8863fa12018-05-10 20:15:27 +02004617 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004618 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004619
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004620 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4621 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4622 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4623 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4624 f_ctrs_bts_verify();
4625
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004626 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004627 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004628}
4629
4630testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004631 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004632 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004633
4634 /* See note above */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004635 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004636 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004637 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004638 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004639
Harald Welte60aa5762018-03-21 19:33:13 +01004640 f_init(1, true);
4641 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004642 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004643 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004644
Harald Welte8863fa12018-05-10 20:15:27 +02004645 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004646 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004647
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004648 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4649 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4650 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4651 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4652 f_ctrs_bts_verify();
4653
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004654 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004655 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004656}
4657
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004658/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4659testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4660 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4661 var MSC_ConnHdlr vc_conn;
4662
4663 f_init(1, true);
4664 f_sleep(1.0);
4665
4666 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4667 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4668 * expecting a Channel Mode Modify if the channel type is compatible. */
4669 f_disable_all_sdcch();
4670 f_disable_all_tch_h();
4671
4672 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4673 pars.expect_channel_mode_modify := true;
4674 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4675 vc_conn.done;
4676
4677 f_enable_all_sdcch();
4678 f_enable_all_tch();
4679 f_shutdown_helper();
4680}
4681
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004682/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4683testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4684 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4685 var MSC_ConnHdlr vc_conn;
4686
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004687 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4688 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4689 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy36fe9582022-09-14 15:25:04 +07004690 pars.expect_mr_conf_ie := c_mr_conf_5_90;
4691 pars.expect_mr_conf_ie.multirate_cfg.icmi := false; /* expect ICMI=0, smod=00: */
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004692
4693 f_init(1, true);
4694 f_sleep(1.0);
4695
4696 /* First set nonzero start mode bits */
4697 f_vty_amr_start_mode_set(true, "4");
4698 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4699 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4700 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4701 f_vty_amr_start_mode_set(true, "auto");
4702
4703 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4704 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004705
4706 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4707 f_vty_amr_start_mode_set(true, "1");
4708 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004709 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004710}
4711
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004712function f_TC_assignment_codec_amr(boolean fr, RSL_IE_MultirateCfg mr_cfg,
4713 bitstring s8_s0, bitstring exp_s8_s0,
4714 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004715runs on test_CT {
4716
4717 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4718 var MSC_ConnHdlr vc_conn;
4719
Philipp Maierd0e64b02019-03-13 14:15:23 +01004720 if (fr) {
4721 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4722 } else {
4723 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4724 }
4725 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4726 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004727 pars.expect_mr_conf_ie := { multirate_cfg := mr_cfg };
Philipp Maierd0e64b02019-03-13 14:15:23 +01004728 pars.expect_mr_s0_s7 := exp_s8_s0;
4729
4730 f_init(1, true);
4731 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004732 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004733 f_sleep(1.0);
4734
4735 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4736 vc_conn.done;
4737 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004738 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004739}
4740
4741function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4742runs on test_CT {
4743
4744 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4745 var MSC_ConnHdlr vc_conn;
4746
4747 if (fr) {
4748 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4749 } else {
4750 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4751 }
4752 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4753 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4754
4755 f_init(1, true);
4756 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004757 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004758 f_sleep(1.0);
4759
4760 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4761 vc_conn.done;
4762 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004763 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004764}
4765
Philipp Maierd0e64b02019-03-13 14:15:23 +01004766/* Set S1, we expect an AMR multirate configuration IE with all four rates
4767 * set. */
4768testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004769 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4770 params := '20882208'O));
4771 f_TC_assignment_codec_amr(true, mr_cfg, '00000011'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004772 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004773}
4774
4775/* Set S1, we expect an AMR multirate configuration IE with the lower three
4776 * rates set. */
4777testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004778 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4779 params := '208820'O));
4780 f_TC_assignment_codec_amr(false, mr_cfg, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004781 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004782}
4783
4784/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4785 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4786testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004787 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4788 params := '20882208'O));
4789 f_TC_assignment_codec_amr(true, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004790 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004791}
4792
4793/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4794 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4795testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004796 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4797 params := '208820'O));
4798 f_TC_assignment_codec_amr(false, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004799 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004800}
4801
4802/* The following block of tests selects more and more rates until all four
4803 * possible rates are in the active set (full rate) */
4804testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004805 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4806 f_TC_assignment_codec_amr(true, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004807 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004808}
4809
4810testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004811 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4812 params := '2080'O));
4813 f_TC_assignment_codec_amr(true, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004814 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004815}
4816
4817testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004818 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4819 params := '208820'O));
4820 f_TC_assignment_codec_amr(true, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004821 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004822}
4823
4824testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004825 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4826 params := '20882208'O));
4827 f_TC_assignment_codec_amr(true, mr_cfg, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004828 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004829}
4830
4831/* The following block of tests selects more and more rates until all three
4832 * possible rates are in the active set (half rate) */
4833testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004834 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4835 f_TC_assignment_codec_amr(false, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004836 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004837}
4838
4839testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004840 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4841 params := '2080'O));
4842 f_TC_assignment_codec_amr(false, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004843 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004844}
4845
4846testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004847 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4848 params := '208820'O));
4849 f_TC_assignment_codec_amr(false, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004850 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004851}
4852
4853/* The following block tests what happens when the MSC does offer rate
4854 * configurations that are not supported by the BSC. Normally such situations
4855 * should not happen because the MSC gets informed by the BSC in advance via
4856 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4857 * to offer rates that are not applicable anyway. */
4858
4859testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004860 /* Try to include 12,2k in into the active set even though the channel
4861 * is half rate only. The BSC is expected to remove the 12,0k */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004862 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4863 params := '208820'O));
4864 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004865 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004866}
4867
4868testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004869 /* See what happens when all rates are selected at once. Since then
4870 * Also S1 is selected, this setting will be prefered and we should
4871 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004872 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4873 params := '20882208'O));
4874 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004875 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004876}
4877
4878testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004879 /* Same as above, but with S1 missing, the MSC is then expected to
4880 * select the currently supported rates, which are also 12.2k, 7,40k,
4881 * 5,90k, and 4,75k, into the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004882 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4883 params := '20882208'O));
4884 f_TC_assignment_codec_amr(true, mr_cfg, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004885 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004886}
4887
4888testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004889 /* Try to select no rates at all */
4890 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004891 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004892}
4893
4894testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004895 /* Try to select only unsupported rates */
4896 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004897 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004898}
4899
4900testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004901 /* Try to select 12,2k for half rate */
4902 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004903 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004904}
4905
Neels Hofmeyr21863562020-11-26 00:34:33 +00004906testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004907 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4908 codec_modes := '10010101'B,
4909 params := '20882208'O));
4910 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004911 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004912}
4913
4914testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004915 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4916 codec_modes := '00010101'B,
4917 params := '208820'O));
4918 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B,
Neels Hofmeyr21863562020-11-26 00:34:33 +00004919 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004920 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004921}
4922
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004923testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004924 /* "amr tch-f modes 0 2 4 7" => total 4 modes and start mode 4 => '11'B on the wire */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004925 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 3,
4926 codec_modes := '10010101'B,
4927 params := '20882208'O));
4928 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004929 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004930}
4931
4932testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004933 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004934 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 2,
4935 codec_modes := '00010101'B,
4936 params := '208820'O));
4937 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004938 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004939}
4940
Philipp Maierac09bfc2019-01-08 13:41:39 +01004941private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004942 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4943 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4944 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4945 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004946}
4947
4948private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004949 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4950 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004951}
4952
4953private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004954 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4955 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4956 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4957 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4958 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4959 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004960}
4961
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004962private function f_disable_all_sdcch() runs on test_CT {
4963 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4964 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4965 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4966 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4967}
4968
4969private function f_enable_all_sdcch() runs on test_CT {
4970 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4971 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4972 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4973 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4974}
4975
Philipp Maierac09bfc2019-01-08 13:41:39 +01004976/* Allow HR only */
4977private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4978 g_pars := f_gen_test_hdlr_pars();
4979 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4980 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4981 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4982 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4983 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4984 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4985 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004986 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004987}
4988
4989/* Allow FR only */
4990private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4991 g_pars := f_gen_test_hdlr_pars();
4992 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4993 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4994 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4995 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4996 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4997 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4998 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004999 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005000}
5001
5002/* Allow HR only (expect assignment failure) */
5003private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
5004 g_pars := f_gen_test_hdlr_pars();
5005 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5006 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
5007 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5008 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
5009 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
5010 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5011 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005012 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005013}
5014
5015/* Allow FR only (expect assignment failure) */
5016private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
5017 g_pars := f_gen_test_hdlr_pars();
5018 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5019 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
5020 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5021 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
5022 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
5023 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5024 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005025 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005026}
5027
5028/* Allow FR and HR, but prefer FR */
5029private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5030 g_pars := f_gen_test_hdlr_pars();
5031 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5032 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5033 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5034 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5035 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5036 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5037 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5038 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005039 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005040}
5041
5042/* Allow FR and HR, but prefer HR */
5043private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5044 g_pars := f_gen_test_hdlr_pars();
5045 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5046 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5047 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5048 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5049 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5050 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5051 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5052 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005053 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005054}
5055
5056/* Allow FR and HR, but prefer FR */
5057private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5058 g_pars := f_gen_test_hdlr_pars();
5059 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5060 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5061 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5062 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5063 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5064 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5065 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5066 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005067 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005068}
5069
5070/* Allow FR and HR, but prefer HR */
5071private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5072 g_pars := f_gen_test_hdlr_pars();
5073 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5074 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5075 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5076 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5077 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5078 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5079 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5080 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005081 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005082}
5083
5084/* Request a HR channel while all FR channels are exhausted, this is expected
5085 * to work without conflicts */
5086testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
5087 var MSC_ConnHdlr vc_conn;
5088 f_init(1, true);
5089 f_sleep(1.0);
5090 f_enable_all_tch();
5091 f_disable_all_tch_f();
5092 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
5093 vc_conn.done;
5094 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005095 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005096}
5097
5098/* Request a FR channel while all FR channels are exhausted, this is expected
5099 * to fail. */
5100testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
5101 var MSC_ConnHdlr vc_conn;
5102 f_init(1, true);
5103 f_sleep(1.0);
5104 f_enable_all_tch();
5105 f_disable_all_tch_f();
5106 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
5107 vc_conn.done;
5108 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005109 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005110}
5111
5112/* Request a FR (prefered) or alternatively a HR channel while all FR channels
5113 * are exhausted, this is expected to be resolved by selecting a HR channel. */
5114testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
5115 var MSC_ConnHdlr vc_conn;
5116 f_init(1, true);
5117 f_sleep(1.0);
5118 f_enable_all_tch();
5119 f_disable_all_tch_f();
5120 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
5121 vc_conn.done;
5122 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005123 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005124}
5125
5126/* Request a HR (prefered) or alternatively a FR channel while all FR channels
5127 * are exhausted, this is expected to work without conflicts. */
5128testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
5129 var MSC_ConnHdlr vc_conn;
5130 f_init(1, true);
5131 f_sleep(1.0);
5132 f_enable_all_tch();
5133 f_disable_all_tch_f();
5134 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
5135 vc_conn.done;
5136 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005137 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005138}
5139
5140/* Request a FR channel while all HR channels are exhausted, this is expected
5141 * to work without conflicts */
5142testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
5143 var MSC_ConnHdlr vc_conn;
5144 f_init(1, true);
5145 f_sleep(1.0);
5146 f_enable_all_tch();
5147 f_disable_all_tch_h();
5148 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
5149 vc_conn.done;
5150 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005151 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005152}
5153
5154/* Request a HR channel while all HR channels are exhausted, this is expected
5155 * to fail. */
5156testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
5157 var MSC_ConnHdlr vc_conn;
5158 f_init(1, true);
5159 f_sleep(1.0);
5160 f_enable_all_tch();
5161 f_disable_all_tch_h();
5162 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
5163 vc_conn.done;
5164 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005165 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005166}
5167
5168/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5169 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5170testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5171 var MSC_ConnHdlr vc_conn;
5172 f_init(1, true);
5173 f_sleep(1.0);
5174 f_enable_all_tch();
5175 f_disable_all_tch_h();
5176 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5177 vc_conn.done;
5178 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005179 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005180}
5181
5182/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5183 * are exhausted, this is expected to work without conflicts. */
5184testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5185 var MSC_ConnHdlr vc_conn;
5186 f_init(1, true);
5187 f_sleep(1.0);
5188 f_enable_all_tch();
5189 f_disable_all_tch_h();
5190 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5191 vc_conn.done;
5192 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005193 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005194}
5195
5196/* Allow FR and HR, but prefer HR */
5197private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5198 g_pars := f_gen_test_hdlr_pars();
5199 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5200 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5201 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5202 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5203 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5204 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5205 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5206 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005207 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005208}
5209
5210/* Allow FR and HR, but prefer FR */
5211private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5212 g_pars := f_gen_test_hdlr_pars();
5213 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5214 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5215 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5216 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5217 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5218 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5219 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5220 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005221 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005222}
5223
5224/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5225 * HR, which is the prefered type, is selected. */
5226testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5227 var MSC_ConnHdlr vc_conn;
5228 f_init(1, true);
5229 f_sleep(1.0);
5230 f_enable_all_tch();
5231 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5232 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005233 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005234}
5235
5236/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5237 * FR, which is the prefered type, is selected. */
5238testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5239 var MSC_ConnHdlr vc_conn;
5240 f_init(1, true);
5241 f_sleep(1.0);
5242 f_enable_all_tch();
5243 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5244 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005245 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005246}
5247
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005248/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5249private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5250 g_pars := f_gen_test_hdlr_pars();
5251 g_pars.ra := '02'O; /* RA containing reason=LU */
5252
5253 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5254 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5255 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5256 var template uint3_t tsc := ?;
5257
5258 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5259 f_create_bssmap_exp(l3_enc);
5260 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5261 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5262
5263 /* we should now have a COMPL_L3 at the MSC */
5264 timer T := 10.0;
5265 T.start;
5266 alt {
5267 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5268 [] T.timeout {
5269 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5270 }
5271 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005272
5273 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005274}
5275testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5276 var MSC_ConnHdlr vc_conn;
5277 f_init(1, true);
5278 f_sleep(1.0);
5279 f_disable_all_sdcch();
5280 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5281 vc_conn.done;
5282 f_enable_all_sdcch();
5283 f_shutdown_helper();
5284}
5285
5286/* Request a signalling channel with all SDCCH exhausted, it is
5287 expected that no TCH will be selected for signalling and assigment will fail
5288 because it's dictated by VTY config */
5289testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5290 var RSL_Message rsl_unused, rsl_msg;
5291 var GsmRrMessage rr;
5292 f_init(1, false);
5293 f_sleep(1.0);
5294 f_vty_allow_tch_for_signalling(false, 0);
5295 f_disable_all_sdcch();
5296
5297 /* RA containing reason=LU */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005298 f_ipa_tx(ts_RSL_CHAN_RQD('02'O, 2342));
5299 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005300 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5301 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5302 setverdict(fail, "Expected reject");
5303 }
5304
5305 f_vty_allow_tch_for_signalling(true, 0);
5306 f_enable_all_sdcch();
5307 f_shutdown_helper();
5308}
5309
5310/* Request a voice channel with all SDCCH exhausted, it is
5311 * expected that TCH channel will be allocated since the VTY option is only
5312 * aimed at signalling requests */
5313private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5314 g_pars := f_gen_test_hdlr_pars();
5315 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5316
5317 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5318 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5319 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5320 var template uint3_t tsc := ?;
5321
5322 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5323 f_create_bssmap_exp(l3_enc);
5324 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5325 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5326
5327 /* we should now have a COMPL_L3 at the MSC */
5328 timer T := 10.0;
5329 T.start;
5330 alt {
5331 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5332 [] T.timeout {
5333 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5334 }
5335 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005336 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005337}
5338testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5339 var MSC_ConnHdlr vc_conn;
5340 f_init(1, true);
5341 f_sleep(1.0);
5342 f_vty_allow_tch_for_signalling(false, 0);
5343 f_disable_all_sdcch();
5344
5345 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5346 vc_conn.done;
5347
5348 f_vty_allow_tch_for_signalling(true, 0);
5349 f_enable_all_sdcch();
5350 f_shutdown_helper();
5351}
5352
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005353/* Test Osmux setup BSC<->MSC */
5354testcase TC_assignment_osmux_cn() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005355 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5356 var MSC_ConnHdlr vc_conn;
5357
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005358 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5359 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5360 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiyb9bf00f2022-09-14 15:35:37 +07005361 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02005362 pars.use_osmux_cn := true;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005363
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02005364 g_osmux_enabled_cn := true;
5365 f_init(1, true);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005366 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005367 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005368
5369 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5370 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005371
5372 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005373 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005374}
5375
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005376/* Test Osmux setup BTS<->BSC */
5377testcase TC_assignment_osmux_bts() runs on test_CT {
5378 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5379 var MSC_ConnHdlr vc_conn;
5380
5381 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5382 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5383 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005384 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005385 pars.use_osmux_bts := true;
5386
5387 g_osmux_enabled_bts := true;
5388 f_init(1, true);
5389 f_sleep(1.0);
5390 f_vty_amr_start_mode_set(false, "1");
5391
5392 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5393 vc_conn.done;
5394
5395 f_vty_amr_start_mode_restore(false);
5396 f_shutdown_helper();
5397}
5398
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +02005399/* Test non-AMR codecs still work fine as RTP when Osmux is enabled BTS<->BSC<->MSC */
5400testcase TC_assignment_codec_hr_osmux_on() runs on test_CT {
5401 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5402 var MSC_ConnHdlr vc_conn;
5403
5404 g_osmux_enabled_cn := true;
5405 g_osmux_enabled_bts := true;
5406 f_init(1, true);
5407 f_sleep(1.0);
5408 f_ctrs_bsc_and_bts_assignment_init(1);
5409
5410 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5411 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5412 vc_conn.done;
5413
5414 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
5415 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
5416 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
5417 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
5418 f_ctrs_bts_verify();
5419
5420 f_shutdown_helper();
5421}
5422
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005423/* Test Osmux setup BTS<->BSC<->MSC */
5424testcase TC_assignment_osmux() runs on test_CT {
5425 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5426 var MSC_ConnHdlr vc_conn;
5427
5428 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5429 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5430 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005431 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005432 pars.use_osmux_cn := true;
5433 pars.use_osmux_bts := true;
5434
5435 g_osmux_enabled_cn := true;
5436 g_osmux_enabled_bts := true;
5437 f_init(1, true);
5438 f_sleep(1.0);
5439 f_vty_amr_start_mode_set(false, "1");
5440
5441 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5442 vc_conn.done;
5443
5444 f_vty_amr_start_mode_restore(false);
5445 f_shutdown_helper();
5446}
5447
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005448/* test the procedure of the MSC requesting a Classmark Update:
5449 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5450 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005451private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005452 g_pars := f_gen_test_hdlr_pars();
5453
Harald Weltea0630032018-03-20 21:09:55 +01005454 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005455 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005456
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005457 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5458 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5459
Harald Welte898113b2018-01-31 18:32:21 +01005460 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5461 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5462 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005463
5464 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005465}
5466testcase TC_classmark() runs on test_CT {
5467 var MSC_ConnHdlr vc_conn;
5468 f_init(1, true);
5469 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005470 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005471 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005472 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005473}
5474
Harald Welteeddf0e92020-06-21 19:42:15 +02005475/* Send a CommonID from the simulated MSC and verify that the information is used to
5476 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5477private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5478 g_pars := f_gen_test_hdlr_pars();
5479 f_MscConnHdlr_init_vty();
5480
5481 f_create_chan_and_exp();
5482 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005483
5484 /* Send CommonID */
5485 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5486
5487 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5488 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5489 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5490
5491 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005492
5493 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005494}
5495testcase TC_common_id() runs on test_CT {
5496 var MSC_ConnHdlr vc_conn;
5497 f_init(1, true);
5498 f_sleep(1.0);
5499 vc_conn := f_start_handler(refers(f_tc_common_id));
5500 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005501 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005502}
5503
Harald Weltee3bd6582018-01-31 22:51:25 +01005504private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005505 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005506 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005507 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005508
Harald Weltee3bd6582018-01-31 22:51:25 +01005509 /* send the single message we want to send */
5510 f_rsl_send_l3(l3);
5511}
5512
5513private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5514 timer T := sec;
5515 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005516 T.start;
5517 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005518 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5519 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005520 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005521 }
5522 [] T.timeout {
5523 setverdict(pass);
5524 }
5525 }
5526}
5527
Harald Weltee3bd6582018-01-31 22:51:25 +01005528/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5529private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5530 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5531 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005532 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005533}
Harald Welte898113b2018-01-31 18:32:21 +01005534testcase TC_unsol_ass_fail() runs on test_CT {
5535 var MSC_ConnHdlr vc_conn;
5536 f_init(1, true);
5537 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005538 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005539 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005540 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005541}
Harald Welte552620d2017-12-16 23:21:36 +01005542
Harald Welteea99a002018-01-31 20:46:43 +01005543
5544/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5545private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005546 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5547 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005548 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005549}
5550testcase TC_unsol_ass_compl() runs on test_CT {
5551 var MSC_ConnHdlr vc_conn;
5552 f_init(1, true);
5553 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005554 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005555 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005556 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005557}
5558
5559
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005560/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5561private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005562 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5563 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005564 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005565}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005566testcase TC_unsol_ho_fail() runs on test_CT {
5567 var MSC_ConnHdlr vc_conn;
5568 f_init(1, true);
5569 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005570 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005571 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005572 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005573}
5574
5575
Harald Weltee3bd6582018-01-31 22:51:25 +01005576/* short message from MS should be ignored */
5577private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005578 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005579 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005580 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005581
5582 /* send short message */
5583 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5584 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005585 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005586}
5587testcase TC_err_82_short_msg() runs on test_CT {
5588 var MSC_ConnHdlr vc_conn;
5589 f_init(1, true);
5590 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005591 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005592 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005593 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005594}
5595
5596
Harald Weltee9e02e42018-01-31 23:36:25 +01005597/* 24.008 8.4 Unknown message must trigger RR STATUS */
5598private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5599 f_est_single_l3(ts_RRM_UL_REL('00'O));
5600 timer T := 3.0
5601 alt {
5602 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5603 setverdict(pass);
5604 }
5605 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005606 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005607 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005608 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005609}
5610testcase TC_err_84_unknown_msg() runs on test_CT {
5611 var MSC_ConnHdlr vc_conn;
5612 f_init(1, true);
5613 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005614 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005615 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005616 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005617}
5618
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005619/***********************************************************************
5620 * Handover
5621 ***********************************************************************/
5622
Harald Welte94e0c342018-04-07 11:33:23 +02005623/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5624private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5625runs on test_CT {
5626 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5627 " timeslot "&int2str(ts_nr)&" ";
5628 f_vty_transceive(BSCVTY, cmd & suffix);
5629}
5630
Harald Welte261af4b2018-02-12 21:20:39 +01005631/* 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 +07005632private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5633 uint8_t bts_nr, uint8_t trx_nr,
5634 in RslChannelNr chan_nr)
5635{
Harald Welte261af4b2018-02-12 21:20:39 +01005636 /* FIXME: resolve those from component-global state */
5637 var integer ts_nr := chan_nr.tn;
5638 var integer ss_nr;
5639 if (ischosen(chan_nr.u.ch0)) {
5640 ss_nr := 0;
5641 } else if (ischosen(chan_nr.u.lm)) {
5642 ss_nr := chan_nr.u.lm.sub_chan;
5643 } else if (ischosen(chan_nr.u.sdcch4)) {
5644 ss_nr := chan_nr.u.sdcch4.sub_chan;
5645 } else if (ischosen(chan_nr.u.sdcch8)) {
5646 ss_nr := chan_nr.u.sdcch8.sub_chan;
5647 } else {
5648 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005649 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005650 }
5651
5652 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5653 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005654 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005655}
5656
Neels Hofmeyr91401012019-07-11 00:42:35 +02005657/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5658 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5659 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5660 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5661 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005662private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5663 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5664{
5665 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005666}
5667
5668/* intra-BSC hand-over between BTS0 and BTS1 */
5669private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005670 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5671 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005672
5673 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5674 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5675
Harald Weltea0630032018-03-20 21:09:55 +01005676 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005677 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005678
5679 var HandoverState hs := {
5680 rr_ho_cmpl_seen := false,
5681 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005682 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005683 expect_target_tsc := c_BtsParams[1].tsc
Harald Welte261af4b2018-02-12 21:20:39 +01005684 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005685 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005686 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005687 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5688 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005689
5690 /* From the MGW perspective, a handover is is characterized by
5691 * performing one MDCX operation with the MGW. So we expect to see
5692 * one more MDCX during handover. */
5693 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5694
Harald Welte261af4b2018-02-12 21:20:39 +01005695 alt {
5696 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005697 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005698
Philipp Maier4dae0652018-11-12 12:03:26 +01005699 /* Since this is an internal handover we expect the BSC to inform the
5700 * MSC about the event */
5701 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5702
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005703 /* Check the amount of MGCP transactions is still consistant with the
5704 * test expectation */
5705 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005706
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005707 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5708
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005709 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5710 * 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 +02005711 f_verify_encr_info(chan_act);
5712
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005713 f_chan_act_verify_tsc(chan_act, c_BtsParams[1].tsc);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005714
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005715 f_perform_clear(RSL1, RSL1_PROC);
5716
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005717 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005718}
5719
5720testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005721 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005722 var MSC_ConnHdlr vc_conn;
5723 f_init(2, true);
5724 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005725
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005726 pars.expect_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005727
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005728 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005729
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005730 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005731 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005732
5733 /* from f_establish_fully() */
5734 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5735 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5736 /* from handover */
5737 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5738 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5739 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5740 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005741 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5742 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005743 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005744 f_shutdown_helper(ho := true);
Harald Welte261af4b2018-02-12 21:20:39 +01005745}
Harald Weltee9e02e42018-01-31 23:36:25 +01005746
Oliver Smith7eabd312021-07-12 14:18:56 +02005747function 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 +02005748 var MSC_ConnHdlr vc_conn;
5749 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5750 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5751
5752 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005753 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005754 f_sleep(1.0);
5755
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005756 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005757
5758 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5759 vc_conn.done;
5760
5761 /* from f_establish_fully() */
5762 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5763 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5764 /* from handover */
5765 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5766 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5767 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5768 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005769 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5770 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005771 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005772 f_vty_encryption_a5_reset();
Oliver Smith39f53072022-10-27 14:44:04 +02005773 f_shutdown_helper(ho := true);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005774}
5775
5776testcase TC_ho_int_a5_0() runs on test_CT {
5777 f_tc_ho_int_a5('01'O);
5778}
5779
5780testcase TC_ho_int_a5_1() runs on test_CT {
5781 f_tc_ho_int_a5('02'O);
5782}
5783
5784testcase TC_ho_int_a5_3() runs on test_CT {
5785 f_tc_ho_int_a5('08'O);
5786}
5787
5788testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005789 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005790}
5791
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005792/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5793private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5794 g_pars := f_gen_test_hdlr_pars();
5795 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5796 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005797
5798 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5799 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5800
5801 f_establish_fully(ass_cmd, exp_compl);
5802 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5803
5804 var HandoverState hs := {
5805 rr_ho_cmpl_seen := false,
5806 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005807 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005808 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005809 };
5810 /* issue hand-over command on VTY */
5811 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5812 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5813 f_rslem_suspend(RSL1_PROC);
5814
5815 /* From the MGW perspective, a handover is is characterized by
5816 * performing one MDCX operation with the MGW. So we expect to see
5817 * one more MDCX during handover. */
5818 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5819
5820 var RSL_Message rsl;
5821 var PDU_ML3_NW_MS l3;
5822 var RslChannelNr new_chan_nr;
5823 var GsmArfcn arfcn;
5824 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5825 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5826 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5827 setverdict(fail, "Expected handoverCommand");
5828 mtc.stop;
5829 }
5830 }
5831 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5832 new_chan_nr, arfcn);
5833
5834 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5835
5836 /* resume processing of RSL DChan messages, which was temporarily suspended
5837 * before performing a hand-over */
5838 f_rslem_resume(RSL1_PROC);
5839 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5840
5841 f_sleep(1.0);
5842
5843 /* Handover fails because no HANDO DET appears on the new lchan,
5844 * and the old lchan reports a Radio Link Failure. */
5845 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5846
5847 var PDU_BSSAP rx_clear_request;
5848 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5849 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5850 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5851
5852 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5853
5854 var MgcpCommand mgcp;
5855 interleave {
5856 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5857 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005858 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005859 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005860 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005861 }
5862 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005863 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005864 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005865 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005866 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005867 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5868 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5869 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005870 }
5871
5872 f_sleep(0.5);
5873 setverdict(pass);
5874}
5875testcase TC_ho_int_radio_link_failure() runs on test_CT {
5876 var MSC_ConnHdlr vc_conn;
5877 f_init(2, true);
5878 f_sleep(1.0);
5879
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005880 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005881
5882 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5883 vc_conn.done;
5884
5885 /* from f_establish_fully() */
5886 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5887 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5888 /* from handover */
5889 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5890 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5891 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5892 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005893 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5894 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005895 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005896 f_shutdown_helper(ho := true);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005897}
5898
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005899/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005900private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005901 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005902 var template MgcpResponse mgcp_resp;
5903 var MGCP_RecvFrom mrf;
5904 var template MgcpMessage msg_resp;
5905 var template MgcpMessage msg_dlcx := {
5906 command := tr_DLCX()
5907 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005908
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005909 if (g_pars.aoip) {
5910 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005911 log("Got first DLCX: ", mgcp);
5912 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005913 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005914
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005915 MGCP.receive(tr_DLCX()) -> value mgcp {
5916 log("Got second DLCX: ", mgcp);
5917 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5918 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005919 } else {
5920 /* For SCCPLite, BSC doesn't handle the MSC-side */
5921 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5922 log("Got first DLCX: ", mrf.msg.command);
5923 msg_resp := {
5924 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5925 }
5926 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5927 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005928 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005929}
5930
Oliver Smithc9a5f532022-10-21 11:32:23 +02005931private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit,
5932 boolean skip_meas_rep := false) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005933
Oliver Smithc9a5f532022-10-21 11:32:23 +02005934 if (not skip_meas_rep) {
5935 var NcellReports neighbor_rep := {
5936 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5937 };
5938 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5939 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5940 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005941
Oliver Smithc9a5f532022-10-21 11:32:23 +02005942 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
5943 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005944
5945 f_sleep(0.5);
5946 /* The MSC negotiates Handover Request and Handover Request Ack with
5947 * the other BSS and comes back with a BSSMAP Handover Command
5948 * containing an RR Handover Command coming from the target BSS... */
5949
5950 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5951 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5952 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5953 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5954 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5955
5956 /* expect the Handover Command to go out on RR */
5957 var RSL_Message rsl_ho_cmd
5958 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5959 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5960 var RSL_IE_Body rsl_ho_cmd_l3;
5961 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5962 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5963 setverdict(fail);
5964 } else {
5965 log("Found L3 Info: ", rsl_ho_cmd_l3);
5966 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5967 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5968 setverdict(fail);
5969 } else {
5970 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5971 setverdict(pass);
5972 }
5973 }
5974
5975 /* When the other BSS has reported a completed handover, this side is
5976 * torn down. */
5977
5978 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5979 var BssmapCause cause := enum2int(cause_val);
5980 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5981
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005982 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005983
5984 interleave {
5985 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5986 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5987 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005988 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5989 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5990 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005991 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005992 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005993}
5994
5995private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5996 g_pars := f_gen_test_hdlr_pars();
5997 var PDU_BSSAP ass_req := f_gen_ass_req();
5998 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5999 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6000 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6001 f_establish_fully(ass_req, exp_compl);
6002
6003 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006004}
6005testcase TC_ho_out_of_this_bsc() runs on test_CT {
6006 var MSC_ConnHdlr vc_conn;
6007
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01006008 f_init_vty();
6009 f_bts_0_cfg(BSCVTY,
6010 {"neighbor-list mode automatic",
6011 "handover 1",
6012 "handover algorithm 2",
6013 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006014 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01006015 "neighbor lac 99 arfcn 123 bsic any"});
6016 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6017
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006018 f_init(1, true);
6019 f_sleep(1.0);
6020
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006021 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006022
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006023 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
6024 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006025
6026 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6027 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6028 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6029 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6030 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6031 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
6032 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006033 f_shutdown_helper(ho := true);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006034}
6035
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006036private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6037 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07006038 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07006039 octetstring l3 := '0123456789'O)
6040runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02006041 /* The old lchan and conn should still be active. See that arbitrary L3
6042 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006043 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02006044 var template PDU_BSSAP exp_data := {
6045 discriminator := '1'B,
6046 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07006047 dlci := dlci,
6048 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02006049 pdu := {
6050 dtap := l3
6051 }
6052 };
6053 BSSAP.receive(exp_data);
6054 setverdict(pass);
6055}
6056
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006057private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6058 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006059 template (value) OCT1 dlci := '00'O,
6060 octetstring l3 := '0123456789'O)
6061runs on MSC_ConnHdlr {
6062 BSSAP.send(PDU_BSSAP:{
6063 discriminator := '1'B,
6064 spare := '0000000'B,
6065 dlci := dlci,
6066 lengthIndicator := lengthof(l3),
6067 pdu := {
6068 dtap := l3
6069 }
6070 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006071 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006072 setverdict(pass);
6073}
6074
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006075/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
6076 * simply never sends a BSSMAP Handover Command. */
6077private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006078 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006079
6080 var PDU_BSSAP ass_req := f_gen_ass_req();
6081 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6082 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6083 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6084 f_establish_fully(ass_req, exp_compl);
6085
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006086 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006087 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6088
6089 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6090
6091 /* osmo-bsc should time out 10 seconds after the handover started.
6092 * Let's give it a bit extra. */
6093 f_sleep(15.0);
6094
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006095 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006096 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006097 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006098}
6099testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
6100 var MSC_ConnHdlr vc_conn;
6101
6102 f_init(1, true);
6103 f_sleep(1.0);
6104
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006105 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006106
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006107 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
6108 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006109
6110 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6111 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6112 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6113 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6114 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6115 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6116 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006117 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006118}
6119
6120/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
6121 * RR Handover Failure. */
6122private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006123 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006124
6125 var PDU_BSSAP ass_req := f_gen_ass_req();
6126 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6127 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6128 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6129 f_establish_fully(ass_req, exp_compl);
6130
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006131 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006132 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6133
6134 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6135
6136 f_sleep(0.5);
6137 /* The MSC negotiates Handover Request and Handover Request Ack with
6138 * the other BSS and comes back with a BSSMAP Handover Command
6139 * containing an RR Handover Command coming from the target BSS... */
6140
6141 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6142 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6143 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6144 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6145 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6146
6147 /* expect the Handover Command to go out on RR */
6148 var RSL_Message rsl_ho_cmd
6149 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6150 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6151 var RSL_IE_Body rsl_ho_cmd_l3;
6152 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6153 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6154 setverdict(fail);
6155 } else {
6156 log("Found L3 Info: ", rsl_ho_cmd_l3);
6157 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6158 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6159 setverdict(fail);
6160 } else {
6161 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6162 setverdict(pass);
6163 }
6164 }
6165
6166 f_sleep(0.2);
6167 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6168
6169 /* Should tell the MSC about the failure */
6170 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6171
6172 f_sleep(1.0);
6173
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006174 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006175 f_sleep(1.0);
6176
6177 setverdict(pass);
6178 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006179 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006180}
6181testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
6182 var MSC_ConnHdlr vc_conn;
6183
6184 f_init(1, true);
6185 f_sleep(1.0);
6186
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006187 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006188
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006189 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
6190 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006191
6192 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6193 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6194 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6195 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6196 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6197 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
6198 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006199 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006200}
6201
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006202/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
6203 * (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 +02006204 * and the lchan is released. */
6205private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006206 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006207
6208 var PDU_BSSAP ass_req := f_gen_ass_req();
6209 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6210 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6211 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6212 f_establish_fully(ass_req, exp_compl);
6213
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006214 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006215 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6216
6217 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6218
6219 f_sleep(0.5);
6220 /* The MSC negotiates Handover Request and Handover Request Ack with
6221 * the other BSS and comes back with a BSSMAP Handover Command
6222 * containing an RR Handover Command coming from the target BSS... */
6223
6224 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6225 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6226 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6227 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6228 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6229
6230 /* expect the Handover Command to go out on RR */
6231 var RSL_Message rsl_ho_cmd
6232 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6233 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6234 var RSL_IE_Body rsl_ho_cmd_l3;
6235 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6236 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6237 setverdict(fail);
6238 } else {
6239 log("Found L3 Info: ", rsl_ho_cmd_l3);
6240 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6241 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6242 setverdict(fail);
6243 } else {
6244 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6245 setverdict(pass);
6246 }
6247 }
6248
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006249 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6250 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6251 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006252
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006253 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006254 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6255 log("Got BSSMAP Clear Request");
6256 /* Instruct BSC to clear channel */
6257 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6258 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6259
6260 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006261 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006262 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6263 log("Got Deact SACCH");
6264 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006265 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006266 log("Got RR Release");
6267 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006268 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006269 log("Got RF Chan Rel");
6270 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006271 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006272 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006273 }
6274
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006275 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006276 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006277 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006278
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006279 setverdict(pass);
6280 f_sleep(1.0);
6281}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006282testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006283 var MSC_ConnHdlr vc_conn;
6284
6285 f_init(1, true);
6286 f_sleep(1.0);
6287
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006288 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006289
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006290 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006291 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006292
6293 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6294 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6295 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6296 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6297 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6298 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6299 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006300 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006301}
6302
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006303private 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 +01006304 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006305 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6306 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6307 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6308 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6309 * before we get started. */
6310 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6311 f_rslem_register(0, new_chan_nr);
6312 g_chan_nr := new_chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06006313 var uint3_t expect_target_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006314 f_sleep(1.0);
6315
6316 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6317 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006318 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006319
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006320 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6321 cell_id_source := g_pars.cell_id_source,
6322 oldToNewBSSIEs := oldToNewBSSIEs,
6323 enc := g_pars.encr);
6324 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6325 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6326 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6327 } else {
6328 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6329 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6330 BSSAP.send(ho_req);
6331 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006332
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006333 alt {
6334 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6335 if (g_pars.expect_ho_fail) {
6336 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6337 "Expected Handover Request to fail, but got Handover Request Ack")
6338 }
6339 }
6340 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6341 if (not g_pars.expect_ho_fail) {
6342 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6343 "Expected Handover Request to succeed, but got Handover Failure")
6344 }
6345 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6346 // For now just accept any cause.
6347 BSSAP.receive(tr_BSSMAP_ClearRequest);
6348 setverdict(pass);
6349 return;
6350 }
6351 }
6352
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006353 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6354
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006355 /* we're sure that the channel activation is done now, verify the parameters in it */
6356 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6357 f_verify_encr_info(chan_act);
6358 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006359
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006360 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6361 if (not g_pars.aoip) {
6362 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6363 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6364 }
6365 /* TODO: check actual codecs? */
6366 } else {
6367 if (g_pars.aoip) {
6368 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6369 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6370 }
6371 }
6372
6373 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6374 if (not g_pars.aoip) {
6375 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6376 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6377 }
6378 /* TODO: check actual codec? */
6379 } else {
6380 if (g_pars.aoip) {
6381 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6382 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6383 }
6384 }
6385
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006386 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006387 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6388 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6389 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6390 log("L3 Info in HO Request Ack is ", ho_command);
6391
6392 var GsmArfcn arfcn;
6393 var RslChannelNr actual_new_chan_nr;
6394 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6395 actual_new_chan_nr, arfcn);
6396
6397 if (actual_new_chan_nr != new_chan_nr) {
6398 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6399 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6400 setverdict(fail);
6401 return;
6402 }
6403 log("Handover Command chan_nr is", actual_new_chan_nr);
6404
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006405 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6406 if (not match(got_tsc, expect_target_tsc)) {
6407 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6408 expect_target_tsc, " got ", got_tsc);
6409 mtc.stop;
6410 } else {
6411 log("handoverCommand: verified TSC = ", got_tsc);
6412 }
6413
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006414 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6415 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6416 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6417 var template (present) CipherModeSetting_TV tr_cms := {
6418 sC := '0'B, /* no ciphering by default */
6419 algorithmIdentifier := '000'B,
6420 elementIdentifier := ?
6421 };
6422 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6423 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6424 tr_cms.sC := '1'B;
6425 }
6426 if (not match(cms, tr_cms)) {
6427 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6428 cms, ", expected: ", tr_cms);
6429 }
6430 } else {
6431 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6432 }
6433
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006434 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6435 * tells the MS to handover to the new lchan. Here comes the new MS on
6436 * the new lchan with a Handover RACH: */
6437
6438 /* send handover detect */
6439
6440 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6441
6442 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6443
6444 /* send handover complete over the new channel */
6445
6446 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6447 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6448 enc_PDU_ML3_MS_NW(l3_tx)));
6449
6450 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006451 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006452 setverdict(pass);
6453}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006454
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006455private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006456 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006457 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6458 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6459 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006460 }
6461 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006462 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006463 } else {
6464 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006465 }
6466 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006467 if (g_pars.expect_ho_fail) {
6468 f_perform_clear_no_lchan();
6469 } else {
6470 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6471 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006472 setverdict(pass);
6473}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006474function 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 +01006475 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006476
6477 f_init(1, true);
6478 f_sleep(1.0);
6479
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006480 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006481 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006482
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006483 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6484 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006485
6486 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6487 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006488
6489 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006490 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006491 if (pars.expect_ho_fail) {
6492 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6493 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6494 } else {
6495 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6496 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6497 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006498 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006499
6500 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006501}
6502
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006503testcase TC_ho_into_this_bsc() runs on test_CT {
6504 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6505 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006506 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006507}
6508
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006509function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6510 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006511 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006512 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006513 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006514 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Oliver Smith39f53072022-10-27 14:44:04 +02006515 f_shutdown_helper(ho := true);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006516}
6517
6518testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006519 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006520}
6521
6522testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006523 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006524}
6525
6526testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006527 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006528}
6529
6530testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006531 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006532}
6533
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006534/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6535 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6536 *
6537 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6538 * omitted.
6539 *
6540 * Related: SYS#5839
6541 */
6542testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6543 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6544}
6545
6546testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6547 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6548}
6549
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006550/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6551testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6552 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6553 expect_fail := true); // 0x18 = A5/3 and A5/4
6554}
6555
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006556testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6557 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6558 pars.host_aoip_tla := "::6";
6559 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006560 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006561}
6562
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006563/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006564 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006565 channel is later released (RR CHannel Release), should trigger inclusion of
6566 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6567 neighbors. */
6568testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6569 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6570 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006571 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006572 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006573
6574 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6575 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6576 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006577 f_shutdown_helper(ho := true);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006578}
6579
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006580/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6581testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6582 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6583 pars.encr := f_encr_params('08'O); /* only A5/3 */
6584 pars.last_used_eutran_plmn := '323454'O;
6585 pars.exp_fast_return := true;
6586 f_tc_ho_into_this_bsc_main(pars);
6587
6588 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6589 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6590 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006591 f_shutdown_helper(ho := true);
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006592}
6593
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006594/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6595 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6596 list when the channel is released. */
6597testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6598 f_init_vty();
6599 f_vty_allow_srvcc_fast_return(true, 0)
6600
6601 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6602 pars.last_used_eutran_plmn := '323454'O;
6603 pars.exp_fast_return := false;
6604 f_tc_ho_into_this_bsc_main(pars);
6605 f_vty_allow_srvcc_fast_return(false, 0);
6606 f_shutdown_helper();
6607}
6608
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006609/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6610testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6611 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6612 pars.last_used_eutran_plmn := '323454'O;
6613 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6614 f_tc_ho_into_this_bsc_main(pars);
6615
6616 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6617 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6618 f_ctrs_bsc_and_bts_verify();
6619 f_shutdown_helper();
6620}
6621
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006622private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6623 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6624 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6625 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6626 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6627 setverdict(pass);
6628}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006629
6630private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6631 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006632 var MSC_ConnHdlr vc_conn;
6633 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6634
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006635 f_init_vty();
6636 f_bts_0_cfg(BSCVTY,
6637 {"neighbor-list mode automatic",
6638 "handover 1",
6639 "handover algorithm 2",
6640 "handover2 window rxlev averaging 1",
6641 "no neighbors",
6642 "neighbor lac 99 arfcn 123 bsic any"});
6643 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6644
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006645 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006646 if (disable_fast_return) {
6647 f_vty_allow_srvcc_fast_return(true, 0);
6648 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006649 f_sleep(1.0);
6650
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006651 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006652
6653 pars.last_used_eutran_plmn := '323454'O;
6654 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6655 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6656
6657 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6658 vc_conn.done;
6659
6660 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6661 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6662 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6663 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6664 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6665 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006666
6667 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6668 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006669 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006670
6671 if (disable_fast_return) {
6672 f_vty_allow_srvcc_fast_return(false, 0);
6673 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006674 f_shutdown_helper();
6675}
6676
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006677/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6678 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6679 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6680 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6681testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6682 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6683}
6684/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6685 * independently of fast-reture allowed/forbidden in local BTS */
6686testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6687 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6688}
6689
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006690private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6691 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6692 f_rslem_register(0, new_chan_nr);
6693 g_chan_nr := new_chan_nr;
6694 f_sleep(1.0);
6695
6696 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6697 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6698 activate(as_Media());
6699
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006700 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006701 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006702 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006703
6704 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6705
6706 var PDU_BSSAP rx_bssap;
6707 var octetstring ho_command_str;
6708
6709 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6710
6711 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6712 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6713 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6714 log("L3 Info in HO Request Ack is ", ho_command);
6715
6716 var GsmArfcn arfcn;
6717 var RslChannelNr actual_new_chan_nr;
6718 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6719 actual_new_chan_nr, arfcn);
6720
6721 if (actual_new_chan_nr != new_chan_nr) {
6722 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6723 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6724 setverdict(fail);
6725 return;
6726 }
6727 log("Handover Command chan_nr is", actual_new_chan_nr);
6728
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006729 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6730 f_sleep(1.0);
6731
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006732 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6733 * tells the MS to handover to the new lchan. In this case, the MS
6734 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6735 * Handover Failure to the MSC. The procedure according to 3GPP TS
6736 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6737 * BSSMAP Clear Command: */
6738
6739 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6740 var BssmapCause cause := enum2int(cause_val);
6741 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6742
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006743 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006744 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006745 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006746
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006747 setverdict(pass);
6748 f_sleep(1.0);
6749
6750 setverdict(pass);
6751}
6752testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6753 var MSC_ConnHdlr vc_conn;
6754 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6755
6756 f_init(1, true);
6757 f_sleep(1.0);
6758
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006759 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006760
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006761 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6762 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006763
6764 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6765 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006766
6767 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6768 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6769 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6770 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6771 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006772 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006773}
6774
6775private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6776 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6777 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6778 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6779 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6780 * before we get started. */
6781 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6782 f_rslem_register(0, new_chan_nr);
6783 g_chan_nr := new_chan_nr;
6784 f_sleep(1.0);
6785
6786 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6787 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6788 activate(as_Media());
6789
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006790 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006791 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006792 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006793
6794 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6795
6796 var PDU_BSSAP rx_bssap;
6797 var octetstring ho_command_str;
6798
6799 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6800
6801 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6802 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6803 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6804 log("L3 Info in HO Request Ack is ", ho_command);
6805
6806 var GsmArfcn arfcn;
6807 var RslChannelNr actual_new_chan_nr;
6808 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6809 actual_new_chan_nr, arfcn);
6810
6811 if (actual_new_chan_nr != new_chan_nr) {
6812 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6813 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6814 setverdict(fail);
6815 return;
6816 }
6817 log("Handover Command chan_nr is", actual_new_chan_nr);
6818
6819 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6820 * tells the MS to handover to the new lchan. Here comes the new MS on
6821 * the new lchan with a Handover RACH: */
6822
6823 /* send handover detect */
6824
6825 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6826
6827 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6828
6829 /* The MSC chooses to clear the connection now, maybe we got the
6830 * Handover RACH on the new cell but the MS still signaled Handover
6831 * Failure to the old BSS? */
6832
6833 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6834 var BssmapCause cause := enum2int(cause_val);
6835 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6836
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006837 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006838 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006839 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006840
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006841 f_sleep(1.0);
6842}
6843testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6844 var MSC_ConnHdlr vc_conn;
6845 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6846
6847 f_init(1, true);
6848 f_sleep(1.0);
6849
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006850 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006851
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006852 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6853 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006854
6855 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6856 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006857
6858 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6859 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6860 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6861 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6862 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006863 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006864}
6865
6866/* The new BSS's lchan times out before the MSC decides that handover failed. */
6867private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6868 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6869 f_rslem_register(0, new_chan_nr);
6870 g_chan_nr := new_chan_nr;
6871 f_sleep(1.0);
6872
6873 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6874 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006875 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006876
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006877 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006878 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006879 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006880
6881 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6882
6883 var PDU_BSSAP rx_bssap;
6884 var octetstring ho_command_str;
6885
6886 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6887
6888 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6889 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6890 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6891 log("L3 Info in HO Request Ack is ", ho_command);
6892
6893 var GsmArfcn arfcn;
6894 var RslChannelNr actual_new_chan_nr;
6895 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6896 actual_new_chan_nr, arfcn);
6897
6898 if (actual_new_chan_nr != new_chan_nr) {
6899 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6900 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6901 setverdict(fail);
6902 return;
6903 }
6904 log("Handover Command chan_nr is", actual_new_chan_nr);
6905
6906 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6907 * tells the MS to handover to the new lchan. But the MS never shows up
6908 * on the new lchan. */
6909
6910 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6911
6912 /* Did osmo-bsc also send a Clear Request? */
6913 timer T := 0.5;
6914 T.start;
6915 alt {
6916 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6917 [] T.timeout { }
6918 }
6919
6920 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6921 * asked for it, this is a Handover Failure after all). */
6922
6923 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6924 var BssmapCause cause := enum2int(cause_val);
6925 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6926
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006927 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006928 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006929 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006930
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006931 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006932}
6933testcase TC_ho_in_fail_no_detect() runs on test_CT {
6934 var MSC_ConnHdlr vc_conn;
6935 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6936
6937 f_init(1, true);
6938 f_sleep(1.0);
6939
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006940 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006941
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006942 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6943 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006944
6945 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6946 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006947
6948 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6949 f_ctrs_bsc_and_bts_add(0, "handover:error");
6950 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6951 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6952 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006953 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006954}
6955
6956/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6957private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6958 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6959 f_rslem_register(0, new_chan_nr);
6960 g_chan_nr := new_chan_nr;
6961 f_sleep(1.0);
6962
6963 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6964 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006965 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006966
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006967 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006968 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006969 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006970
6971 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6972
6973 var PDU_BSSAP rx_bssap;
6974 var octetstring ho_command_str;
6975
6976 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6977
6978 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6979 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6980 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6981 log("L3 Info in HO Request Ack is ", ho_command);
6982
6983 var GsmArfcn arfcn;
6984 var RslChannelNr actual_new_chan_nr;
6985 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6986 actual_new_chan_nr, arfcn);
6987
6988 if (actual_new_chan_nr != new_chan_nr) {
6989 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6990 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6991 setverdict(fail);
6992 return;
6993 }
6994 log("Handover Command chan_nr is", actual_new_chan_nr);
6995
6996 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6997 * tells the MS to handover to the new lchan. But the MS never shows up
6998 * on the new lchan. */
6999
7000 BSSAP.receive(tr_BSSMAP_HandoverFailure);
7001
7002 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007003 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02007004
7005 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007006 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
7007 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
7008 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02007009 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007010 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007011 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007012
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007013 f_sleep(1.0);
7014}
7015testcase TC_ho_in_fail_no_detect2() runs on test_CT {
7016 var MSC_ConnHdlr vc_conn;
7017 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7018
7019 f_init(1, true);
7020 f_sleep(1.0);
7021
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007022 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007023
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007024 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
7025 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007026
7027 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
7028 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007029
7030 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7031 f_ctrs_bsc_and_bts_add(0, "handover:error");
7032 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
7033 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
7034 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007035 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007036}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01007037
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01007038/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
7039 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
7040 * empty N-Connect case. */
7041testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
7042 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7043 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
7044 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02007045 f_shutdown_helper(ho := true);
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01007046}
7047
Neels Hofmeyr91401012019-07-11 00:42:35 +02007048type record of charstring Commands;
7049
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007050private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02007051{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007052 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007053 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007054 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007055 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007056 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02007057}
7058
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01007059private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
7060{
7061 f_vty_enter_cfg_cs7_inst(pt, 0);
7062 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
7063 f_vty_transceive(pt, cmds[i]);
7064 }
7065 f_vty_transceive(pt, "end");
7066}
7067
Neels Hofmeyr91401012019-07-11 00:42:35 +02007068private function f_probe_for_handover(charstring log_label,
7069 charstring log_descr,
7070 charstring handover_vty_cmd,
7071 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007072 boolean is_inter_bsc_handover := false,
7073 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02007074runs on MSC_ConnHdlr
7075{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02007076 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
7077 * lchans to be established on bts 1 or bts 2. */
7078 f_rslem_suspend(RSL1_PROC);
7079 f_rslem_suspend(RSL2_PROC);
7080
Neels Hofmeyr91401012019-07-11 00:42:35 +02007081 var RSL_Message rsl;
7082
7083 var charstring log_msg := " (expecting handover)"
7084 if (not expect_handover) {
7085 log_msg := " (expecting NO handover)";
7086 }
7087 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
7088 f_vty_transceive(BSCVTY, handover_vty_cmd);
7089
Neels Hofmeyr91401012019-07-11 00:42:35 +02007090 timer T := 2.0;
7091 T.start;
7092
7093 alt {
7094 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
7095 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
7096 log("Rx L3 from net: ", l3);
7097 if (ischosen(l3.msgs.rrm.handoverCommand)) {
7098 var RslChannelNr new_chan_nr;
7099 var GsmArfcn arfcn;
7100 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
7101 new_chan_nr, arfcn);
7102 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
7103 log(l3.msgs.rrm.handoverCommand);
7104
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007105 /* Verify correct TSC in handoverCommand */
7106 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
7107 if (not match(got_tsc, expect_target_tsc)) {
7108 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
7109 expect_target_tsc, " got ", got_tsc);
7110 mtc.stop;
7111 } else {
7112 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
7113 expect_target_tsc, ")");
7114 }
7115
Neels Hofmeyr91401012019-07-11 00:42:35 +02007116 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
7117 * matter on which BTS it really is, we're not going to follow through an entire handover
7118 * anyway. */
7119 f_rslem_register(0, new_chan_nr, RSL1_PROC);
7120 f_rslem_resume(RSL1_PROC);
7121 f_rslem_register(0, new_chan_nr, RSL2_PROC);
7122 f_rslem_resume(RSL2_PROC);
7123
7124 if (expect_handover and not is_inter_bsc_handover) {
7125 setverdict(pass);
7126 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
7127 } else {
7128 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
7129 & log_label & ": " & log_descr);
7130 }
7131
7132 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
7133 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
7134 * Handover Failure. */
7135 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
7136
7137 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
7138 f_sleep(0.5);
7139 RSL1.clear;
7140 RSL2.clear;
7141 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
7142 break;
7143 } else {
7144 repeat;
7145 }
7146 }
7147 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
7148 if (expect_handover and is_inter_bsc_handover) {
7149 setverdict(pass);
7150 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
7151 } else {
7152 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
7153 & log_label & ": " & log_descr);
7154 }
7155
7156 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
7157
7158 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
7159 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
7160 * setting a short timeout and waiting is the only way. */
7161 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
7162 f_sleep(1.5);
7163 log("f_probe_for_handover(" & log_label & "): ...done");
7164
7165 break;
7166 }
7167 [] T.timeout {
7168 if (expect_handover) {
7169 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
7170 & log_label & ": " & log_descr);
7171 } else {
7172 setverdict(pass);
7173 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
7174 }
7175 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
7176 break;
7177 }
7178 }
7179
7180 f_rslem_resume(RSL1_PROC);
7181 f_rslem_resume(RSL2_PROC);
7182 f_sleep(3.0);
7183 RSL.clear;
7184
7185 log("f_probe_for_handover(" & log_label & "): done clearing");
7186}
7187
7188/* Test the effect of various neighbor configuration scenarios:
7189 *
7190 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
7191 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
7192 */
7193private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
7194 g_pars := f_gen_test_hdlr_pars();
7195 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
7196 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007197
7198 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
7199 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
7200
7201 /* Establish lchan at bts 0 */
7202 f_establish_fully(ass_cmd, exp_compl);
7203
7204 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
7205 f_vty_enter_cfg_network(BSCVTY);
7206 f_vty_transceive(BSCVTY, "timer T7 1");
7207 f_vty_transceive(BSCVTY, "end");
7208}
7209
7210private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
7211 f_tc_ho_neighbor_config_start();
7212
7213 /*
7214 * bts 0 ARFCN 871 BSIC 10
7215 * bts 1 ARFCN 871 BSIC 11
7216 * bts 2 ARFCN 871 BSIC 12
7217 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7218 */
7219
7220 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007221 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007222 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
7223 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007224 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007225
7226 f_probe_for_handover("1.b", "HO to unknown cell does not start",
7227 "handover any to arfcn 13 bsic 39",
7228 false);
7229
7230 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
7231 "handover any to arfcn 871 bsic 12",
7232 false);
7233
7234 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
7235 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007236 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007237
7238 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007239}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007240testcase TC_ho_neighbor_config_1() runs on test_CT {
7241 var MSC_ConnHdlr vc_conn;
7242 f_init(3, true, guard_timeout := 60.0);
7243 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007244 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007245 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7246 vc_conn.done;
7247
7248 /* f_tc_ho_neighbor_config_start() */
7249 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7250 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7251
7252 /* 1.a */
7253 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7254 * handover quickly by sending a Handover Failure message. */
7255 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7256 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7257 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7258 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007259 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7260 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007261
7262 /* 1.b */
7263 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7264 f_ctrs_bsc_and_bts_add(0, "handover:error");
7265
7266 /* 1.c */
7267 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7268 f_ctrs_bsc_and_bts_add(0, "handover:error");
7269
7270 /* 1.d */
7271 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7272 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7273 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7274 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007275 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7276 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007277
7278 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007279 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007280}
7281
Neels Hofmeyr91401012019-07-11 00:42:35 +02007282private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7283 f_tc_ho_neighbor_config_start();
7284
7285 /*
7286 * bts 0 ARFCN 871 BSIC 10
7287 * bts 1 ARFCN 871 BSIC 11
7288 * bts 2 ARFCN 871 BSIC 12
7289 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7290 */
7291
7292 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007293 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007294 f_sleep(0.5);
7295
7296 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7297 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007298 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007299
7300 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7301 "handover any to arfcn 871 bsic 12",
7302 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007303 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007304}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007305testcase TC_ho_neighbor_config_2() runs on test_CT {
7306 var MSC_ConnHdlr vc_conn;
7307 f_init(3, true, guard_timeout := 50.0);
7308 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007309 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007310 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7311 vc_conn.done;
7312
7313 /* f_tc_ho_neighbor_config_start() */
7314 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7315 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7316
7317 /* 2.a */
7318 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7319 * handover quickly by sending a Handover Failure message. */
7320 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7321 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7322 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7323 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007324 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7325 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007326
7327 /* 2.b */
7328 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7329 f_ctrs_bsc_and_bts_add(0, "handover:error");
7330
7331 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007332 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007333}
7334
Neels Hofmeyr91401012019-07-11 00:42:35 +02007335private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7336 f_tc_ho_neighbor_config_start();
7337
7338 /*
7339 * bts 0 ARFCN 871 BSIC 10
7340 * bts 1 ARFCN 871 BSIC 11
7341 * bts 2 ARFCN 871 BSIC 12
7342 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7343 */
7344
7345 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007346 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007347 f_sleep(0.5);
7348
7349 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7350 "handover any to arfcn 871 bsic 11",
7351 false);
7352 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",
7353 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007354 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007355 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007356}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007357testcase TC_ho_neighbor_config_3() runs on test_CT {
7358 var MSC_ConnHdlr vc_conn;
7359 f_init(3, true, guard_timeout := 50.0);
7360 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007361 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007362 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7363 vc_conn.done;
7364
7365 /* f_tc_ho_neighbor_config_start() */
7366 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7367 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7368
7369 /* 3.a */
7370 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7371 f_ctrs_bsc_and_bts_add(0, "handover:error");
7372
7373 /* 3.b */
7374 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7375 * handover quickly by sending a Handover Failure message. */
7376 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7377 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7378 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7379 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007380 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7381 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007382
7383 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007384 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007385}
7386
Neels Hofmeyr91401012019-07-11 00:42:35 +02007387private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7388 f_tc_ho_neighbor_config_start();
7389
7390 /*
7391 * bts 0 ARFCN 871 BSIC 10
7392 * bts 1 ARFCN 871 BSIC 11
7393 * bts 2 ARFCN 871 BSIC 12
7394 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7395 */
7396
7397 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007398 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007399 f_sleep(0.5);
7400
7401 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7402 "handover any to arfcn 871 bsic 11",
7403 false);
7404 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7405 "handover any to arfcn 871 bsic 12",
7406 false);
7407 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7408 "handover any to arfcn 123 bsic 45",
7409 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007410 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007411}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007412testcase TC_ho_neighbor_config_4() runs on test_CT {
7413 var MSC_ConnHdlr vc_conn;
7414 f_init(3, true, guard_timeout := 50.0);
7415 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007416 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007417 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7418 vc_conn.done;
7419
7420 /* f_tc_ho_neighbor_config_start() */
7421 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7422 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7423
7424 /* 4.a */
7425 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7426 f_ctrs_bsc_and_bts_add(0, "handover:error");
7427
7428 /* 4.b */
7429 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7430 f_ctrs_bsc_and_bts_add(0, "handover:error");
7431
7432 /* 4.c */
7433 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7434 * handover quickly by timing out after the Handover Required message */
7435 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7436 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7437 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7438 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7439
7440 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007441 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007442}
7443
Neels Hofmeyr91401012019-07-11 00:42:35 +02007444private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7445 f_tc_ho_neighbor_config_start();
7446
7447 /*
7448 * bts 0 ARFCN 871 BSIC 10
7449 * bts 1 ARFCN 871 BSIC 11
7450 * bts 2 ARFCN 871 BSIC 12
7451 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7452 */
7453
7454 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 +02007455 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007456 f_sleep(0.5);
7457
7458 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7459 "handover any to arfcn 871 bsic 12",
7460 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007461 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007462}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007463testcase TC_ho_neighbor_config_5() runs on test_CT {
7464 var MSC_ConnHdlr vc_conn;
7465 f_init(3, true);
7466 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007467 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007468 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7469 vc_conn.done;
7470
7471 /* f_tc_ho_neighbor_config_start() */
7472 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7473 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7474
7475 /* 5 */
7476 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7477 * handover quickly by timing out after the Handover Required message */
7478 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7479 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7480 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7481 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7482
7483 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007484 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007485}
7486
Neels Hofmeyr91401012019-07-11 00:42:35 +02007487private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7488 f_tc_ho_neighbor_config_start();
7489
7490 /*
7491 * bts 0 ARFCN 871 BSIC 10
7492 * bts 1 ARFCN 871 BSIC 11
7493 * bts 2 ARFCN 871 BSIC 12
7494 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7495 */
7496
7497 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7498 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007499 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007500 f_sleep(0.5);
7501
7502 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7503 "handover any to arfcn 871 bsic 12",
7504 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007505 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007506}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007507testcase TC_ho_neighbor_config_6() runs on test_CT {
7508 var MSC_ConnHdlr vc_conn;
7509 f_init(3, true);
7510 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007511 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007512 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7513 vc_conn.done;
7514
7515 /* f_tc_ho_neighbor_config_start() */
7516 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7517 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7518
7519 /* 6.a */
7520 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7521 * handover quickly by timing out after the Handover Required message */
7522 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7523 f_ctrs_bsc_and_bts_add(0, "handover:error");
7524
7525 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007526 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007527}
7528
Neels Hofmeyr91401012019-07-11 00:42:35 +02007529private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7530 f_tc_ho_neighbor_config_start();
7531
7532 /*
7533 * bts 0 ARFCN 871 BSIC 10
7534 * bts 1 ARFCN 871 BSIC 11
7535 * bts 2 ARFCN 871 BSIC 12
7536 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7537 */
7538
7539 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7540 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007541 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007542 f_sleep(0.5);
7543
7544 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7545 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007546 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007547 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7548 "handover any to arfcn 123 bsic 45",
7549 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007550 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007551}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007552testcase TC_ho_neighbor_config_7() runs on test_CT {
7553 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007554 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007555 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007556 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007557 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7558 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007559
7560 /* f_tc_ho_neighbor_config_start() */
7561 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7562 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7563
7564 /* 7.a */
7565 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7566 * handover quickly by sending a Handover Failure message. */
7567 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7568 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7569 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7570 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007571 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7572 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007573
7574 /* 7.b */
7575 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7576 * handover quickly by timing out after the Handover Required message */
7577 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7578 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7579 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7580 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7581
7582 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007583 f_shutdown_helper(ho := true);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007584}
7585
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007586/* OS#3041: Open and close N connections in a normal fashion, and expect no
7587 * BSSMAP Reset just because of that. */
7588testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7589 var default d;
7590 var integer i;
7591 var DchanTuple dt;
7592
7593 f_init();
7594
7595 /* Wait for initial BSSMAP Reset to pass */
7596 f_sleep(4.0);
7597
7598 d := activate(no_bssmap_reset());
7599
7600 /* Setup up a number of connections and RLSD them again from the MSC
7601 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7602 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007603 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007604 /* Since we're doing a lot of runs, give each one a fresh
7605 * T_guard from the top. */
7606 T_guard.start;
7607
7608 /* Setup a BSSAP connection and clear it right away. This is
7609 * the MSC telling the BSC about a planned release, it's not an
7610 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007611 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007612
7613 /* MSC disconnects (RLSD). */
7614 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7615 }
7616
7617 /* In the buggy behavior, a timeout of 2 seconds happens between above
7618 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7619 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7620 f_sleep(4.0);
7621
7622 deactivate(d);
7623 f_shutdown_helper();
7624}
Harald Welte552620d2017-12-16 23:21:36 +01007625
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007626/* OS#3041: Open and close N connections in a normal fashion, and expect no
7627 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7628 * the MSC. */
7629testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7630 var default d;
7631 var integer i;
7632 var DchanTuple dt;
7633 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007634 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7635 var BssmapCause cause := enum2int(cause_val);
7636
7637 f_init();
7638
7639 /* Wait for initial BSSMAP Reset to pass */
7640 f_sleep(4.0);
7641
7642 d := activate(no_bssmap_reset());
7643
7644 /* Setup up a number of connections and RLSD them again from the MSC
7645 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7646 * Let's do it some more times for good measure. */
7647 for (i := 0; i < 8; i := i+1) {
7648 /* Since we're doing a lot of runs, give each one a fresh
7649 * T_guard from the top. */
7650 T_guard.start;
7651
7652 /* Setup a BSSAP connection and clear it right away. This is
7653 * the MSC telling the BSC about a planned release, it's not an
7654 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007655 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007656
7657 /* Instruct BSC to clear channel */
7658 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7659
7660 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007661 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007662 }
7663
7664 /* In the buggy behavior, a timeout of 2 seconds happens between above
7665 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7666 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7667 f_sleep(4.0);
7668
7669 deactivate(d);
7670 f_shutdown_helper();
7671}
7672
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007673/* OS#3041: Open and close N connections in a normal fashion, and expect no
7674 * BSSMAP Reset just because of that. Close connections from the MS side with a
7675 * Release Ind on RSL. */
7676testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7677 var default d;
7678 var integer i;
7679 var DchanTuple dt;
7680 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007681 var integer j;
7682
7683 f_init();
7684
7685 /* Wait for initial BSSMAP Reset to pass */
7686 f_sleep(4.0);
7687
7688 d := activate(no_bssmap_reset());
7689
7690 /* Setup up a number of connections and RLSD them again from the MSC
7691 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7692 * Let's do it some more times for good measure. */
7693 for (i := 0; i < 8; i := i+1) {
7694 /* Since we're doing a lot of runs, give each one a fresh
7695 * T_guard from the top. */
7696 T_guard.start;
7697
7698 /* Setup a BSSAP connection and clear it right away. This is
7699 * the MSC telling the BSC about a planned release, it's not an
7700 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007701 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007702
7703 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007704 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007705
7706 /* expect Clear Request on MSC side */
7707 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7708
7709 /* Instruct BSC to clear channel */
7710 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7711 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7712
7713 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007714 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007715 }
7716
7717 /* In the buggy behavior, a timeout of 2 seconds happens between above
7718 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7719 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7720 f_sleep(4.0);
7721
7722 deactivate(d);
7723 f_shutdown_helper();
7724}
7725
Harald Welte94e0c342018-04-07 11:33:23 +02007726/***********************************************************************
7727 * IPA style dynamic PDCH
7728 ***********************************************************************/
7729
7730private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7731 template (omit) RSL_Cause nack := omit)
7732runs on test_CT {
7733 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7734 var RSL_Message rsl_unused;
7735 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7736 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7737 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007738 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007739 if (istemplatekind(nack, "omit")) {
7740 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007741 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007742 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007743 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007744 }
7745}
7746
7747private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7748 template (omit) RSL_Cause nack := omit)
7749runs on test_CT {
7750 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7751 var RSL_Message rsl_unused;
7752 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7753 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7754 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007755 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_DEACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007756 if (istemplatekind(nack, "omit")) {
7757 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007758 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007759 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007760 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007761 }
7762}
7763
7764private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7765runs on test_CT return charstring {
7766 var charstring cmd, resp;
7767 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007768 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007769}
7770
7771private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7772 template charstring exp)
7773runs on test_CT {
7774 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7775 if (not match(mode, exp)) {
7776 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007777 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007778 }
7779}
7780
7781private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7782runs on test_CT {
7783 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7784 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7785 f_vty_transceive(BSCVTY, "end");
7786}
7787
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007788
7789private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7790 var integer i;
7791 for (i := 0; i < 8; i := i + 1) {
7792 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7793 }
7794}
7795
Harald Welte94e0c342018-04-07 11:33:23 +02007796private const charstring TCHF_MODE := "TCH/F mode";
7797private const charstring TCHH_MODE := "TCH/H mode";
7798private const charstring PDCH_MODE := "PDCH mode";
7799private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007800private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007801
7802/* Test IPA PDCH activation / deactivation triggered by VTY */
7803testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7804 var RSL_Message rsl_unused;
7805
7806 /* change Timeslot 6 before f_init() starts RSL */
7807 f_init_vty();
7808 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7809 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7810
7811 f_init(1, false);
7812 f_sleep(1.0);
7813
7814 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7815
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007816 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007817 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7818 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007819 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7820 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007821 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007822 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007823 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7824
7825 /* De-activate it via VTY */
7826 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7827 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007828 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007829 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7830
7831 /* re-activate it via VTY */
7832 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7833 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007834 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007835 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7836
7837 /* and finally de-activate it again */
7838 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7839 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007840 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007841 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7842
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007843 /* clean up config */
7844 f_ts_set_chcomb(0, 0, 6, "PDCH");
7845
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007846 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007847}
7848
7849/* Test IPA PDCH activation NACK */
7850testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7851 var RSL_Message rsl_unused;
7852
7853 /* change Timeslot 6 before f_init() starts RSL */
7854 f_init_vty();
7855 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7856 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7857
7858 f_init(1, false);
7859 f_sleep(1.0);
7860
7861 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7862
7863 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7864 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007865 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7866 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007867 f_sleep(1.0);
7868 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7869
7870 /* De-activate it via VTY */
7871 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7872 f_sleep(1.0);
7873 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7874
7875 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7876 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7877 f_sleep(1.0);
7878 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7879
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007880 /* clean up config */
7881 f_ts_set_chcomb(0, 0, 6, "PDCH");
7882
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007883 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007884}
7885
7886
7887/***********************************************************************
7888 * Osmocom style dynamic PDCH
7889 ***********************************************************************/
7890
7891private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7892 template (omit) RSL_Cause nack := omit)
7893runs on test_CT {
7894 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7895 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007896 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007897 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7898 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007899 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT(chan_nr, ?));
Harald Welte94e0c342018-04-07 11:33:23 +02007900 if (istemplatekind(nack, "omit")) {
7901 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007902 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007903 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007904 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007905 }
7906}
7907
7908private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7909 template (omit) RSL_Cause nack := omit)
7910runs on test_CT {
7911 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7912 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007913 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007914 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7915 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007916 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007917 if (istemplatekind(nack, "omit")) {
7918 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007919 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007920 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007921 //f_ipa_tx(ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007922 }
7923}
7924
7925/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7926testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7927 var RSL_Message rsl_unused;
7928
7929 /* change Timeslot 6 before f_init() starts RSL */
7930 f_init_vty();
7931 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7932 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7933
7934 f_init(1, false);
7935 f_sleep(1.0);
7936
7937 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7938
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007939 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007940 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7941 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007942 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007943
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007944 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007945 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007946 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 +02007947 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7948
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007949 /* clean up config */
7950 f_ts_set_chcomb(0, 0, 6, "PDCH");
7951
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007952 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007953}
7954
7955/* Test Osmocom dyn PDCH activation NACK behavior */
7956testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7957 var RSL_Message rsl_unused;
7958
7959 /* change Timeslot 6 before f_init() starts RSL */
7960 f_init_vty();
7961 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7962 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7963
7964 f_init(1, false);
7965 f_sleep(1.0);
7966
7967 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7968
7969 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7970 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007971 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007972
7973 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007974 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte94e0c342018-04-07 11:33:23 +02007975 f_sleep(1.0);
7976 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7977
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007978 /* clean up config */
7979 f_ts_set_chcomb(0, 0, 6, "PDCH");
7980
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007981 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007982}
7983
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007984/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7985testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7986 var RSL_Message rsl_unused, rsl_msg;
7987 var DchanTuple dt;
7988 var BSSAP_N_CONNECT_ind rx_c_ind;
7989
7990 /* change Timeslot 6 before f_init() starts RSL */
7991 f_init_vty();
7992 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7993 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7994
7995 f_init(1, false);
7996 f_sleep(1.0);
7997
7998 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7999
8000 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8001 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8002 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008003 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008004
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008005 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008006 f_sleep(1.0);
8007 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8008 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8009
8010 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8011 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008012 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008013 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008014 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008015 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008016 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008017 }
8018
8019 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008020 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8021 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8022 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008023
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008024 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008025 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008026 dt.idx := {0, 0};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008027
8028 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008029 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8030 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008031 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
8032
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008033 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008034 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8035 dt.sccp_conn_id := rx_c_ind.connectionId;
8036 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8037
8038 /* Instruct BSC to clear channel */
8039 var BssmapCause cause := 0;
8040 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008041 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008042
8043 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008044 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8045 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008046 f_sleep(1.0);
8047 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8048
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008049 /* Clean up SDCCH lchans */
8050 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
8051 f_perform_clear_test_ct(sdcch_cleanup[i]);
8052 }
8053
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008054 /* clean up config */
8055 f_ts_set_chcomb(0, 0, 6, "PDCH");
8056
8057 f_shutdown_helper();
8058}
8059
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008060/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
8061testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
8062 var ASP_RSL_Unitdata rsl_ud;
8063 var integer i;
8064 var integer chreq_total, chreq_nochan;
8065
8066 f_init_vty();
8067 for (i := 1; i < 8; i := i + 1) {
8068 if (i == 2) {
8069 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8070 } else {
8071 f_ts_set_chcomb(0, 0, i, "PDCH");
8072 }
8073 }
8074 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8075
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008076 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008077
8078 /* The dyn TS want to activate PDCH mode, ACK that. */
8079 var RslChannelNr chan_nr;
8080 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008081 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
8082 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008083
8084 f_sleep(1.0);
8085
8086 /* Exhaust all dedicated SDCCH lchans.
8087 /* GSM 44.018 Table 9.1.8.2:
8088 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
8089 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008090 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008091 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008092 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008093 }
8094
8095 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008096 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008097 /* Also occupy the seven other SDCCH of the dyn TS */
8098 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008099 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008100 }
8101
8102 /* Clean up SDCCH lchans */
8103 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8104 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008105 }
8106
8107 /* clean up config */
8108 f_ts_reset_chcomb(0);
8109
8110 f_shutdown_helper();
8111}
8112
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008113/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
8114 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
8115 it as TCH directly instead. SYS#5309. */
8116testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
8117 var RSL_Message rsl_unused, rsl_msg;
8118 var DchanTuple dt;
8119 var BSSAP_N_CONNECT_ind rx_c_ind;
8120 var integer i;
8121
8122 /* change Timeslot 6 before f_init() starts RSL */
8123 f_init_vty();
8124 for (i := 1; i < 8; i := i + 1) {
8125 if (i == 6) {
8126 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8127 } else {
8128 f_ts_set_chcomb(0, 0, i, "PDCH");
8129 }
8130 }
8131 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8132
8133 f_init(1, false);
8134 f_sleep(1.0);
8135
8136 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8137
8138 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8139 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8140 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008141 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008142
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008143 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008144 f_sleep(1.0);
8145 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8146 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8147
8148 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8149 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008150 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008151 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008152 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008153 dt := f_est_dchan(ra, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008154 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008155 }
8156
8157 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008158 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
8159 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8160 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008161
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008162 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008163 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008164 dt.idx := {0, 0};
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008165
8166 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008167 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8168 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008169 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
8170
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008171 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008172 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8173 dt.sccp_conn_id := rx_c_ind.connectionId;
8174 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8175
8176 /* Instruct BSC to clear channel */
8177 var BssmapCause cause := 0;
8178 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008179 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008180
8181 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008182 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8183 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008184 f_sleep(1.0);
8185 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8186
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008187 /* Clean up SDCCH lchans */
8188 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8189 f_perform_clear_test_ct(chan_cleanup[i]);
8190 }
8191
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008192 /* clean up config */
8193 f_ts_reset_chcomb(0);
8194 /* TODO: clean up other channels? */
8195
8196 f_shutdown_helper();
8197}
8198
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008199/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
8200testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
8201 var RSL_Message rsl_unused, rsl_msg;
8202 var DchanTuple dt;
8203 var BSSAP_N_CONNECT_ind rx_c_ind;
8204 var GsmRrMessage rr;
8205
8206 /* change Timeslot 6 before f_init() starts RSL */
8207 f_init_vty();
8208 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8209 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8210
8211 f_init(1, false);
8212 f_sleep(1.0);
8213
8214 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8215
8216 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8217 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8218 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008219 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008220
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008221 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008222 f_sleep(1.0);
8223 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8224 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8225
8226 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8227 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008228 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008229 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008230 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008231 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008232 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008233 }
8234
8235 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008236 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8237 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8238 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008239
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008240 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008241 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008242 dt.idx := {0, 0};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008243
8244 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008245 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8246 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008247 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8248 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8249 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8250 }
8251
8252 /* FIXME? Currently the TS stays in state BORKEN: */
8253
8254 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008255 /* rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8256 * f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008257 * f_sleep(1.0);
8258 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8259 */
8260
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008261 /* Clean up SDCCH lchans */
8262 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8263 f_perform_clear_test_ct(chan_cleanup[i]);
8264 }
8265
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008266 /* clean up config */
8267 f_ts_set_chcomb(0, 0, 6, "PDCH");
8268
8269 f_shutdown_helper();
8270}
8271
Stefan Sperling0796a822018-10-05 13:01:39 +02008272testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008273 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008274 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8275 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8276 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008277 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008278}
8279
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008280testcase TC_chopped_ipa_payload() runs on test_CT {
8281 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8282 /* TODO: mp_bsc_ctrl_port does not work yet */};
8283 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8284 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8285 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008286 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008287}
8288
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008289/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8290 the BTS does autonomous MS power control loop */
8291testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8292 var MSC_ConnHdlr vc_conn;
8293 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8294 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8295 pars.exp_ms_power_params := true;
8296
8297 f_init(1, true);
8298 f_sleep(1.0);
8299 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8300 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008301 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008302}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008303
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008304/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8305testcase TC_c0_power_red_mode() runs on test_CT {
8306 f_init(1);
8307
8308 for (var integer red := 6; red >= 0; red := red - 2) {
8309 /* Configure BCCH carrier power reduction mode via the VTY */
8310 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8311
8312 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008313 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008314 chan_nr := t_RslChanNr_BCCH(0),
8315 bs_power := tr_RSL_IE_BS_Power(red / 2));
8316 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008317 var RSL_Message unused := f_exp_ipa_rx(tr_rsl_pdu);
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008318
8319 /* Additionally verify the applied value over the CTRL interface */
8320 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8321 if (cred != int2str(red)) {
8322 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8323 cred, " (expected ", red, ")");
8324 }
8325 }
8326
8327 f_shutdown_helper();
8328}
8329
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008330/***********************************************************************
8331 * MSC Pooling
8332 ***********************************************************************/
8333
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008334template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008335 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 +02008336
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008337private 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 +02008338runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008339 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008340 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008341 f_logp(BSCVTY, "Got RSL RR Release");
8342 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008343 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008344 f_logp(BSCVTY, "Got RSL Deact SACCH");
8345 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008346 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008347 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008348 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8349 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008350 break;
8351 }
8352 }
8353}
8354
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008355private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8356 var MgcpCommand mgcp_cmd;
8357 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8358 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8359 repeat;
8360 }
8361}
8362
8363private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8364 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8365 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8366 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8367 repeat;
8368 }
8369}
8370
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008371friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8372 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008373runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008374 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8375 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008376 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008377 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8378 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008379 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008380 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008381 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008382 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008383 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008384 }
8385 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008386 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008387 /* Also drop the SCCP connection */
8388 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8389 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008390 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008391 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008392 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8393 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008394 }
8395 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008396 deactivate(ack_dlcx);
8397 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008398}
8399
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008400friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8401runs on MSC_ConnHdlr {
8402 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8403 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8404 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8405 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8406 interleave {
8407 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8408 f_logp(BSCVTY, "Got RSL Deact SACCH");
8409 }
8410 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8411 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8412 /* Also drop the SCCP connection */
8413 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8414 }
8415 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8416 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8417 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8418 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8419 }
8420 }
8421 deactivate(ack_dlcx);
8422 deactivate(ack_rel_req);
8423}
8424
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008425friend function f_perform_clear_no_lchan()
8426runs on MSC_ConnHdlr {
8427 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8428 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8429 BSSAP.receive(tr_BSSMAP_ClearComplete);
8430 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8431 /* Also drop the SCCP connection */
8432 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8433}
8434
Vadim Yanitskiy65d879d2022-06-23 18:15:39 +07008435friend function f_perform_clear_test_ct(DchanTuple dt)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008436 runs on test_CT
8437{
8438 /* Instruct BSC to clear channel */
8439 var BssmapCause cause := 0;
8440 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008441 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008442}
8443
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008444private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8445 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008446runs on MSC_ConnHdlr {
8447 timer T := 10.0;
8448 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8449
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008450 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008451 f_create_bssmap_exp(l3_enc);
8452
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008453 /* RSL_Emulation.f_chan_est() on rsl_pt:
8454 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008455 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8456 */
8457 var RSL_Message rx_rsl;
8458 var GsmRrMessage rr;
8459
8460 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008461 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008462 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008463 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008464 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8465 */
8466 timer Tt := 10.0;
8467
8468 /* request a channel to be established */
8469 Tt.start;
8470 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008471 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008472 Tt.stop;
8473 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008474 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008475 setverdict(fail, "Unexpected RSL message on DCHAN");
8476 mtc.stop;
8477 }
8478 [] Tt.timeout {
8479 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8480 mtc.stop;
8481 }
8482 }
8483 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8484 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008485 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008486
8487
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008488 if (expect_bssmap_l3) {
8489 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8490 var template PDU_BSSAP exp_l3_compl;
8491 exp_l3_compl := tr_BSSMAP_ComplL3()
8492 if (g_pars.aoip == false) {
8493 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8494 } else {
8495 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8496 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008497
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008498 var PDU_BSSAP bssap;
8499 T.start;
8500 alt {
8501 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8502 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8503 log("rx exp_l3_compl = ", bssap);
8504 }
8505 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8506 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8507 }
8508 [] T.timeout {
8509 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8510 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008511 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008512
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008513 /* start ciphering, if requested */
8514 if (ispresent(g_pars.encr)) {
8515 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008516 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008517 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008518 }
8519
8520 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008521 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008522 }
8523 setverdict(pass);
8524 f_sleep(1.0);
8525}
8526
8527private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8528 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8529 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008530 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008531 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008532 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008533 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008534 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008535 }
8536}
8537
8538/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8539private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8540 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008541 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8542 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8543 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8544 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 +02008545}
8546testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8547
8548 f_init(1, true);
8549 f_sleep(1.0);
8550 var MSC_ConnHdlr vc_conn;
8551 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008552
8553 f_ctrs_msc_init();
8554
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008555 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8556 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008557
8558 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008559 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008560}
8561
8562/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8563/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8564 * just as well using only RSL. */
8565testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8566
8567 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8568 f_sleep(1.0);
8569
8570 /* Control which MSC gets chosen next by the round-robin, otherwise
8571 * would be randomly affected by which other tests ran before this. */
8572 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8573
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008574 f_ctrs_msc_init();
8575
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008576 var MSC_ConnHdlr vc_conn1;
8577 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8578 pars1.mscpool.rsl_idx := 0;
8579 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8580 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8581 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008582 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008583
8584 var MSC_ConnHdlr vc_conn2;
8585 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8586 pars2.mscpool.rsl_idx := 1;
8587 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8588 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8589 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008590 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008591
8592 /* Test round-robin wrap to the first MSC */
8593 var MSC_ConnHdlr vc_conn3;
8594 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8595 pars3.mscpool.rsl_idx := 2;
8596 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8597 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8598 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008599 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008600 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008601}
8602
8603/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8604 * (configured in osmo-bsc.cfg). */
8605/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8606 * just as well using only RSL. */
8607testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8608
8609 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8610 f_sleep(1.0);
8611
8612 /* Control which MSC gets chosen next by the round-robin, otherwise
8613 * would be randomly affected by which other tests ran before this. */
8614 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8615
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008616 f_ctrs_msc_init();
8617
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008618 var MSC_ConnHdlr vc_conn1;
8619 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8620 pars1.mscpool.rsl_idx := 0;
8621 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8622 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8623 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008624 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008625
8626 var MSC_ConnHdlr vc_conn2;
8627 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8628 pars2.mscpool.rsl_idx := 1;
8629 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8630 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8631 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008632 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008633
8634 /* Test round-robin wrap to the first MSC */
8635 var MSC_ConnHdlr vc_conn3;
8636 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8637 pars3.mscpool.rsl_idx := 2;
8638 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8639 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8640 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008641 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008642 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008643}
8644
8645/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8646 * (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
8647 * NULL-NRI setting is stronger than that. */
8648/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8649 * just as well using only RSL. */
8650testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8651
8652 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8653 f_sleep(1.0);
8654
8655 /* Control which MSC gets chosen next by the round-robin, otherwise
8656 * would be randomly affected by which other tests ran before this. */
8657 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8658
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008659 f_ctrs_msc_init();
8660
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008661 var MSC_ConnHdlr vc_conn1;
8662 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8663 pars1.mscpool.rsl_idx := 0;
8664 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8665 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8666 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008667 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008668
8669 var MSC_ConnHdlr vc_conn2;
8670 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8671 pars2.mscpool.rsl_idx := 1;
8672 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8673 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8674 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008675 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008676
8677 /* Test round-robin wrap to the first MSC */
8678 var MSC_ConnHdlr vc_conn3;
8679 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8680 pars3.mscpool.rsl_idx := 2;
8681 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8682 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8683 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008684 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008685 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008686}
8687
8688/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8689 * assigned to any MSC (configured in osmo-bsc.cfg). */
8690/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8691 * just as well using only RSL. */
8692testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8693
8694 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8695 f_sleep(1.0);
8696
8697 /* Control which MSC gets chosen next by the round-robin, otherwise
8698 * would be randomly affected by which other tests ran before this. */
8699 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8700
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008701 f_ctrs_msc_init();
8702
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008703 var MSC_ConnHdlr vc_conn1;
8704 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8705 pars1.mscpool.rsl_idx := 0;
8706 /* An NRI that is not assigned to any MSC */
8707 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8708 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8709 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008710 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008711
8712 var MSC_ConnHdlr vc_conn2;
8713 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8714 pars2.mscpool.rsl_idx := 1;
8715 /* An NRI that is not assigned to any MSC */
8716 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8717 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8718 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008719 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008720
8721 /* Test round-robin wrap to the first MSC */
8722 var MSC_ConnHdlr vc_conn3;
8723 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8724 pars3.mscpool.rsl_idx := 2;
8725 /* An NRI that is not assigned to any MSC */
8726 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8727 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8728 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008729 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008730 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008731}
8732
8733/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8734 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8735/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8736 * just as well using only RSL. */
8737testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8738
8739 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8740 f_sleep(1.0);
8741
8742 /* Control which MSC gets chosen next by the round-robin, otherwise
8743 * would be randomly affected by which other tests ran before this. */
8744 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8745
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008746 f_ctrs_msc_init();
8747
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008748 var MSC_ConnHdlr vc_conn1;
8749 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8750 pars1.mscpool.rsl_idx := 0;
8751 /* An NRI that is assigned to an unconnected MSC */
8752 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8753 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8754 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008755 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8756 f_ctrs_msc_add(0, "mscpool:subscr:new");
8757 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008758
8759 var MSC_ConnHdlr vc_conn2;
8760 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8761 pars2.mscpool.rsl_idx := 1;
8762 /* An NRI that is assigned to an unconnected MSC */
8763 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8764 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8765 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008766 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8767 f_ctrs_msc_add(1, "mscpool:subscr:new");
8768 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008769
8770 /* Test round-robin wrap to the first MSC */
8771 var MSC_ConnHdlr vc_conn3;
8772 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8773 pars3.mscpool.rsl_idx := 2;
8774 /* An NRI that is assigned to an unconnected MSC */
8775 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8776 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8777 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008778 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8779 f_ctrs_msc_add(0, "mscpool:subscr:new");
8780 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008781 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008782}
8783
8784/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8785 * osmo-bsc.cfg). */
8786/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8787 * just as well using only RSL. */
8788testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8789
8790 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8791 f_sleep(1.0);
8792
8793 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8794 * this is not using round-robin. */
8795 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8796
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008797 f_ctrs_msc_init();
8798
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008799 var MSC_ConnHdlr vc_conn1;
8800 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8801 pars1.mscpool.rsl_idx := 0;
8802 /* An NRI of the second MSC's range (256-511) */
8803 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8804 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8805 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008806 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008807
8808 var MSC_ConnHdlr vc_conn2;
8809 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8810 pars2.mscpool.rsl_idx := 1;
8811 /* An NRI of the second MSC's range (256-511) */
8812 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8813 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8814 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008815 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008816
8817 var MSC_ConnHdlr vc_conn3;
8818 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8819 pars3.mscpool.rsl_idx := 2;
8820 /* An NRI of the second MSC's range (256-511) */
8821 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8822 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8823 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008824 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008825 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008826}
8827
8828/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8829 * while a round-robin remains unaffected by that. */
8830/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8831 * just as well using only RSL. */
8832testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8833
8834 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8835 f_sleep(1.0);
8836
8837 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8838 * this is not using round-robin. */
8839 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8840
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008841 f_ctrs_msc_init();
8842
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008843 var MSC_ConnHdlr vc_conn1;
8844 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8845 pars1.mscpool.rsl_idx := 0;
8846 /* An NRI of the third MSC's range (512-767) */
8847 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8848 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8849 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008850 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008851
8852 var MSC_ConnHdlr vc_conn2;
8853 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8854 pars2.mscpool.rsl_idx := 1;
8855 /* An NRI of the third MSC's range (512-767) */
8856 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8857 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8858 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008859 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008860
8861 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8862 var MSC_ConnHdlr vc_conn3;
8863 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8864 pars3.mscpool.rsl_idx := 2;
8865 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8866 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8867 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008868 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008869 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008870}
8871
8872/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8873/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8874 * just as well using only RSL. */
8875testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8876
8877 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8878 f_sleep(1.0);
8879
8880 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8881 * instead, and hits msc 0. */
8882 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8883
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008884 f_ctrs_msc_init();
8885
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008886 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8887 var MSC_ConnHdlr vc_conn1;
8888 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8889 pars1.mscpool.rsl_idx := 0;
8890 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8891 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8892 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008893 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008894
8895 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8896 var MSC_ConnHdlr vc_conn2;
8897 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8898 pars2.mscpool.rsl_idx := 1;
8899 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8900 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8901 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008902 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008903 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008904}
8905
8906/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8907 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8908private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8909 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8910 //cid_list := { cIl_allInBSS := ''O };
8911 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8912 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8913 var BSSAP_N_UNITDATA_req paging;
8914 var hexstring imsi := '001010000000123'H;
8915
8916 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8917
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008918 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008919 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8920 BSSAP.send(paging);
8921
8922 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8923 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8924 * channel number is picked here. */
8925 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8926 f_rslem_register(0, new_chan_nr);
8927 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8928 f_rslem_unregister(0, new_chan_nr);
8929
8930 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8931 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008932 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008933 f_sleep(1.0);
8934}
8935testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8936 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8937 f_sleep(1.0);
8938
8939 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8940 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8941 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8942
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008943 f_ctrs_msc_init();
8944
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008945 var MSC_ConnHdlr vc_conn1;
8946 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8947 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008948 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8949 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008950 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8951 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008952 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008953 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008954}
8955
8956/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8957 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8958private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8959 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8960 //cid_list := { cIl_allInBSS := ''O };
8961 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8962 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8963 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008964 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008965 var BSSAP_N_UNITDATA_req paging;
8966
8967 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8968
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008969 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008970 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8971 BSSAP.send(paging);
8972
8973 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8974 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8975 * channel number is picked here. */
8976 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8977 f_rslem_register(0, new_chan_nr);
8978 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8979 f_rslem_unregister(0, new_chan_nr);
8980
8981 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8982 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8983 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008984 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 +02008985 f_sleep(1.0);
8986}
8987testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8988 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8989 f_sleep(1.0);
8990
8991 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8992 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8993 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8994
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008995 f_ctrs_msc_init();
8996
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008997 var MSC_ConnHdlr vc_conn1;
8998 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8999 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02009000 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
9001 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009002 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
9003 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009004 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009005 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009006}
9007
9008/* For round-robin, skip an MSC that has 'no allow-attach' set. */
9009/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
9010 * just as well using only RSL. */
9011testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
9012
9013 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9014 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009015 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9016 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009017
9018 /* Control which MSC gets chosen next by the round-robin, otherwise
9019 * would be randomly affected by which other tests ran before this. */
9020 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9021
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009022 f_ctrs_msc_init();
9023
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009024 var MSC_ConnHdlr vc_conn1;
9025 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9026 pars1.mscpool.rsl_idx := 0;
9027 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
9028 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9029 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009030 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009031
9032 var MSC_ConnHdlr vc_conn2;
9033 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
9034 pars2.mscpool.rsl_idx := 1;
9035 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9036 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9037 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009038 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009039
9040 var MSC_ConnHdlr vc_conn3;
9041 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
9042 pars3.mscpool.rsl_idx := 2;
9043 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
9044 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9045 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009046 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009047 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009048}
9049
9050/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
9051 * TMSI NRI. */
9052testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
9053
9054 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9055 f_sleep(1.0);
9056
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009057 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9058 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
9059
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009060 /* Control which MSC gets chosen next by the round-robin, otherwise
9061 * would be randomly affected by which other tests ran before this. */
9062 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9063
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009064 f_ctrs_msc_init();
9065
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009066 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
9067 var MSC_ConnHdlr vc_conn1;
9068 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
9069 pars1.mscpool.rsl_idx := 0;
9070 /* An NRI of the second MSC's range (256-511) */
9071 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
9072 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9073 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009074 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009075
9076 var MSC_ConnHdlr vc_conn2;
9077 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
9078 pars2.mscpool.rsl_idx := 1;
9079 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9080 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9081 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009082 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009083
9084 var MSC_ConnHdlr vc_conn3;
9085 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
9086 pars3.mscpool.rsl_idx := 2;
9087 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
9088 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9089 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009090 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009091 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009092}
9093
Philipp Maier783681c2020-07-16 16:47:06 +02009094/* Allow/Deny emergency calls globally via VTY */
9095private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
9096 f_vty_enter_cfg_msc(BSCVTY, 0);
9097 if (allow) {
9098 f_vty_transceive(BSCVTY, "allow-emergency allow");
9099 } else {
9100 f_vty_transceive(BSCVTY, "allow-emergency deny");
9101 }
9102 f_vty_transceive(BSCVTY, "exit");
9103 f_vty_transceive(BSCVTY, "exit");
9104}
9105
9106/* Allow/Deny emergency calls per BTS via VTY */
9107private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
9108 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9109 if (allow) {
9110 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
9111 } else {
9112 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
9113 }
9114 f_vty_transceive(BSCVTY, "exit");
9115 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00009116 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02009117}
9118
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02009119/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
9120private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
9121 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9122 if (allow) {
9123 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
9124 } else {
9125 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
9126 }
9127 f_vty_transceive(BSCVTY, "exit");
9128 f_vty_transceive(BSCVTY, "exit");
9129 f_vty_transceive(BSCVTY, "exit");
9130}
9131
Pau Espin Pedrol14475352021-07-22 15:48:16 +02009132/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
9133private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
9134 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9135 if (allow) {
9136 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
9137 } else {
9138 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
9139 }
9140 f_vty_transceive(BSCVTY, "exit");
9141 f_vty_transceive(BSCVTY, "exit");
9142 f_vty_transceive(BSCVTY, "exit");
9143}
9144
Pau Espin Pedrol35609792023-01-03 16:56:59 +01009145/* Begin assignment procedure and send an EMERGENCY SETUP (RR) */
Philipp Maier783681c2020-07-16 16:47:06 +02009146private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
9147 var PDU_ML3_MS_NW emerg_setup;
9148 var octetstring emerg_setup_enc;
9149 var RSL_Message emerg_setup_data_ind;
9150
9151 f_establish_fully(omit, omit);
9152
9153 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
9154 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
9155 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
9156
9157 RSL.send(emerg_setup_data_ind);
9158}
9159
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009160/* expect EmergencySetup on BSSAP after calling f_assignment_emerg_setup() */
9161private function f_assignment_emerg_setup_exp_bssap()
9162runs on MSC_ConnHdlr {
Philipp Maier783681c2020-07-16 16:47:06 +02009163 var PDU_BSSAP emerg_setup_data_ind_bssap;
9164 var PDU_ML3_MS_NW emerg_setup;
9165 timer T := 3.0;
9166
Philipp Maier783681c2020-07-16 16:47:06 +02009167 T.start;
9168 alt {
9169 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
9170 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
9171 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
9172 setverdict(fail, "no emergency setup");
9173 }
9174 }
9175 [] BSSAP.receive {
9176 setverdict(fail, "unexpected BSSAP message!");
9177 }
9178 [] T.timeout {
9179 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
9180 }
9181 }
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009182}
9183
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009184private function f_assignment_emerg_setup_voice()
9185runs on MSC_ConnHdlr {
9186 /* Go on with voice call assignment */
9187 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9188 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9189
9190 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
9191 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
9192 * seems a good idea to see how osmo-bsc reacts to this. */
9193 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
9194 elementIdentifier := '0B'O, /* overwritten */
9195 lengthIndicator := 0, /* overwritten */
9196 speechOrDataIndicator := '0001'B, /* speech */
9197 spare1_4 := '0000'B,
9198 channelRateAndType := ChRate_TCHForH_Fpref,
9199 speechId_DataIndicator := 'c2918105'O
9200 };
9201 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
9202 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
9203
9204 f_rslem_dchan_queue_enable();
9205
9206 var ExpectCriteria mgcpcrit := {
9207 connid := omit,
9208 endpoint := omit,
9209 transid := omit
9210 };
9211 f_create_mgcp_expect(mgcpcrit);
9212
9213 BSSAP.send(ass_cmd);
9214
9215 var AssignmentState st := valueof(ts_AssignmentStateInit);
9216 st.voice_call := true;
9217 st.is_assignment := false;
9218 alt {
9219 [] as_modify(st);
9220 [] as_Media();
9221 [st.modify_done] BSSAP.receive(exp_compl) {
9222 setverdict(pass);
9223 }
9224 }
9225
9226 /* Voice call carries on ... */
9227 f_sleep(2.0);
9228}
9229
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009230/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
9231 * CALLS are permitted by the BSC config. */
9232private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
9233
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009234 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
9235 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
9236 * another lchan. */
9237 g_pars.ra := f_rnd_ra_emerg();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009238 f_assignment_emerg_setup();
9239 f_assignment_emerg_setup_exp_bssap();
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009240 f_assignment_emerg_setup_voice();
Philipp Maier783681c2020-07-16 16:47:06 +02009241
9242 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009243 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02009244}
9245
9246/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
9247 * forbidden by the BSC config. */
9248private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
9249 var PDU_BSSAP emerg_setup_data_ind_bssap;
9250 timer T := 3.0;
9251
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009252 f_assignment_emerg_setup();
Philipp Maier783681c2020-07-16 16:47:06 +02009253
9254 T.start;
9255 alt {
9256 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9257 setverdict(pass);
9258 }
9259 [] RSL.receive {
9260 setverdict(fail, "unexpected RSL message!");
9261 }
9262 [] T.timeout {
9263 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
9264 }
9265 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009266 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01009267 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02009268}
9269
9270/* EMERGENCY CALL situation #1, allowed globally and by BTS */
9271testcase TC_assignment_emerg_setup_allow() runs on test_CT {
9272 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9273 var MSC_ConnHdlr vc_conn;
9274
9275 f_init(1, true);
9276 f_sleep(1.0);
9277
9278 f_vty_allow_emerg_msc(true);
9279 f_vty_allow_emerg_bts(true, 0);
9280 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9281 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009282 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009283}
9284
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +01009285/* Test MO emergency call using MobileIdentity=IMEI (possible for emergency
9286 * calls from phones without SIM card).
9287 * 3GPP TS 24.008 section 10.5.1.4, OS#5849 */
9288testcase TC_assignment_emerg_setup_allow_imei() runs on test_CT {
9289 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9290 var MSC_ConnHdlr vc_conn;
9291
9292 /* Remove IMSI set by f_gen_test_hdlr_pars(), then IMEI will be used to place the call */
9293 pars.imsi := omit;
9294
9295 f_init(1, true);
9296 f_sleep(1.0);
9297
9298 f_vty_allow_emerg_msc(true);
9299 f_vty_allow_emerg_bts(true, 0);
9300 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9301 vc_conn.done;
9302 f_shutdown_helper();
9303}
9304
Philipp Maier783681c2020-07-16 16:47:06 +02009305/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
9306testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
9307 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9308 var MSC_ConnHdlr vc_conn;
9309
9310 f_init(1, true);
9311 f_sleep(1.0);
9312
9313 f_vty_allow_emerg_msc(false);
9314 f_vty_allow_emerg_bts(true, 0);
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009315 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx): */
9316 pars.ra := f_rnd_ra_emerg();
Philipp Maier783681c2020-07-16 16:47:06 +02009317 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9318 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009319 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009320}
9321
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009322/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS.
9323 * The RACH req (and hence CHAN RQD) indicate other than emergency call.
9324 * Hence BSC only learns about it being an emergency call later during call setup.
9325 * If interested in the ra="emergency call" + deny bts policy case,
9326 * see TC_chan_rqd_emerg_deny.
9327 */
Philipp Maier783681c2020-07-16 16:47:06 +02009328testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9329 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9330 var MSC_ConnHdlr vc_conn;
9331
9332 /* Note: This simulates a spec violation by the MS, correct MS
9333 * implementations would not try to establish an emergency call because
9334 * the system information tells in advance that emergency calls are
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009335 * not allowed */
Philipp Maier783681c2020-07-16 16:47:06 +02009336
9337 f_init(1, true);
9338 f_sleep(1.0);
9339
9340 f_vty_allow_emerg_msc(true);
9341 f_vty_allow_emerg_bts(false, 0);
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009342 /* Note: Here we implicitly leave default g_pars.ra which is different than "emergency call" */
Philipp Maier783681c2020-07-16 16:47:06 +02009343 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9344 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009345 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009346}
9347
Philipp Maier82812002020-08-13 18:48:27 +02009348/* Test what happens when an emergency call arrives while all TCH channels are
9349 * busy, the BSC is expected to terminate one call in favor of the incoming
9350 * emergency call */
9351testcase TC_emerg_premption() runs on test_CT {
9352 var ASP_RSL_Unitdata rsl_ud;
9353 var integer i;
9354 var integer chreq_total, chreq_nochan;
9355 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009356 var octetstring l3_payload := gen_l3_valid_payload();
Philipp Maier82812002020-08-13 18:48:27 +02009357
9358 f_init(1);
9359 f_sleep(1.0);
9360
9361 f_vty_allow_emerg_msc(true);
9362 f_vty_allow_emerg_bts(true, 0);
9363
9364 /* Fill up all channels on the BTS */
9365 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9366 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9367 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009368 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009369 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009370 IPA_RSL[0][0].clear;
Philipp Maier82812002020-08-13 18:48:27 +02009371 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9372 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9373
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009374 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9375 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009376 f_ipa_tx(ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009377
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009378 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9379 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009380 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009381 var integer sccp_conn_id := rx_c_ind.connectionId;
9382 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9383
Philipp Maier82812002020-08-13 18:48:27 +02009384 /* Send Channel request for emegergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009385 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier82812002020-08-13 18:48:27 +02009386
9387 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009388 f_expect_chan_rel(first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009389 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009390
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009391 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9392 var BSSAP_N_DATA_ind rx_clear_req;
9393 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9394 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9395 log("XXX ", rx_clear_req);
9396 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9397 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9398 }
9399
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009400 /* Expect the BSC to send activate/assign the channel for the emergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009401 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009402 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9403 setverdict(fail, "different TCH lchan activated than expected");
9404 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009405 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(first_tch, 33));
9406 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009407
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009408 /* complete the BSSMAP Clear to satisfy the conn leak check */
9409 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9410 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9411 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9412 }
9413
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009414 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009415}
9416
9417/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009418private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009419private type record FHParamsTs {
9420 boolean enabled,
9421 uint6_t hsn,
9422 uint6_t maio,
9423 ArfcnList ma
9424};
9425
9426/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009427private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009428 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009429 FHParamsTs ts[8]
9430};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009431
9432/* Randomly generate the hopping parameters for the given timeslot numbers */
9433private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9434runs on test_CT return FHParamsTrx {
9435 var FHParamsTrx fhp;
9436
Philipp Maier798d8952021-10-19 14:43:19 +02009437 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9438 * fall in the GSM900 band. */
9439 fhp.arfcn.arfcn := f_rnd_int(3);
9440 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009441
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009442 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9443 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009444 fhp.ts[tn].enabled := false;
9445 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009446 continue;
9447 }
9448
9449 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009450 fhp.ts[tn].hsn := f_rnd_int(64);
9451 fhp.ts[tn].maio := f_rnd_int(64);
9452 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009453
9454 /* Random Mobile Allocation (hopping channels) */
9455 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9456 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9457 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009458 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009459 }
9460
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009461 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009462 }
9463
9464 log("f_TC_fh_params_gen(): ", fhp);
9465 return fhp;
9466}
9467
9468/* Make sure that the given Channel Description IE matches the hopping configuration */
9469private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9470{
9471 var template (present) ChannelDescription tr_cd;
9472 var template (present) MaioHsn tr_maio_hsn;
9473 var uint3_t tn := cd.chan_nr.tn;
9474
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009475 if (fhp.ts[tn].enabled) {
9476 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009477 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9478 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009479 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009480 }
9481
9482 if (not match(cd, tr_cd)) {
9483 setverdict(fail, "Channel Description IE does not match: ",
9484 cd, " vs expected ", tr_cd);
9485 }
9486}
9487
9488/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9489private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9490 in MobileAllocationLV ma)
9491{
9492 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9493
9494 if (not match(ma, tr_ma)) {
9495 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9496 tn, "): ", ma, " vs expected: ", tr_ma);
9497 } else {
9498 setverdict(pass);
9499 }
9500}
9501
9502private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9503 in MobileAllocationLV ma)
9504return template MobileAllocationLV {
9505 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009506 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009507 return { len := 0, ma := ''B };
9508 }
9509
9510 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9511 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9512 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009513
9514 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009515 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9516 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9517 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009518 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009519 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009520 }
9521 }
9522
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009523 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009524 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009525
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009526 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009527 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9528 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009529 }
9530
9531 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009532 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009533 if (full_mask[i] != '1'B)
9534 { continue; }
9535
9536 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9537 if (slot_mask[i] == '1'B) {
9538 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009539 } else {
9540 ma_mask := ma_mask & '0'B;
9541 }
9542 }
9543
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009544 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9545 if (full_mask[0] == '1'B) {
9546 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9547 if (slot_mask[0] == '1'B) {
9548 ma_mask := ma_mask & '1'B;
9549 } else {
9550 ma_mask := ma_mask & '0'B;
9551 }
9552 }
9553
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009554 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009555 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009556 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9557
9558 return { len := ma_mask_len, ma := ma_mask };
9559}
9560
Philipp Maier798d8952021-10-19 14:43:19 +02009561/* Configure the appropriate band for a given arfcn, exc */
9562private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9563{
9564 var charstring band;
9565 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9566
9567 select (arfcn_) {
9568 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9569 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9570 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9571 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9572 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9573 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9574 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9575 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9576 case else { return; }
9577 }
9578
9579 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9580 f_vty_transceive(BSCVTY, "band " & band);
9581 f_vty_transceive(BSCVTY, "end");
9582}
9583
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009584/* Configure the hopping parameters in accordance with the given record */
9585private function f_TC_fh_params_set(in FHParamsTrx fhp,
9586 uint8_t bts_nr := 0,
9587 uint8_t trx_nr := 0)
9588runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009589
9590 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9591
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009592 /* Enter the configuration node for the given BTS/TRX numbers */
9593 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9594
Philipp Maier798d8952021-10-19 14:43:19 +02009595 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009596
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009597 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009598 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9599
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009600 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009601 f_vty_transceive(BSCVTY, "hopping enabled 0");
9602 f_vty_transceive(BSCVTY, "exit"); /* go back */
9603 continue;
9604 }
9605
9606 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009607 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9608 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009609
9610 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009611 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9612 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009613 }
9614
9615 f_vty_transceive(BSCVTY, "hopping enabled 1");
9616 f_vty_transceive(BSCVTY, "exit"); /* go back */
9617 }
9618
9619 f_vty_transceive(BSCVTY, "end");
9620}
9621
9622/* Disable frequency hopping on all timeslots */
9623private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9624 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009625 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009626 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009627runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009628
9629 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9630
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009631 /* Enter the configuration node for the given BTS/TRX numbers */
9632 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9633
Philipp Maier798d8952021-10-19 14:43:19 +02009634 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009635
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009636 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009637 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9638
9639 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009640 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9641 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009642 }
9643
9644 f_vty_transceive(BSCVTY, "hopping enabled 0");
9645 f_vty_transceive(BSCVTY, "exit"); /* go back */
9646 }
9647
9648 f_vty_transceive(BSCVTY, "end");
9649 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9650}
9651
9652/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9653 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9654testcase TC_fh_params_chan_activ() runs on test_CT {
9655 var FHParamsTrx fhp := f_TC_fh_params_gen();
9656 var RSL_Message rsl_msg;
9657 var RSL_IE_Body ie;
9658
9659 f_init_vty();
9660
9661 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9662 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9663
9664 f_init(1);
9665
9666 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9667 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009668 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9669 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009670
9671 /* Make sure that Channel Identification IE is present */
9672 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9673 setverdict(fail, "RSL Channel Identification IE is absent");
9674 continue;
9675 }
9676
9677 /* Make sure that hopping parameters (HSN/MAIO) match */
9678 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9679
9680 /* "Mobile Allocation shall be included but empty" - let's check this */
9681 if (ie.chan_ident.ma.v.len != 0) {
9682 setverdict(fail, "Mobile Allocation IE is not empty: ",
9683 ie.chan_ident.ma, ", despite it shall be");
9684 continue;
9685 }
9686 }
9687
9688 /* Disable frequency hopping */
9689 f_TC_fh_params_unset(fhp);
9690
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009691 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009692}
9693
9694/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9695testcase TC_fh_params_imm_ass() runs on test_CT {
9696 var FHParamsTrx fhp := f_TC_fh_params_gen();
9697 var RSL_Message rsl_msg;
9698 var RSL_IE_Body ie;
9699
9700 f_init_vty();
9701
9702 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9703 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9704
9705 f_init(1);
9706
9707 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9708 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009709 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9710 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009711
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009712 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9713 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009714
9715 /* Make sure that Full Immediate Assign Info IE is present */
9716 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9717 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9718 continue;
9719 }
9720
9721 /* Decode the actual Immediate Assignment message */
9722 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9723 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9724 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9725 continue;
9726 }
9727
9728 /* Make sure that hopping parameters (HSN/MAIO) match */
9729 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9730
9731 /* Make sure that the Mobile Allocation IE matches */
9732 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9733 rr_msg.payload.imm_ass.mobile_allocation);
9734 }
9735
9736 /* Disable frequency hopping */
9737 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009738
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009739 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009740}
9741
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009742/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9743testcase TC_fh_params_assignment_cmd() runs on test_CT {
9744 var FHParamsTrx fhp := f_TC_fh_params_gen();
9745 var RSL_Message rsl_msg;
9746 var RSL_IE_Body ie;
9747
9748 f_init_vty();
9749
9750 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9751 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9752
9753 f_init(1);
9754
9755 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02009756 vc_MGCP[0].stop;
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009757
9758 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9759 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9760
9761 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9762 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9763 for (var integer i := 0; i < 3; i := i + 1) {
9764 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009765 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009766
9767 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9768 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009769 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009770
9771 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009772 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9773 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009774
9775 /* Make sure that L3 Information IE is present */
9776 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9777 setverdict(fail, "RSL L3 Information IE is absent");
9778 continue;
9779 }
9780
9781 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9782 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9783 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9784 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9785 continue;
9786 }
9787
9788 /* Make sure that hopping parameters (HSN/MAIO) match */
9789 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9790 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9791
9792 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9793 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009794 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009795 continue;
9796 }
9797
9798 /* Make sure that the Mobile Allocation IE matches (if present) */
9799 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9800 if (chan_desc.h and ma_present) {
9801 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9802 l3_msg.payload.ass_cmd.mobile_allocation.v);
9803 } else if (chan_desc.h and not ma_present) {
9804 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9805 continue;
9806 } else if (not chan_desc.h and ma_present) {
9807 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9808 continue;
9809 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009810
9811 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009812 }
9813
9814 /* Give the IUT some time to release all channels */
9815 f_sleep(3.0);
9816
9817 /* Disable frequency hopping */
9818 f_TC_fh_params_unset(fhp);
9819
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009820 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009821}
9822
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009823/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9824private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9825runs on test_CT {
9826 var RSL_Message rsl_msg;
9827 var RSL_IE_Body ie;
9828 var DchanTuple dt;
9829
9830 /* Establish a dedicated channel, so we can trigger handover */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009831 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009832 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009833
9834 /* Trigger handover from BTS0 to BTS1 */
9835 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9836 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9837
9838 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009839 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx := {1, 0});
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009840
9841 /* ACKnowledge channel activation and expect (RR) Handover Command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009842 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33), idx := {1, 0});
9843 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009844
9845 /* Make sure that L3 Information IE is present */
9846 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9847 setverdict(fail, "RSL L3 Information IE is absent");
9848 return;
9849 }
9850
9851 /* Decode the L3 message and make sure it is (RR) Handover Command */
9852 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9853 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9854 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9855 return;
9856 }
9857
9858 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9859 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9860 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9861 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9862 return;
9863 }
9864
9865 /* Make sure that hopping parameters (HSN/MAIO) match */
9866 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9867
9868 /* Make sure that Cell Channel Description IE is present */
9869 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9870 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9871 return;
9872 }
9873
9874 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9875 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9876 if (ma_present) {
9877 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9878 l3_msg.payload.ho_cmd.mobile_allocation.v);
9879 } else {
9880 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9881 return;
9882 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009883
9884 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009885}
9886testcase TC_fh_params_handover_cmd() runs on test_CT {
9887 var FHParamsTrx fhp := f_TC_fh_params_gen();
9888
9889 f_init_vty();
9890
9891 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9892 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9893
9894 f_vty_transceive(BSCVTY, "timeslot 0");
9895 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9896 f_vty_transceive(BSCVTY, "exit"); /* go back */
9897
9898 f_vty_transceive(BSCVTY, "timeslot 1");
9899 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9900 f_vty_transceive(BSCVTY, "end"); /* we're done */
9901
9902 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9903 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9904
9905 f_init(2);
9906
9907 f_TC_fh_params_handover_cmd(fhp);
9908
9909 /* Disable frequency hopping on BTS1 */
9910 f_TC_fh_params_unset(fhp, 1);
9911
9912 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9913 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9914
9915 f_vty_transceive(BSCVTY, "timeslot 0");
9916 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9917 f_vty_transceive(BSCVTY, "exit"); /* go back */
9918
9919 f_vty_transceive(BSCVTY, "timeslot 1");
9920 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9921 f_vty_transceive(BSCVTY, "end"); /* we're done */
9922
9923 f_shutdown_helper();
9924}
9925
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009926/* Verify the hopping parameters in System Information Type 4 */
9927testcase TC_fh_params_si4_cbch() runs on test_CT {
9928 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9929 var ASP_RSL_Unitdata rx_rsl_ud;
9930 timer T := 5.0;
9931
9932 f_init_vty();
9933
9934 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9935 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9936
9937 f_vty_transceive(BSCVTY, "timeslot 0");
9938 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9939 f_vty_transceive(BSCVTY, "exit"); /* go back */
9940
9941 f_vty_transceive(BSCVTY, "timeslot 1");
9942 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9943 f_vty_transceive(BSCVTY, "end"); /* we're done */
9944
9945 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9946 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9947
9948 f_init(1);
9949
9950 T.start;
9951 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009952 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009953 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9954 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9955
9956 /* Make sure that what we decoded is System Information Type 4 */
9957 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9958 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9959 repeat;
9960 }
9961
9962 /* Make sure that CBCH Channel Description IE is present */
9963 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9964 setverdict(fail, "CBCH Channel Description IE is absent");
9965 break;
9966 }
9967
9968 /* Finally, check the hopping parameters (HSN, MAIO) */
9969 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9970 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9971
9972 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9973 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9974 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9975 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9976 break;
9977 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9978 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9979 si.payload.si4.cbch_mobile_alloc.v);
9980 }
9981 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009982 [] IPA_RSL[0][0].receive { repeat; }
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009983 [] T.timeout {
9984 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9985 }
9986 }
9987
9988 /* Disable frequency hopping */
9989 f_TC_fh_params_unset(fhp);
9990
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009991 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009992 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9993
9994 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009995 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009996 f_vty_transceive(BSCVTY, "exit"); /* go back */
9997
9998 f_vty_transceive(BSCVTY, "timeslot 1");
9999 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
10000 f_vty_transceive(BSCVTY, "end"); /* we're done */
10001
Vadim Yanitskiy21726312020-09-04 01:45:36 +070010002 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010003}
10004
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010005template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
10006 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
10007
10008private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
10009 template (present) BSSLAP_PDU expect_bsslap)
10010{
10011 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
10012 if (not match(bsslap, expect_bsslap)) {
10013 log("EXPECTING BSSLAP: ", expect_bsslap);
10014 log("GOT BSSLAP: ", bsslap);
10015 setverdict(fail, "BSSLAP is not as expected");
10016 mtc.stop;
10017 }
10018 setverdict(pass);
10019}
10020
10021/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
10022const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
10023
10024private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
10025 var PDU_BSSAP_LE rx_bsslap;
10026 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
10027 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
10028}
10029
10030/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10031 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
10032private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
10033 f_sleep(1.0);
10034
10035 f_establish_fully(omit, omit);
10036 f_bssap_le_register_imsi(g_pars.imsi, omit);
10037
10038 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10039 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10040
10041 var PDU_BSSAP_LE plr;
10042 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10043
10044 if (not do_ta_request) {
10045 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
10046 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
10047 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
10048 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
10049 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
10050 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
10051 mtc.stop;
10052 }
10053 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
10054 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
10055 if (not match(bsslap, expect_ta_layer3)) {
10056 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
10057 log("GOT BSSLAP: ", bsslap);
10058 setverdict(fail, "BSSLAP is not as expected");
10059 mtc.stop;
10060 }
10061 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
10062 * has no need to request the TA from the BSC and directly responds. */
10063 } else {
10064 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10065 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10066 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10067 }
10068
10069 /* SMLC got the TA from the BSC, now responds with geo information data. */
10070 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10071 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10072 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10073
10074 /* The LCS was using an active A-interface conn. It should still remain active after this. */
10075 f_mo_l3_transceive();
10076
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010077 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010078
10079 f_sleep(2.0);
10080 setverdict(pass);
10081}
10082
10083/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10084 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
10085private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
10086 f_lcs_loc_req_for_active_ms(false);
10087}
10088testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
10089 var MSC_ConnHdlr vc_conn;
10090 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10091
10092 f_init(1, true);
10093 f_sleep(1.0);
10094 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
10095 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010096 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010097}
10098
10099/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10100 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
10101private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
10102 f_lcs_loc_req_for_active_ms(true);
10103}
10104testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
10105 var MSC_ConnHdlr vc_conn;
10106 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10107
10108 f_init(1, true);
10109 f_sleep(1.0);
10110 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
10111 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010112 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010113}
10114
10115/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
10116 * conn without an active lchan. */
10117private function f_clear_A_conn() runs on MSC_ConnHdlr
10118{
10119 var BssmapCause cause := 0;
10120 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10121 BSSAP.receive(tr_BSSMAP_ClearComplete);
10122 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10123
10124 timer no_more_bssap := 5.0;
10125 no_more_bssap.start;
10126 alt {
10127 [] no_more_bssap.timeout { break; }
10128 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
10129 setverdict(fail, "Expected no more BSSAP after Clear Complete");
10130 mtc.stop;
10131 }
10132 }
10133 setverdict(pass);
10134}
10135
10136/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
10137 * for LCS, for cases where there is only an A conn without an active lchan. */
10138private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
10139{
10140 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
10141
10142 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
10143 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
10144 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
10145 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10146 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10147 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10148
10149 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
10150 f_clear_A_conn();
10151 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10152 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10153}
10154
10155/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10156 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
10157 */
10158private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
10159 f_sleep(1.0);
10160
10161 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10162 f_bssap_le_register_imsi(g_pars.imsi, omit);
10163
10164 /* Register to receive the Paging Command */
10165 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10166 g_chan_nr := new_chan_nr;
10167 f_rslem_register(0, g_chan_nr);
10168
10169 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10170 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10171 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10172 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10173
10174 var PDU_BSSAP_LE plr;
10175 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10176
10177 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10178 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10179
10180 /* OsmoBSC needs to Page */
10181 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
10182 f_logp(BSCVTY, "got Paging Command");
10183
10184 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
10185 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010186 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);
10187 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010188
10189 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
10190
10191 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10192
10193 /* SMLC got the TA from the BSC, now responds with geo information data. */
10194 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10195 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10196
10197 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10198
10199 /* The lchan is gone, the A-interface conn was created for the LCS only.
10200 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
10201 f_verify_active_A_conn_and_clear();
10202
10203 f_sleep(2.0);
10204 setverdict(pass);
10205}
10206testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
10207 var MSC_ConnHdlr vc_conn;
10208 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10209
10210 f_init(1, true);
10211 f_sleep(1.0);
10212
10213 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10214 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10215
10216 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
10217 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010218 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010219}
10220
10221/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
10222 */
10223private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
10224 f_sleep(1.0);
10225
10226 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10227 f_bssap_le_register_imsi(g_pars.imsi, omit);
10228
10229 /* provoke an abort by omitting both IMSI and IMEI */
10230 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10231 valueof(ts_BSSMAP_Perform_Location_Request(omit,
10232 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
10233 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10234
10235 /* BSC tells MSC about failure */
10236 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10237 locationEstimate := omit, positioningData := omit,
10238 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
10239
10240 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10241 f_verify_active_A_conn_and_clear();
10242
10243 f_sleep(2.0);
10244 setverdict(pass);
10245}
10246testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
10247 var MSC_ConnHdlr vc_conn;
10248 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10249
10250 f_init(1, true);
10251 f_sleep(1.0);
10252
10253 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10254 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10255
10256 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
10257 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010258 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010259}
10260
10261/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10262 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
10263private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
10264 f_sleep(1.0);
10265
10266 f_establish_fully(omit, omit);
10267 f_bssap_le_register_imsi(g_pars.imsi, omit);
10268
10269 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10270 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10271
10272 var PDU_BSSAP_LE plr;
10273 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10274
10275 if (do_ta) {
10276 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10277 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10278 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10279 }
10280
10281 /* SMLC fails to respond, BSC runs into timeout */
10282 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
10283 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10284
10285 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10286 locationEstimate := omit, positioningData := omit,
10287 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
10288
10289 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10290 f_verify_active_A_conn_and_clear();
10291
10292 f_sleep(2.0);
10293 setverdict(pass);
10294}
10295
10296/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10297 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
10298private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
10299 f_lcs_loc_req_for_active_ms_le_timeout(false);
10300}
10301
10302testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
10303 var MSC_ConnHdlr vc_conn;
10304 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10305
10306 f_init(1, true);
10307 f_sleep(1.0);
10308 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
10309 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010310 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010311}
10312
10313/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10314 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
10315private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
10316 f_lcs_loc_req_for_active_ms_le_timeout(true);
10317}
10318
10319testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
10320 var MSC_ConnHdlr vc_conn;
10321 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10322
10323 f_init(1, true);
10324 f_sleep(1.0);
10325 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10326 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010327 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010328}
10329
10330/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10331private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10332 f_sleep(1.0);
10333
10334 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10335 f_bssap_le_register_imsi(g_pars.imsi, omit);
10336
10337 /* Register to receive the Paging Command */
10338 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10339 g_chan_nr := new_chan_nr;
10340 f_rslem_register(0, g_chan_nr);
10341
10342 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10343 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10344 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10345 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10346
10347 var PDU_BSSAP_LE plr;
10348 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10349
10350 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10351 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10352
10353 /* OsmoBSC needs to Page */
10354 var PDU_BSSAP_LE rx_bsslap;
10355 alt {
10356 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10357 f_logp(BSCVTY, "got Paging Command");
10358 repeat;
10359 }
10360 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10361 /* MS does not respond to Paging, TA Req runs into timeout. */
10362 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10363 }
10364 }
10365
10366 /* SMLC responds with failure */
10367 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10368 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10369
10370 /* BSC tells MSC about failure */
10371 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10372 locationEstimate := omit, positioningData := omit,
10373 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10374
10375 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10376 f_verify_active_A_conn_and_clear();
10377
10378 f_sleep(2.0);
10379 setverdict(pass);
10380}
10381testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10382 var MSC_ConnHdlr vc_conn;
10383 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10384
10385 f_init(1, true);
10386 f_sleep(1.0);
10387
10388 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10389 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10390
10391 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10392 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010393 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010394}
10395
10396/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10397 * over. */
10398private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10399 f_sleep(1.0);
10400
10401 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10402 f_bssap_le_register_imsi(g_pars.imsi, omit);
10403
10404 /* Register to receive the Paging Command */
10405 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10406 g_chan_nr := new_chan_nr;
10407 f_rslem_register(0, g_chan_nr);
10408
10409 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10410 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10411 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10412 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10413
10414 var PDU_BSSAP_LE plr;
10415 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10416
10417 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10418 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010419 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 +020010420 do_clear := false, expect_bssmap_l3 := true);
10421
10422 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10423 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10424
10425 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10426 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10427
10428 /* SMLC got the TA from the BSC, now responds with geo information data. */
10429 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10430 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10431 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10432
10433 /* The lchan should still exist, it was from a CM Service Request. */
10434 f_mo_l3_transceive();
10435
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010436 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010437
10438 f_sleep(2.0);
10439 setverdict(pass);
10440}
10441testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10442 var MSC_ConnHdlr vc_conn;
10443 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10444
10445 f_init(1, true);
10446 f_sleep(1.0);
10447
10448 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10449 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10450
10451 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10452 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010453 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010454}
10455
10456/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10457 * the new lchan after handover. */
10458private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10459 f_sleep(1.0);
10460
10461 f_establish_fully(omit, omit);
10462 f_bssap_le_register_imsi(g_pars.imsi, omit);
10463
10464 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10465 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10466
10467 var PDU_BSSAP_LE plr;
10468 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10469
10470 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10471 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10472
10473 var HandoverState hs := {
10474 rr_ho_cmpl_seen := false,
10475 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010476 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010477 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010478 };
10479 /* issue hand-over command on VTY */
10480 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10481 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10482 f_rslem_suspend(RSL1_PROC);
10483
10484 /* From the MGW perspective, a handover is is characterized by
10485 * performing one MDCX operation with the MGW. So we expect to see
10486 * one more MDCX during handover. */
10487 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10488
10489 alt {
10490 [] as_handover(hs);
10491 }
10492
10493 var PDU_BSSAP_LE rx_bsslap;
10494
10495 interleave {
10496 /* Expect the BSC to inform the MSC about the handover */
10497 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10498
10499 /* Expect the BSC to inform the SMLC about the handover */
10500 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10501 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10502 }
10503 }
10504
10505 /* SMLC now responds with geo information data. */
10506 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10507 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10508 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10509
10510 /* lchan still active */
10511 f_mo_l3_transceive(RSL1);
10512
10513 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010514 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010515
10516 f_sleep(2.0);
10517 setverdict(pass);
10518}
10519testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10520 var MSC_ConnHdlr vc_conn;
10521 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10522
10523 f_init(2, true);
10524 f_sleep(1.0);
10525 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10526 vc_conn.done;
Oliver Smith39f53072022-10-27 14:44:04 +020010527 f_shutdown_helper(ho := true);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010528}
10529
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010530private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10531{
10532 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10533 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10534 * another lchan. */
Pau Espin Pedrol1809bce2023-01-03 16:54:41 +010010535 g_pars.ra := f_rnd_ra_emerg();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010536 f_assignment_emerg_setup();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +010010537 f_assignment_emerg_setup_exp_bssap();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010538
10539 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10540
10541 /* Do a Location Request in-between the CC call setup */
10542 f_bssap_le_register_imsi(g_pars.imsi, omit);
10543 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10544 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10545 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10546 /* SMLC got the TA from the BSC, now responds with geo information data. */
10547 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10548 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10549 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10550
Pau Espin Pedrol14076d32023-01-03 17:07:59 +010010551 f_assignment_emerg_setup_voice();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010552
10553 setverdict(pass);
10554 f_perform_clear();
10555}
10556
10557testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10558 var MSC_ConnHdlr vc_conn;
10559 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10560
10561 f_init(1, true);
10562 f_sleep(1.0);
10563 f_vty_allow_emerg_msc(true);
10564 f_vty_allow_emerg_bts(true, 0);
10565 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10566 vc_conn.done;
10567 f_shutdown_helper();
10568}
10569
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010570private altstep no_bssmap_clear_req() runs on MSC_ConnHdlr {
10571 [] BSSAP.receive(tr_BSSMAP_ClearRequest) {
10572 setverdict(fail, "unexpected BSSMAP Clear Request");
10573 mtc.stop;
10574 }
10575}
10576
10577private type enumerated RslRel {
10578 RSLREL_REL_IND,
10579 RSLREL_CONN_FAIL
10580};
10581
10582private function f_emerg_call_and_lcs_loc_req_early_lchan_release(RslRel rsl_rel) runs on MSC_ConnHdlr
10583{
10584 g_pars.ra := f_rnd_ra_emerg();
10585 f_assignment_emerg_setup();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +010010586 f_assignment_emerg_setup_exp_bssap();
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010587
10588 /* Start a Location Request to locate the emergency */
10589 f_bssap_le_register_imsi(g_pars.imsi, omit);
10590 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10591 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10592 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10593
10594 /* As long as this LCS is going on, the BSC should not send any Clear Request. Later on, it is up to the MSC to
10595 * do a Clear Command when the Location Response arrives. */
10596 activate(no_bssmap_clear_req());
10597
10598 /* the lchan gets interrupted while the Location Request has no response */
10599 select (rsl_rel) {
10600 case (RSLREL_REL_IND) {
10601 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10602 f_expect_lchan_rel(RSL, RSL_PROC);
10603 }
10604 case (RSLREL_CONN_FAIL) {
10605 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
10606 }
10607 case else {
10608 setverdict(fail, "Unknown RslRel type");
10609 mtc.stop;
10610 }
10611 }
10612
10613 /* Still expect the Location Response to find its way to the MSC. */
10614 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10615 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10616 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10617
10618 setverdict(pass);
10619
10620 select (rsl_rel) {
10621 case (RSLREL_REL_IND) {
10622 f_perform_clear_no_lchan();
10623 }
10624 case (RSLREL_CONN_FAIL) {
10625 f_perform_clear();
10626 }
10627 }
10628}
10629
10630private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind(charstring id) runs on MSC_ConnHdlr
10631{
10632 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_REL_IND);
10633}
10634
10635testcase TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() runs on test_CT {
10636 var MSC_ConnHdlr vc_conn;
10637 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10638
10639 f_init(1, true);
10640 f_sleep(1.0);
10641 f_vty_allow_emerg_msc(true);
10642 f_vty_allow_emerg_bts(true, 0);
10643 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind), pars);
10644 vc_conn.done;
10645 f_shutdown_helper();
10646}
10647
10648private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail(charstring id) runs on MSC_ConnHdlr
10649{
10650 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_CONN_FAIL);
10651}
10652
10653testcase TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() runs on test_CT {
10654 var MSC_ConnHdlr vc_conn;
10655 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10656
10657 f_init(1, true);
10658 f_sleep(1.0);
10659 f_vty_allow_emerg_msc(true);
10660 f_vty_allow_emerg_bts(true, 0);
10661 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail), pars);
10662 vc_conn.done;
10663 f_shutdown_helper();
10664}
10665
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010666/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10667private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10668 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10669
10670 /* Also disable attach for the single connected MSC */
10671 f_vty_msc_allow_attach(BSCVTY, { false });
10672
10673 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) ));
10674 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10675
10676 /* No MSC is found, expecting a proper release on RSL */
10677 interleave {
10678 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10679 f_logp(BSCVTY, "Got RSL RR Release");
10680 }
10681 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10682 f_logp(BSCVTY, "Got RSL Deact SACCH");
10683 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010684 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010685 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10686 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010687 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010688 }
10689 }
10690 setverdict(pass);
10691}
10692testcase TC_no_msc() runs on test_CT {
10693
10694 f_init(1, true);
10695 f_sleep(1.0);
10696 var MSC_ConnHdlr vc_conn;
10697 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10698
10699 f_ctrs_bsc_init(counternames_bsc_mscpool);
10700
10701 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10702 vc_conn.done;
10703
10704 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10705 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010706 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010707}
10708
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010709/* Dyn PDCH todo:
10710 * activate OSMO as TCH/F
10711 * activate OSMO as TCH/H
10712 * does the BSC-located PCU socket get the updated INFO?
10713 * what if no PCU is connected at the time?
10714 * is the info correct on delayed PCU (re)connect?
10715 */
Harald Welte94e0c342018-04-07 11:33:23 +020010716
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010717private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +020010718 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020010719 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010720
10721 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10722 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10723 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10724 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10725 g_pars.ass_codec_list.codecElements[0];
10726 if (isvalue(g_pars.expect_mr_s0_s7)) {
10727 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10728 g_pars.expect_mr_s0_s7;
10729 }
10730 }
10731 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10732 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10733 log("expecting ASS COMPL like this: ", exp_compl);
10734
10735 f_establish_fully(ass_cmd, exp_compl);
10736
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010737 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 +000010738
10739 var RSL_Message rsl;
10740
10741 timer T := 5.0;
10742 T.start;
10743 alt {
10744 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10745 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10746 log("Rx L3 from net: ", l3);
10747 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10748 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10749 mtc.stop;
10750 }
10751 }
10752 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10753 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10754 mtc.stop;
10755 }
10756 [] T.timeout {
10757 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10758 setverdict(pass);
10759 }
10760 }
10761 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010762
10763 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010764}
10765
10766/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10767 * osmo-bsc. */
10768testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10769 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10770 var MSC_ConnHdlr vc_conn;
10771
10772 f_init(1, true);
10773 f_sleep(1.0);
10774
10775 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10776 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10777 vc_conn.done;
10778 f_shutdown_helper();
10779}
10780
10781/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10782 */
10783testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10784 f_init_vty();
10785
10786 f_init(1, false);
10787 f_sleep(1.0);
10788
10789 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10790
10791 var ASP_RSL_Unitdata rx_rsl_ud;
10792 timer T := 5.0;
10793
10794 T.start;
10795 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010796 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010797 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10798 T.stop;
10799 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10800 mtc.stop;
10801 }
10802 repeat;
10803 }
10804 [] T.timeout {
10805 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10806 setverdict(pass);
10807 }
10808 }
10809}
10810
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010811private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10812 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010813 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010814
10815 /* Trigger re-assignment to another lchan */
10816 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10817
10818 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10819 * one MDCX on MGCP. */
10820 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10821
10822 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10823 * as the old lchan used. */
10824 g_media.bts.ipa_crcx_seen := false;
10825 g_media.bts.ipa_mdcx_seen := false;
10826
10827 /* Send different BTS side RTP port number for the new lchan */
10828 g_media.bts.bts.port_nr := 4223;
10829
10830 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10831
10832 /* Trigger re-assignment. */
10833 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10834
10835 timer T := 5.0;
10836 T.start;
10837 alt {
10838 [] as_assignment(assignment_st);
10839 [] as_Media();
10840 [] T.timeout {
10841 break;
10842 }
10843 }
10844
10845 if (not assignment_st.assignment_done) {
10846 setverdict(fail, "Assignment did not complete");
10847 mtc.stop;
10848 }
10849
10850 f_check_mgcp_expectations()
10851 setverdict(pass);
10852
10853 f_sleep(2.0);
10854 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10855
10856 /* Instruct BSC to clear channel */
10857 var BssmapCause cause := 0;
10858 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10859 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010860 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10861 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010862 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010863 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010864 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010865 }
10866 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10867 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10868 }
10869 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010870 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010871
10872 f_sleep(0.5);
10873}
10874
10875testcase TC_reassignment_fr() runs on test_CT {
10876 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10877 var MSC_ConnHdlr vc_conn;
10878
10879 f_init(1, true);
10880 f_sleep(1.0);
10881
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010882 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010883
10884 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10885 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10886 vc_conn.done;
10887
10888 /* from f_establish_fully() */
10889 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10890 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10891 /* from re-assignment */
10892 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10893 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10894 f_ctrs_bsc_and_bts_verify();
10895 f_shutdown_helper();
10896}
10897
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010898const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10899const charstring REEST_CLEAR := "REEST_CLEAR";
10900const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10901
10902/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10903 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10904 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10905 * the MSC as the CM Re-Establishment is handled.
10906 *
10907 * MS bts0 bts1 bsc msc test-component
10908 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10909 * | | _1 wait a bit, to settle down
10910 * |<-x x--| | _1 "lose connection"
10911 * | | REEST_LOST_CONNECTION
10912 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10913 * | | REEST_CLEAR
10914 * | |<-0---| _1 Clear Command on first A-conn
10915 * | |--0-->| _1 Clear Complete
10916 * | |<----------------->| | _1 Release first channel
10917 * | | REEST_CLEAR_DONE
10918 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10919 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10920 *
10921 */
10922private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10923 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10924 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10925
10926 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10927 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10928
10929 f_establish_fully(ass_cmd, exp_compl);
10930
10931 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10932 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10933 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10934 f_sleep(2.0);
10935 COORD.send(REEST_LOST_CONNECTION);
10936
10937 alt {
10938 [] COORD.receive(REEST_CLEAR);
10939 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10940 setverdict(fail, "Unexpected channel release");
10941 mtc.stop;
10942 }
10943 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10944 setverdict(fail, "Unexpected channel release");
10945 mtc.stop;
10946 }
10947 }
10948 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010949 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010950 COORD.send(REEST_CLEAR_DONE);
10951}
10952
10953private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10954 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10955
10956 /* The MS lost the connection on the first channel, now establishes another one */
10957 COORD.receive(REEST_LOST_CONNECTION);
10958
10959 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10960 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10961 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10962
10963 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010964 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 +020010965 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10966
10967 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10968 COORD.send(REEST_CLEAR);
10969 COORD.receive(REEST_CLEAR_DONE);
10970
10971 f_sleep(2.0);
10972
10973 /* Answer the CM Re-Establishment with an Assignment Command. */
10974 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10975 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10976 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10977 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10978
10979 var AssignmentState st := valueof(ts_AssignmentStateInit);
10980 st.voice_call := true;
10981 st.is_assignment := true;
10982
10983 var ExpectCriteria mgcpcrit := {
10984 connid := omit,
10985 endpoint := omit,
10986 transid := omit
10987 };
10988 f_create_mgcp_expect(mgcpcrit);
10989
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010990 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010991
10992 BSSAP.send(ass_cmd);
10993
10994 var PDU_BSSAP bssap;
10995
10996 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010997 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10998 [] as_Media_ipacc(RSL1, RSL2);
10999 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011000 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
11001 break;
11002 }
11003 }
11004
11005 f_sleep(3.0);
11006
11007 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011008 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011009}
11010
11011testcase TC_cm_reestablishment() runs on test_CT {
11012 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11013 var MSC_ConnHdlr vc_conn1;
11014
11015 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11016 var MSC_ConnHdlr vc_conn2;
11017 pars2.imsi := pars1.imsi;
11018 pars2.media_nr := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011019 pars2.expect_tsc := c_BtsParams[1].tsc;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011020
11021 f_init(2, true, guard_timeout := 40.0);
11022 f_sleep(1.0);
11023
11024 vc_conn1 := f_start_handler_create(pars1);
11025 vc_conn2 := f_start_handler_create(pars2);
11026 connect(vc_conn1:COORD, vc_conn2:COORD);
11027 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
11028 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
11029 vc_conn1.done;
11030 vc_conn2.done;
11031
11032 f_shutdown_helper();
11033}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011034
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011035function f_exp_ipa_rx_nonfatal(template (present) RSL_Message t_rx,
11036 boolean ignore_other_rx := true,
11037 BtsTrxIdx idx := {0, 0},
11038 float Tval := 2.0)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011039runs on test_CT return template (omit) RSL_Message {
11040 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011041 timer T := Tval;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011042
11043 T.start;
11044 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011045 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011046 T.stop;
11047 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011048 [ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
11049 [not ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011050 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
11051 T.stop;
11052 return omit;
11053 }
11054 [] T.timeout {
11055 return omit;
11056 }
11057 }
11058 return rx_rsl_ud.rsl;
11059}
11060
11061private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
11062 f_vty_enter_cfg_bts(pt, bts_nr);
11063 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
11064 f_vty_transceive(pt, "exit");
11065 f_vty_transceive(pt, "exit");
11066 f_vty_transceive(pt, "exit");
11067}
11068
11069private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030011070 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011071 template (present) uint12_t arfcn := ?,
11072 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011073{
11074 var RSL_IE_Body full_imm_ass_info;
11075 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
11076 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
11077 mtc.stop;
11078 }
11079
11080 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
11081 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
11082 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011083 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011084 page_mode := ?);
11085 if (not match(rr_imm_ass, expect_imm_ass)) {
11086 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
11087 setverdict(fail, "Failed to match Immediate Assignment");
11088 mtc.stop;
11089 }
11090}
11091
11092testcase TC_imm_ass_post_chan_ack() runs on test_CT {
11093 var RSL_Message chan_act;
11094 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011095 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011096
11097 f_init(1, false);
11098 f_sleep(1.0);
11099
11100 /* (should be the default anyway, just to make things clear) */
11101 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
11102
11103 /* RA containing reason=LU */
11104 var GsmFrameNumber fn := 2342;
11105 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011106 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011107
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011108 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011109
11110 /* First send the Chan Act ACK */
11111 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011112 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011113 var RSL_IE_Body chan_ident_ie;
11114 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11115 setverdict(fail, "RSL Channel Identification IE is absent");
11116 mtc.stop;
11117 }
11118
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011119 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011120
11121 /* Then expect the Immediate Assignment, after we ACKed the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011122 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011123
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011124 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11125 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011126
11127 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011128 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011129
11130 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011131 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011132 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011133 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11134
11135 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011136 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011137 f_shutdown_helper();
11138}
11139
11140testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
11141 var RSL_Message chan_act;
11142 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011143 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011144
11145 f_init(1, false);
11146 f_sleep(1.0);
11147
11148 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11149
11150 /* RA containing reason=LU */
11151 var GsmFrameNumber fn := 2342;
11152 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011153 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011154
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011155 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011156 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011157 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011158 var RSL_IE_Body chan_ident_ie;
11159 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11160 setverdict(fail, "RSL Channel Identification IE is absent");
11161 mtc.stop;
11162 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011163
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011164 /* (set bts 0 cfg back to default) */
11165 f_vty_set_imm_ass(BSCVTY);
11166
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011167 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011168 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011169 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11170 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011171
11172 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011173 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011174
11175 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011176 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011177
11178 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011179 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011180 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011181 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11182
11183 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011184 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011185 f_shutdown_helper();
11186}
11187
Neels Hofmeyr23158742021-09-07 19:08:07 +020011188testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
11189 var RSL_Message chan_act;
11190 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011191 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr23158742021-09-07 19:08:07 +020011192
11193 f_init(1, false);
11194 f_sleep(1.0);
11195
11196 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11197
11198 /* RA containing reason=LU */
11199 var GsmFrameNumber fn := 2342;
11200 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011201 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011202
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011203 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011204 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011205 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr23158742021-09-07 19:08:07 +020011206 var RSL_IE_Body chan_ident_ie;
11207 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11208 setverdict(fail, "RSL Channel Identification IE is absent");
11209 mtc.stop;
11210 }
11211
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011212 /* (set bts 0 cfg back to default) */
11213 f_vty_set_imm_ass(BSCVTY);
11214
Neels Hofmeyr23158742021-09-07 19:08:07 +020011215 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011216 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011217 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11218 chan_ident_ie.chan_ident.ch_desc.v.tsc);
11219
11220 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011221 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011222
11223 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011224 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011225
11226 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011227 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011228 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020011229 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11230
11231 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011232 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020011233 f_shutdown_helper();
11234}
11235
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011236testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
11237 /* change Timeslot 6 before f_init() starts RSL */
11238 f_init_vty();
11239 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11240 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11241
11242 f_init(1, false);
11243 f_sleep(1.0);
11244
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011245 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011246 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11247 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011248 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11249 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011250
11251 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11252 f_ts_set_chcomb(0, 0, 6, "PDCH");
11253
11254 /* block all static timeslots so that the dyn TS will be used */
11255 f_disable_all_tch_f();
11256 f_disable_all_tch_h();
11257 f_disable_all_sdcch();
11258
11259 var RSL_Message chan_act;
11260 var RSL_Message imm_ass;
11261
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011262 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11263
11264 /* RA containing reason=LU */
11265 var GsmFrameNumber fn := 2342;
11266 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011267 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011268
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011269 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011270 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
11271 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011272
11273 /* Now activation as SDCCH8 */
11274 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011275 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011276
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011277 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011278 var RSL_IE_Body chan_ident_ie;
11279 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11280 setverdict(fail, "RSL Channel Identification IE is absent");
11281 mtc.stop;
11282 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011283
11284 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011285 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011286 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11287 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011288
11289 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011290 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011291
11292 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011293 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011294
11295 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011296 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011297 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011298 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11299
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011300 /* (set bts 0 cfg back to default) */
11301 f_vty_set_imm_ass(BSCVTY);
11302
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011303 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011304 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011305 f_shutdown_helper();
11306}
11307
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011308testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
11309 /* change Timeslot 6 before f_init() starts RSL */
11310 f_init_vty();
11311 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11312 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11313
11314 f_init(1, false);
11315 f_sleep(1.0);
11316
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011317 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011318 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11319 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011320 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11321 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011322
11323 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11324 f_ts_set_chcomb(0, 0, 6, "PDCH");
11325
11326 /* block all static timeslots so that the dyn TS will be used */
11327 f_disable_all_tch_f();
11328 f_disable_all_tch_h();
11329 f_disable_all_sdcch();
11330
11331 var RSL_Message chan_act;
11332 var RSL_Message imm_ass;
11333
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011334 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11335
11336 /* RA containing reason=LU */
11337 var GsmFrameNumber fn := 2342;
11338 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011339 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011340
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011341 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011342 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011343
11344 /* And already the Immediate Assignment even before the PDCH Deact ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011345 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011346
11347 /* continue the Osmo style PDCH Deact (usual chan rel) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011348 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011349
11350 /* Now activation as SDCCH8 */
11351 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011352 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011353
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011354 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011355 var RSL_IE_Body chan_ident_ie;
11356 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11357 setverdict(fail, "RSL Channel Identification IE is absent");
11358 mtc.stop;
11359 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011360 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011361
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011362 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11363 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011364
11365 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011366 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011367
11368 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011369 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011370 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011371 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11372
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011373 /* (set bts 0 cfg back to default) */
11374 f_vty_set_imm_ass(BSCVTY);
11375
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011376 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011377 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011378 f_shutdown_helper();
11379}
11380
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011381/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11382testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11383 var MSC_ConnHdlr vc_conn;
11384
11385 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11386 f_sleep(1.0);
11387
11388 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11389 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11390 "0,0,operational,unlocked,on,rsl-up;" &
11391 "1,0,operational,unlocked,on,rsl-up;" &
11392 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011393 "2,1,operational,unlocked,on,rsl-down;" &
11394 "2,2,operational,unlocked,on,rsl-down;" &
11395 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011396 "3,0,inoperational,locked,on,rsl-down;");
11397
11398 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11399 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11400 /* give it a moment to settle the FSM status */
11401 f_sleep(1.0);
11402
11403 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11404 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11405 * of "off"? But that's for a future patch if at all. */
11406 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11407 "0,0,operational,unlocked,on,rsl-up;" &
11408 "1,0,operational,locked,on,rsl-up;" &
11409 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011410 "2,1,operational,unlocked,on,rsl-down;" &
11411 "2,2,operational,unlocked,on,rsl-down;" &
11412 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011413 "3,0,inoperational,locked,on,rsl-down;");
11414
11415 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11416 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11417 f_sleep(1.0);
11418 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11419 "0,0,operational,unlocked,on,rsl-up;" &
11420 "1,0,operational,locked,on,rsl-up;" &
11421 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011422 "2,1,operational,unlocked,on,rsl-down;" &
11423 "2,2,operational,unlocked,on,rsl-down;" &
11424 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011425 "3,0,inoperational,locked,on,rsl-down;");
11426
11427 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11428 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11429 f_sleep(1.0);
11430 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11431 "0,0,operational,unlocked,on,rsl-up;" &
11432 "1,0,operational,unlocked,on,rsl-up;" &
11433 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011434 "2,1,operational,unlocked,on,rsl-down;" &
11435 "2,2,operational,unlocked,on,rsl-down;" &
11436 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011437 "3,0,inoperational,locked,on,rsl-down;");
11438
11439 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11440 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11441 f_sleep(1.0);
11442 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11443 "0,0,operational,unlocked,on,rsl-up;" &
11444 "1,0,operational,unlocked,on,rsl-up;" &
11445 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011446 "2,1,operational,unlocked,on,rsl-down;" &
11447 "2,2,operational,unlocked,on,rsl-down;" &
11448 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011449 "3,0,inoperational,locked,on,rsl-down;");
11450
11451 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11452 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11453 f_sleep(1.0);
11454 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11455 "0,0,operational,unlocked,on,rsl-up;" &
11456 "1,0,operational,unlocked,on,rsl-up;" &
11457 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011458 "2,1,operational,unlocked,on,rsl-down;" &
11459 "2,2,operational,unlocked,on,rsl-down;" &
11460 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011461 "3,0,inoperational,locked,on,rsl-down;");
11462
11463 f_shutdown_helper();
11464}
11465
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011466const CounterNameVals counternames_cm_serv_rej := {
11467 { "cm_serv_rej", 0 },
11468 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11469 { "cm_serv_rej:illegal_ms", 0 },
11470 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11471 { "cm_serv_rej:imei_not_accepted", 0 },
11472 { "cm_serv_rej:illegal_me", 0 },
11473 { "cm_serv_rej:plmn_not_allowed", 0 },
11474 { "cm_serv_rej:loc_not_allowed", 0 },
11475 { "cm_serv_rej:roaming_not_allowed", 0 },
11476 { "cm_serv_rej:network_failure", 0 },
11477 { "cm_serv_rej:synch_failure", 0 },
11478 { "cm_serv_rej:congestion", 0 },
11479 { "cm_serv_rej:srv_opt_not_supported", 0 },
11480 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11481 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11482 { "cm_serv_rej:call_can_not_be_identified", 0 },
11483 { "cm_serv_rej:incorrect_message", 0 },
11484 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11485 { "cm_serv_rej:msg_type_not_implemented", 0 },
11486 { "cm_serv_rej:msg_type_not_compatible", 0 },
11487 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11488 { "cm_serv_rej:condtional_ie_error", 0 },
11489 { "cm_serv_rej:msg_not_compatible", 0 },
11490 { "cm_serv_rej:protocol_error", 0 },
11491 { "cm_serv_rej:retry_in_new_cell", 0 }
11492};
11493
11494private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11495{
11496 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011497 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011498 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011499 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11500 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011501 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011502}
11503testcase TC_cm_serv_rej() runs on test_CT {
11504 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11505 var MSC_ConnHdlr vc_conn;
11506
11507 f_init(1, true);
11508 f_sleep(1.0);
11509
11510 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11511
11512 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11513 vc_conn.done;
11514
11515 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11516 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11517 f_ctrs_bts_verify();
11518
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011519 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011520 f_shutdown_helper();
11521}
11522
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011523/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11524 * Activ Ack (SYS#5627). */
11525private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11526 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011527
11528 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11529 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011530
11531 var BSSMAP_FIELD_CodecType codecType;
11532 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11533
11534 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11535
11536 /* First establish a signalling lchan */
11537 f_create_chan_and_exp();
11538 f_rslem_dchan_queue_enable();
11539
11540 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011541
11542 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011543 activate(as_Media_mgw(fail_on_dlcx := false));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011544
11545 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11546 f_rslem_register(0, chan_nr);
11547
11548 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11549 BSSAP.send(ass_cmd);
11550
11551
11552 /* Wait for the Channel Activ for the TCH channel */
11553 var ASP_RSL_Unitdata rx_rsl_ud;
11554 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11555
11556 /* make the original SDCCH disappear */
11557 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11558
11559 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11560 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11561
11562 interleave {
11563 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11564 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11565 }
11566
11567 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11568 BSSAP.receive(tr_BSSMAP_ClearComplete);
11569 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11570
11571 var MgcpCommand mgcp;
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011572 var MGCP_RecvFrom mrf;
11573 var template MgcpMessage msg_dlcx := { command := tr_DLCX };
11574 alt {
11575 [g_pars.aoip] MGCP.receive(tr_DLCX) -> value mgcp {
11576 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11577 }
11578 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
11579 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
11580 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
11581 }));
11582 }
11583 }
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011584
11585 f_sleep(0.5);
11586}
11587testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11588 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11589 var MSC_ConnHdlr vc_conn;
11590
11591 f_init(1, true);
11592 f_sleep(1.0);
11593
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011594 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11595 vc_conn.done;
11596
11597 f_shutdown_helper();
11598}
11599
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011600const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11601 { "all_allocated:sdcch", 0 },
11602 { "all_allocated:static_sdcch", 0 },
11603 { "all_allocated:tch", 0 },
11604 { "all_allocated:static_tch", 0 }
11605}
11606
11607private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11608{
11609 /* Make sure counters settle first */
11610 f_sleep(1.0);
11611
11612 /* Take a baseline of counters */
11613 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11614
11615 /* Elapse some time so that we see changes in counters, hopefully where expected */
11616 f_sleep(2.0);
11617
11618 /* Get new counters */
11619 var charstring_list all_changed := {};
11620 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11621 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11622
11623 /* Compare with expectations */
11624 var charstring_list all_expect_changed := {};
11625 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11626 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11627 }
11628 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11629}
11630
11631testcase TC_ratectr_all_available_allocated() runs on test_CT {
11632 var ASP_RSL_Unitdata rsl_ud;
11633 var integer i;
11634 var integer chreq_total, chreq_nochan;
11635
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011636 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011637 f_sleep(1.0);
11638
11639 /* Exhaust all dedicated SDCCH lchans.
11640 /* GSM 44.018 Table 9.1.8.2:
11641 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11642 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011643 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011644 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011645 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011646 }
11647
11648 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11649 * level.
11650 * All SDCCH are now occupied. */
11651 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11652
11653 /* Also fill up all remaining (TCH) channels */
11654 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011655 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011656 }
11657
11658 /* All TCH are now also occupied */
11659 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11660 "all_allocated:tch", "all_allocated:static_tch"});
11661
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011662 /* Clean up SDCCH lchans */
11663 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11664 f_perform_clear_test_ct(chan_cleanup[i]);
11665 }
11666
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011667 f_shutdown_helper();
11668}
11669
11670testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11671 var ASP_RSL_Unitdata rsl_ud;
11672 var integer i;
11673 var integer chreq_total, chreq_nochan;
11674
11675 f_init_vty();
11676 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11677 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11678 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11679
11680 f_init(1, guard_timeout := 60.0);
11681 f_sleep(1.0);
11682
11683 /* The dyn TS wants to activate PDCH mode, ACK that. */
11684 var RslChannelNr chan_nr;
11685 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011686 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11687 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011688
11689 /* Exhaust all dedicated SDCCH lchans.
11690 /* GSM 44.018 Table 9.1.8.2:
11691 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11692 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011693 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011694 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011695 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011696 }
11697
11698 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11699 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11700 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11701
11702 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11703 * Will release them later, so remember all the DchanTuples. */
11704 var DchanTuples dyn_sddch := {};
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011705 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011706
11707 /* Also occupy the seven other SDCCH of the dyn TS */
11708 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011709 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011710 }
11711
11712 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11713 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11714
11715 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11716 for (i := 0; i < 5; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011717 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011718 }
11719
11720 /* All TCH lchans are now also occupied, both static and dynamic */
11721 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11722 "all_allocated:tch", "all_allocated:static_tch"});
11723
11724 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11725 * incrementing. */
11726 var BssmapCause cause := 0;
11727 var DchanTuple dt := dyn_sddch[0];
11728 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011729 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011730
11731 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11732 * count as occupied, so those still both increment. */
11733 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11734 "all_allocated:tch", "all_allocated:static_tch"});
11735
11736 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11737 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11738 dt := dyn_sddch[i];
11739 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011740 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011741 }
11742
11743 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11744 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011745 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11746 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011747
11748 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11749 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11750
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011751 /* Clean up SDCCH lchans */
11752 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11753 f_perform_clear_test_ct(chan_cleanup[i]);
11754 }
11755
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011756 /* clean up config */
11757 f_ts_reset_chcomb(0);
11758
11759 f_shutdown_helper();
11760}
11761
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011762private function f_TC_chan_alloc_algo(DchanTuple dt, BtsTrxIdx idx)
11763runs on test_CT {
11764 /* MSC sends an Assignment Request */
11765 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11766 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11767 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11768 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
11769
11770 /* Expect the BSC to allocate a TCH channel on the given BTS/TRX */
11771 var RSL_Message rsl_chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
11772 /* Send CHAN ACT NACK, so that the requested TCH channel becomes BORKEN */
11773 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(rsl_chan_act.ies[0].body.chan_nr, RSL_ERR_EQUIPMENT_FAIL), idx);
11774 /* Expect to receive an Assignment Failure */
11775 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail));
11776}
11777
11778testcase TC_chan_alloc_algo_ascending() runs on test_CT {
11779 /* We need to access BTS2, which has 4 TRXs */
11780 f_init(nr_bts := 3);
11781
11782 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011783 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011784
11785 f_vty_enter_cfg_bts(BSCVTY, 2);
11786 f_vty_transceive(BSCVTY, "channel allocator ascending");
11787 f_vty_transceive(BSCVTY, "end");
11788
11789 /* Expect the BSC to allocate 4 x TCH/F channels on BTS2/TRX0 */
11790 for (var integer i := 0; i < 4; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011791 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011792 f_TC_chan_alloc_algo(dt, {2, 0});
11793 f_perform_clear_test_ct(dt);
11794 }
11795
11796 /* At this point all 4 x TCH/F channels are BORKEN, but they will be
11797 * resurrected upon the A-bis/OML link re-establishment. */
11798 f_shutdown_helper();
11799}
11800
11801testcase TC_chan_alloc_algo_descending() runs on test_CT {
11802 /* We need to access BTS2, which has 4 TRXs */
11803 f_init(nr_bts := 3);
11804
11805 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011806 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011807
11808 f_vty_enter_cfg_bts(BSCVTY, 2);
11809 f_vty_transceive(BSCVTY, "channel allocator descending");
11810 f_vty_transceive(BSCVTY, "end");
11811
11812 /* Expect the BSC to allocate 5 x TCH/F channels on BTS2/TRX3 */
11813 for (var integer i := 0; i < 5; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011814 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011815 f_TC_chan_alloc_algo(dt, {2, 3});
11816 f_perform_clear_test_ct(dt);
11817 }
11818
11819 /* At this point all 5 x TCH/F channels are BORKEN, but they will be
11820 * resurrected upon the A-bis/OML link re-establishment. */
11821 f_shutdown_helper();
11822}
11823
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011824testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
11825 const BtsTrxIdx TRX0 := {2, 0};
11826 const BtsTrxIdx TRX3 := {2, 3};
11827
11828 /* We need to access BTS2, which has 4 TRXs */
11829 f_init(nr_bts := 3);
11830
11831 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011832 vc_MGCP[0].stop;
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011833
11834 f_vty_enter_cfg_bts(BSCVTY, 2);
11835 f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
11836 f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
11837 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
11838 f_vty_transceive(BSCVTY, "end");
11839
11840 var DchanTuple dt;
11841
11842 f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011843 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011844 f_TC_chan_alloc_algo(dt, TRX0);
11845 f_perform_clear_test_ct(dt);
11846
11847 f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011848 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011849 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11850 ts_RSL_IE_UplinkMeas(30, 0),
11851 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011852 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011853 f_TC_chan_alloc_algo(dt, TRX0);
11854 f_perform_clear_test_ct(dt);
11855
11856 f_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011857 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011858 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11859 ts_RSL_IE_UplinkMeas(45, 0),
11860 ts_RSL_IE_BS_Power(0)), TRX0);
11861 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11862 ts_RSL_IE_UplinkMeas(48, 0),
11863 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011864 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011865 f_TC_chan_alloc_algo(dt, TRX0);
11866 f_perform_clear_test_ct(dt);
11867
11868 f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011869 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011870 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11871 ts_RSL_IE_UplinkMeas(50, 0),
11872 ts_RSL_IE_BS_Power(0)), TRX0);
11873 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11874 ts_RSL_IE_UplinkMeas(58, 0),
11875 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011876 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011877 f_TC_chan_alloc_algo(dt, TRX3);
11878 f_perform_clear_test_ct(dt);
11879
11880 f_vty_enter_cfg_bts(BSCVTY, 2);
11881 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
11882 f_vty_transceive(BSCVTY, "end");
11883
11884 f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011885 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011886 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11887 ts_RSL_IE_UplinkMeas(50, 0),
11888 ts_RSL_IE_BS_Power(0)), TRX0);
11889 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11890 ts_RSL_IE_UplinkMeas(58, 0),
11891 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011892 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011893 f_TC_chan_alloc_algo(dt, TRX0);
11894 f_perform_clear_test_ct(dt);
11895
11896 f_vty_enter_cfg_bts(BSCVTY, 2);
11897 f_vty_transceive(BSCVTY, "channel allocator ascending");
11898 f_vty_transceive(BSCVTY, "end");
11899
11900 /* At this point some TCH/F channels are BORKEN, but they will be
11901 * resurrected upon the A-bis/OML link re-establishment. */
11902 f_shutdown_helper();
11903}
11904
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020011905private function f_vty_mgw_enable(integer mgw_nr := 1) runs on test_CT {
11906 var rof_charstring cmds := {
11907 "remote-ip " & mp_test_ip,
11908 "remote-port " & int2str(2427 + mgw_nr)
11909 };
11910 f_vty_config3(BSCVTY, {"network", "mgw " & int2str(mgw_nr)}, cmds);
11911 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " reconnect")
11912}
11913private function f_vty_mgw_disable(integer mgw_nr := 1) runs on test_CT {
11914 f_vty_config3(BSCVTY, {"network"}, { "no mgw " &int2str(mgw_nr) });
11915}
11916private function f_vty_mgw_block(integer mgw_nr := 1, boolean blocked := true) runs on test_CT {
11917 var charstring arg;
11918 if (blocked) {
11919 arg := "block";
11920 } else {
11921 arg := "unblock";
11922 }
11923 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " " & arg);
11924}
11925private const charstring COORD_CMD_ESTABLISHED := "COORD_CMD_ESTABLISHED";
11926private function f_TC_mgwpool_call_seq_1(charstring id) runs on MSC_ConnHdlr {
11927 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11928 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11929 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11930 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11931
11932 f_establish_fully(ass_cmd, exp_compl);
11933 COORD.send(COORD_CMD_ESTABLISHED);
11934
11935 COORD.receive(COORD_CMD_ESTABLISHED);
11936 f_perform_clear()
11937 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11938}
11939private function f_TC_mgwpool_call_seq_2(charstring id) runs on MSC_ConnHdlr {
11940 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11941 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11942 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11943 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11944
11945
11946 COORD.receive(COORD_CMD_ESTABLISHED);
11947 f_establish_fully(ass_cmd, exp_compl);
11948 COORD.send(COORD_CMD_ESTABLISHED);
11949
11950 f_perform_clear()
11951 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11952}
11953/* Test load is spread around 2 available MGWs */
11954testcase TC_mgwpool_all_used() runs on test_CT {
11955 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11956 var MSC_ConnHdlr vc_conn1;
11957 pars1.mgwpool_idx := 0;
11958
11959 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11960 var MSC_ConnHdlr vc_conn2;
11961 pars2.mgwpool_idx := 1;
11962
11963 f_init(1, true, nr_mgw := 2);
11964 f_sleep(1.0);
11965
11966 f_vty_mgw_enable(1);
11967
11968 vc_conn1 := f_start_handler_create(pars1);
11969 vc_conn2 := f_start_handler_create(pars2);
11970 connect(vc_conn1:COORD, vc_conn2:COORD);
11971 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11972 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11973 vc_conn1.done;
11974 vc_conn2.done;
11975
11976 f_vty_mgw_disable(1);
11977
11978 f_shutdown_helper();
11979}
11980
11981/* Test blocked MGW in the pool are not selected */
11982testcase TC_mgwpool_blocked_not_used() runs on test_CT {
11983 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11984 var MSC_ConnHdlr vc_conn1;
11985 pars1.mgwpool_idx := 0;
11986
11987 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11988 var MSC_ConnHdlr vc_conn2;
11989 pars2.mgwpool_idx := 0; /* expect it in the first one, since the second will be blocked */
11990 pars2.media_nr := 2;
11991
11992 f_init(1, true, nr_mgw := 2);
11993 f_sleep(1.0);
11994
11995 f_vty_mgw_enable(1);
11996 f_vty_mgw_block(1, true);
11997
11998 vc_conn1 := f_start_handler_create(pars1);
11999 vc_conn2 := f_start_handler_create(pars2);
12000 connect(vc_conn1:COORD, vc_conn2:COORD);
12001 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12002 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12003 vc_conn1.done;
12004 vc_conn2.done;
12005
12006 f_vty_mgw_disable(1);
12007
12008 f_shutdown_helper();
12009}
12010
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012011/* Test BTS pinning to an MGW is applied */
12012testcase TC_mgwpool_pin_bts() runs on test_CT {
12013 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
12014 var MSC_ConnHdlr vc_conn1;
12015 pars1.mgwpool_idx := 0;
12016
12017 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12018 var MSC_ConnHdlr vc_conn2;
12019 pars2.mgwpool_idx := 0; /* expect it in the first one, since the BTS is pinned to the first MGW */
12020 pars2.media_nr := 2;
12021
12022 f_init(1, true, nr_mgw := 2);
12023 f_sleep(1.0);
12024
12025 f_vty_mgw_enable(1);
12026 f_vty_cfg_bts(BSCVTY, 0, { "mgw pool-target 0" });
12027
12028 vc_conn1 := f_start_handler_create(pars1);
12029 vc_conn2 := f_start_handler_create(pars2);
12030 connect(vc_conn1:COORD, vc_conn2:COORD);
12031 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12032 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12033 vc_conn1.done;
12034 vc_conn2.done;
12035
12036 f_vty_cfg_bts(BSCVTY, 0, { "no mgw pool-target" } );
Vadim Yanitskiy389d7e02022-10-25 17:44:05 +070012037 f_vty_mgw_disable(1);
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012038
12039 f_shutdown_helper();
12040}
12041
Oliver Smithc9a5f532022-10-21 11:32:23 +020012042private function f_tc_ho_meas_rep_multi_band(charstring id) runs on MSC_ConnHdlr {
12043 g_pars := f_gen_test_hdlr_pars();
12044 var PDU_BSSAP ass_req := f_gen_ass_req();
12045 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
12046 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
12047 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
12048 f_establish_fully(ass_req, exp_compl);
12049
12050 /* Send a measurement report with bad rxlev except on 3rd entry. The
12051 * measurement report is divided into two sub lists, as described in
12052 * 3GPP TS 04.08 § 10.5.2.20. */
12053 var NcellReports neighbor_rep := {
12054 /* Sub list 1: same band */
Oliver Smitha6773042022-10-24 12:56:30 +020012055 { rxlev := 0, bcch_freq := 0, bsic := 12 }, /* ARFCN 800, band 1800, LAC 98 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012056 /* Sub list 2: different band */
Oliver Smitha6773042022-10-24 12:56:30 +020012057 { rxlev := 0, bcch_freq := 1, bsic := 13 }, /* ARFCN 200, band 850, LAC 97 */
12058 { rxlev := 40, bcch_freq := 2, bsic := 14 }, /* ARFCN 1000, band 900, LAC 99 */
12059 { rxlev := 0, bcch_freq := 3, bsic := 11 } /* ARFCN 0, band 900, LAC 96 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012060 };
12061 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
12062 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
12063 l3_mr, 0));
12064
12065 /* Expect a handover to the third entry. If the BSC parsed the report
Oliver Smitha6773042022-10-24 12:56:30 +020012066 * correctly, the third entry has LAC 99. */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012067 var template BSSMAP_FIELD_CellIdentificationList cid_list := {
Oliver Smitha6773042022-10-24 12:56:30 +020012068 cIl_LAC := { ts_BSSMAP_CI_LAC(99) }
Oliver Smithc9a5f532022-10-21 11:32:23 +020012069 };
12070 alt {
12071 [] BSSAP.receive(tr_BSSMAP_HandoverRequired(cid_list := cid_list)) {
12072 setverdict(pass);
12073 }
12074 [] BSSAP.receive(tr_BSSMAP_HandoverRequired()) {
12075 setverdict(fail, "Handover has unexpected LAC in Cell Identification List. The BSC probably"
12076 & " didn't parse the multi-band measurement report correctly.");
12077 }
12078 }
12079
12080 f_ho_out_of_this_bsc(skip_meas_rep := true);
12081}
12082testcase TC_ho_meas_rep_multi_band() runs on test_CT {
12083 /* Verify that the BSC parses the measurement report correctly when
12084 * neighbors in multiple bands are configured (OS#5717). See
12085 * gsm_arfcn2band_rc() in libosmocore src/gsm/gsm_utils.c for the
12086 * ARFCN -> band mapping. The MS is connected to band 1800. */
12087 var MSC_ConnHdlr vc_conn;
12088
12089 f_init_vty();
12090 f_bts_0_cfg(BSCVTY,
12091 {"neighbor-list mode automatic",
12092 "handover 1",
12093 "handover algorithm 2",
12094 "handover2 window rxlev averaging 1",
12095 "no neighbors",
12096 "neighbor lac 99 arfcn 1000 bsic any", /* band 900 */
12097 "neighbor lac 98 arfcn 800 bsic any", /* band 1800 */
12098 "neighbor lac 97 arfcn 200 bsic any", /* band 850 */
Oliver Smitha6773042022-10-24 12:56:30 +020012099 "neighbor lac 96 arfcn 0 bsic any"}); /* band 900 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012100 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
12101
12102 f_init(1, true);
12103 f_sleep(1.0);
12104
12105 f_ctrs_bsc_and_bts_handover_init();
12106
12107 vc_conn := f_start_handler(refers(f_tc_ho_meas_rep_multi_band));
12108 vc_conn.done;
12109
12110 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
12111 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
12112 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
12113 f_ctrs_bsc_and_bts_add(0, "handover:completed");
12114 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
12115 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
12116 f_ctrs_bsc_and_bts_verify();
12117 f_shutdown_helper(ho := true);
12118}
12119
Harald Welte28d943e2017-11-25 15:00:50 +010012120control {
Harald Welte898113b2018-01-31 18:32:21 +010012121 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010012122 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010012123 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020012124 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
12125 * these in the AoIP test suite. */
12126 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12127 execute( TC_stat_num_msc_connected_1() );
12128 execute( TC_stat_num_msc_connected_2() );
12129 execute( TC_stat_num_msc_connected_3() );
12130 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020012131 execute( TC_stat_num_bts_connected_1() );
12132 execute( TC_stat_num_bts_connected_2() );
12133 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010012134 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012135 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020012136 execute( TC_ctrl_location() );
12137 }
Harald Welte898113b2018-01-31 18:32:21 +010012138
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012139 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020012140 execute( TC_si2quater_2_earfcns() );
12141 execute( TC_si2quater_3_earfcns() );
12142 execute( TC_si2quater_4_earfcns() );
12143 execute( TC_si2quater_5_earfcns() );
12144 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020012145 execute( TC_si2quater_12_earfcns() );
12146 execute( TC_si2quater_23_earfcns() );
12147 execute( TC_si2quater_32_earfcns() );
12148 execute( TC_si2quater_33_earfcns() );
12149 execute( TC_si2quater_42_earfcns() );
12150 execute( TC_si2quater_48_earfcns() );
12151 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020012152 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020012153 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012154
Harald Welte898113b2018-01-31 18:32:21 +010012155 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010012156 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010012157 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010012158 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020012159 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020012160 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010012161 execute( TC_chan_act_ack_est_ind_noreply() );
12162 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010012163 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010012164 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070012165 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010012166 execute( TC_chan_rel_rll_rel_ind() );
12167 execute( TC_chan_rel_conn_fail() );
12168 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020012169 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
12170 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010012171 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010012172 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020012173 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010012174 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010012175 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020012176 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010012177
Harald Weltecfe2c962017-12-15 12:09:32 +010012178 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010012179
12180 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010012181 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010012182 execute( TC_assignment_csd() );
12183 execute( TC_assignment_ctm() );
12184 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012185 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12186 execute( TC_assignment_aoip_tla_v6() );
12187 }
Harald Welte235ebf12017-12-15 14:18:16 +010012188 execute( TC_assignment_fr_a5_0() );
12189 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012190 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020012191 execute( TC_assignment_fr_a5_1_codec_missing() );
12192 }
Harald Welte235ebf12017-12-15 14:18:16 +010012193 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020012194 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020012195 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020012196 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012197 execute( TC_ciph_mode_a5_0() );
12198 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020012199 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020012200 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012201 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020012202 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010012203
Harald Welte60aa5762018-03-21 19:33:13 +010012204 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020012205 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010012206 execute( TC_assignment_codec_hr() );
12207 execute( TC_assignment_codec_efr() );
12208 execute( TC_assignment_codec_amr_f() );
12209 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012210
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012211 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010012212 execute( TC_assignment_codec_amr_f_S1() );
12213 execute( TC_assignment_codec_amr_h_S1() );
12214 execute( TC_assignment_codec_amr_f_S124() );
12215 execute( TC_assignment_codec_amr_h_S124() );
12216 execute( TC_assignment_codec_amr_f_S0() );
12217 execute( TC_assignment_codec_amr_f_S02() );
12218 execute( TC_assignment_codec_amr_f_S024() );
12219 execute( TC_assignment_codec_amr_f_S0247() );
12220 execute( TC_assignment_codec_amr_h_S0() );
12221 execute( TC_assignment_codec_amr_h_S02() );
12222 execute( TC_assignment_codec_amr_h_S024() );
12223 execute( TC_assignment_codec_amr_h_S0247() );
12224 execute( TC_assignment_codec_amr_f_S01234567() );
12225 execute( TC_assignment_codec_amr_f_S0234567() );
12226 execute( TC_assignment_codec_amr_f_zero() );
12227 execute( TC_assignment_codec_amr_f_unsupp() );
12228 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000012229 execute( TC_assignment_codec_amr_f_start_mode_auto() );
12230 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000012231 execute( TC_assignment_codec_amr_f_start_mode_4() );
12232 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000012233 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012234 }
Harald Welte60aa5762018-03-21 19:33:13 +010012235
Philipp Maierac09bfc2019-01-08 13:41:39 +010012236 execute( TC_assignment_codec_fr_exhausted_req_hr() );
12237 execute( TC_assignment_codec_fr_exhausted_req_fr() );
12238 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
12239 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
12240 execute( TC_assignment_codec_hr_exhausted_req_fr() );
12241 execute( TC_assignment_codec_hr_exhausted_req_hr() );
12242 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
12243 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
12244 execute( TC_assignment_codec_req_hr_fr() );
12245 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020012246 execute( TC_assignment_sdcch_exhausted_req_signalling() );
12247 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
12248 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010012249
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +020012250 execute( TC_assignment_codec_hr_osmux_on() );
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020012251 execute( TC_assignment_osmux() );
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020012252 execute( TC_assignment_osmux_cn() );
12253 execute( TC_assignment_osmux_bts() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020012254
Harald Welte898113b2018-01-31 18:32:21 +010012255 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010012256 execute( TC_rll_est_ind_inact_lchan() );
12257 execute( TC_rll_est_ind_inval_sapi1() );
12258 execute( TC_rll_est_ind_inval_sapi3() );
12259 execute( TC_rll_est_ind_inval_sacch() );
12260
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070012261 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
12262 execute( TC_tch_dlci_link_id_sapi() );
12263
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012264 /* SAPI N Reject triggered by RLL establishment failures */
12265 execute( TC_rll_rel_ind_sapi_n_reject() );
12266 execute( TC_rll_err_ind_sapi_n_reject() );
12267 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070012268 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012269
Harald Welte898113b2018-01-31 18:32:21 +010012270 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010012271 execute( TC_paging_imsi_nochan() );
12272 execute( TC_paging_tmsi_nochan() );
12273 execute( TC_paging_tmsi_any() );
12274 execute( TC_paging_tmsi_sdcch() );
12275 execute( TC_paging_tmsi_tch_f() );
12276 execute( TC_paging_tmsi_tch_hf() );
12277 execute( TC_paging_imsi_nochan_cgi() );
12278 execute( TC_paging_imsi_nochan_lac_ci() );
12279 execute( TC_paging_imsi_nochan_ci() );
12280 execute( TC_paging_imsi_nochan_lai() );
12281 execute( TC_paging_imsi_nochan_lac() );
12282 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010012283 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
12284 execute( TC_paging_imsi_nochan_rnc() );
12285 execute( TC_paging_imsi_nochan_lac_rnc() );
12286 execute( TC_paging_imsi_nochan_lacs() );
12287 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010012288 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010012289 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010012290 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010012291 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010012292 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020012293 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020012294 execute( TC_paging_450req_no_paging_load_ind() );
Pau Espin Pedrol07657ae2023-01-03 12:08:05 +010012295 execute( TC_paging_imsi_nochan_ci_resp_invalid_mi() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010012296
12297 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010012298 execute( TC_rsl_unknown_unit_id() );
12299
12300 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012301
12302 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020012303 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012304 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010012305 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010012306 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010012307 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010012308 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012309
Harald Welte261af4b2018-02-12 21:20:39 +010012310 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020012311 execute( TC_ho_int_a5_0() );
12312 execute( TC_ho_int_a5_1() );
12313 execute( TC_ho_int_a5_3() );
12314 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000012315 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012316
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012317 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020012318 execute( TC_ho_out_fail_no_msc_response() );
12319 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020012320 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012321
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012322 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020012323 execute( TC_ho_into_this_bsc_a5_0() );
12324 execute( TC_ho_into_this_bsc_a5_1() );
12325 execute( TC_ho_into_this_bsc_a5_3() );
12326 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010012327 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
12328 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010012329 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012330 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12331 execute( TC_ho_into_this_bsc_tla_v6() );
12332 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020012333 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030012334 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010012335 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020012336 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020012337 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
12338 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012339 execute( TC_ho_in_fail_msc_clears() );
12340 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
12341 execute( TC_ho_in_fail_no_detect() );
12342 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010012343 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012344
Neels Hofmeyr91401012019-07-11 00:42:35 +020012345 execute( TC_ho_neighbor_config_1() );
12346 execute( TC_ho_neighbor_config_2() );
12347 execute( TC_ho_neighbor_config_3() );
12348 execute( TC_ho_neighbor_config_4() );
12349 execute( TC_ho_neighbor_config_5() );
12350 execute( TC_ho_neighbor_config_6() );
12351 execute( TC_ho_neighbor_config_7() );
12352
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012353 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010012354 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010012355 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020012356
12357 execute( TC_dyn_pdch_ipa_act_deact() );
12358 execute( TC_dyn_pdch_ipa_act_nack() );
12359 execute( TC_dyn_pdch_osmo_act_deact() );
12360 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010012361 execute( TC_dyn_ts_sdcch8_act_deact() );
12362 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
12363 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
12364 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012365
Stefan Sperling0796a822018-10-05 13:01:39 +020012366 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020012367 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020012368
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010012369 /* Power control related */
12370 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020012371 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020012372
12373 /* MSC pooling */
12374 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
12375 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
12376 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
12377 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
12378 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12379 execute( TC_mscpool_L3Compl_on_1_msc() );
12380 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
12381 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
12382 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
12383 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
12384 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
12385 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
12386 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
12387 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
12388 execute( TC_mscpool_paging_and_response_imsi() );
12389 execute( TC_mscpool_paging_and_response_tmsi() );
12390 execute( TC_mscpool_no_allow_attach_round_robin() );
12391 execute( TC_mscpool_no_allow_attach_valid_nri() );
12392 }
12393
Harald Welte99f3ca02018-06-14 13:40:29 +020012394 execute( TC_early_conn_fail() );
12395 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020012396 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012397
Philipp Maier783681c2020-07-16 16:47:06 +020012398 /* Emergency call handling (deny / allow) */
12399 execute( TC_assignment_emerg_setup_allow() );
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +010012400 execute( TC_assignment_emerg_setup_allow_imei() );
Philipp Maier783681c2020-07-16 16:47:06 +020012401 execute( TC_assignment_emerg_setup_deny_msc() );
12402 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020012403 execute( TC_emerg_premption() );
12404
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070012405 /* Frequency hopping parameters handling */
12406 execute( TC_fh_params_chan_activ() );
12407 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070012408 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070012409 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070012410 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012411
12412 if (mp_enable_lcs_tests) {
12413 execute( TC_lcs_loc_req_for_active_ms() );
12414 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
12415 execute( TC_lcs_loc_req_for_idle_ms() );
12416 execute( TC_lcs_loc_req_no_subscriber() );
12417 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
12418 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
12419 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
12420 execute( TC_cm_service_during_lcs_loc_req() );
12421 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020012422 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020012423 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() );
12424 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012425 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000012426
12427 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000012428
12429 execute( TC_refuse_chan_act_to_vamos() );
12430 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000012431
12432 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020012433
12434 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020012435
12436 execute( TC_imm_ass_post_chan_ack() );
12437 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020012438 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020012439 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020012440 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020012441
12442 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012443
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020012444 execute( TC_ratectr_all_available_allocated() );
12445 execute( TC_ratectr_all_available_allocated_dyn() );
12446
Neels Hofmeyrb7581872021-11-07 14:02:49 +010012447 execute( TC_cm_serv_rej() );
12448
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012449 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012450
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012451 /* Channel allocator */
12452 execute( TC_chan_alloc_algo_ascending() );
12453 execute( TC_chan_alloc_algo_descending() );
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012454 execute( TC_chan_alloc_algo_ass_dynamic() );
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012455
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012456 /* MGW pool */
12457 /* TODO: this conditional canbe dropped once osmo-bsc >1.10.0 is released: */
12458 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
12459 execute( TC_mgwpool_all_used() );
12460 execute( TC_mgwpool_blocked_not_used() );
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012461 execute( TC_mgwpool_pin_bts() );
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012462 }
12463
Oliver Smithc9a5f532022-10-21 11:32:23 +020012464 execute( TC_ho_meas_rep_multi_band() );
12465
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012466 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
12467 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
12468 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010012469}
12470
12471}