blob: b9182e3c4177ffb42ebfbd532e7d0e64752caeda [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: */
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01001304 f_vty_enter_cfg_bts(BSCVTY, bts_idx);
1305 if (g_osmux_enabled_bts) {
1306 f_vty_transceive(BSCVTY, "osmux on");
1307 } else {
1308 f_vty_transceive(BSCVTY, "osmux off");
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001309 }
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01001310 f_vty_transceive(BSCVTY, "end");
Harald Welte28d943e2017-11-25 15:00:50 +01001311}
1312
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001313function f_init_bts_and_check_sysinfo(integer bts_idx := 0,
1314 integer trx_num := NUM_TRX_CFG,
1315 boolean handler_mode := false,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001316 template SystemInformationConfig expect_si)
1317runs on test_CT {
1318 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1319
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001320 f_init_bts(bts_idx, trx_num, handler_mode);
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001321
1322 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1323 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1324 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1325 */
1326 f_sleep(5.0);
1327 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1328
1329 deactivate(sysinfo);
1330
1331 if (match(g_system_information[bts_idx], expect_si)) {
1332 setverdict(pass);
1333 } else {
1334 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1335 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1336 setverdict(fail, "received SI does not match expectations");
1337 return;
1338 }
1339}
1340
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001341/* expect to receive a RSL message matching a specified template on a given BTS / TRX */
1342function f_exp_ipa_rx(template (present) RSL_Message t_rx,
1343 BtsTrxIdx idx := {0, 0},
1344 float Tval := 2.0)
Harald Welteae026692017-12-09 01:03:01 +01001345runs on test_CT return RSL_Message {
1346 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001347 timer T := Tval;
Harald Welteae026692017-12-09 01:03:01 +01001348
1349 T.start;
1350 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001351 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001352 T.stop;
1353 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001354 [] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001355 [] T.timeout {
1356 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001357 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001358 }
Harald Welteae026692017-12-09 01:03:01 +01001359 }
1360 return rx_rsl_ud.rsl;
1361}
1362
Harald Welte21b46bd2017-12-17 19:46:32 +01001363/* helper function to transmit RSL on a given BTS/stream */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001364function f_ipa_tx(template (value) RSL_Message t_tx,
1365 BtsTrxIdx idx := {0, 0},
1366 IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001367runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001368 IPA_RSL[idx.bts][idx.trx].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001369}
1370
1371
Harald Welte4003d112017-12-09 22:35:39 +01001372/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001373testcase TC_chan_act_noreply() runs on test_CT {
1374 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001375 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001376
Harald Welte89d42e82017-12-17 16:42:41 +01001377 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001378
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001379 f_ipa_tx(ts_RSL_CHAN_RQD('23'O, 23));
1380 rsl_unused := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001381 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001382}
1383
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001384const CounterNameVals counternames_bts_chreq := {
1385 { "chreq:total", 0 },
1386 { "chreq:attempted_emerg", 0 },
1387 { "chreq:attempted_call", 0 },
1388 { "chreq:attempted_location_upd", 0 },
1389 { "chreq:attempted_pag", 0 },
1390 { "chreq:attempted_pdch", 0 },
1391 { "chreq:attempted_other", 0 },
1392 { "chreq:attempted_unknown", 0 },
1393 { "chreq:successful", 0 },
1394 { "chreq:successful_emerg", 0 },
1395 { "chreq:successful_call", 0 },
1396 { "chreq:successful_location_upd", 0 },
1397 { "chreq:successful_pag", 0 },
1398 { "chreq:successful_pdch", 0 },
1399 { "chreq:successful_other", 0 },
1400 { "chreq:successful_unknown", 0 },
1401 { "chreq:no_channel", 0 },
1402 { "chreq:max_delay_exceeded", 0 }
1403};
1404
1405/* verify the "chreq:*" counters */
1406private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1407{
1408 var GsmFrameNumber fn := 23;
1409
1410 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1411
1412 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001413 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn));
1414 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001415 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1416
1417 f_ctrs_bts_add(0, "chreq:total");
1418 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1419 f_ctrs_bts_verify();
1420
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001421 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1422 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001423
1424 f_ctrs_bts_add(0, "chreq:successful");
1425 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1426 f_ctrs_bts_verify();
1427
1428 /* test is done, release RSL Conn Fail Ind to clean up */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001429 f_ipa_tx(ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1430 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
1431 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001432 f_sleep(1.0);
1433}
1434
Harald Welte4003d112017-12-09 22:35:39 +01001435testcase TC_chan_act_counter() runs on test_CT {
1436 var BSSAP_N_UNITDATA_ind ud_ind;
1437 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001438 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001439
Harald Welte89d42e82017-12-17 16:42:41 +01001440 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001441
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001442 f_vty_allow_emerg_bts(true, 0);
1443
1444 f_ctrs_bts_init(1, counternames_bts_chreq);
1445
1446 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1447 f_chan_act_counter('a3'O, "emerg");
1448
1449 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1450 f_chan_act_counter('43'O, "call");
1451
1452 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1453 f_chan_act_counter('03'O, "location_upd");
1454
1455 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1456 f_chan_act_counter('23'O, "pag");
1457 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1458 f_chan_act_counter('33'O, "pag");
1459
1460 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1461 /* no PCU, so PDCH not allowed. Skip this test for now. */
1462 /* f_chan_act_counter('7b'O, "pdch"); */
1463
1464 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1465 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001466
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001467 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001468}
1469
Harald Welteae026692017-12-09 01:03:01 +01001470/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001471private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001472 var RSL_Message rx_rsl;
1473
Harald Welteae026692017-12-09 01:03:01 +01001474 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001475 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001476
1477 /* expect BSC to disable the channel again if there's no RLL EST IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001478 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := T3101_MAX);
Harald Welteae026692017-12-09 01:03:01 +01001479
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001480 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001481}
1482
Philipp Maier9c60a622020-07-09 15:08:46 +02001483/* Normal variant */
1484testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001485 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001486 f_TC_chan_act_ack_noest();
1487}
1488
1489/* Emergency call variant */
1490testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1491 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001492 f_init(1);
1493 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001494 f_TC_chan_act_ack_noest(ra := 'A5'O);
1495}
1496
Philipp Maier606f07d2020-08-12 17:21:58 +02001497/* Emergency call variant, but emergency calls are not allowed */
1498testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1499 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1500
1501 var RSL_Message rx_rsl;
1502 var GsmRrMessage rr;
1503
1504 f_init(1);
1505 f_vty_allow_emerg_bts(false, 0);
1506
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001507 IPA_RSL[0][0].clear;
1508 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier606f07d2020-08-12 17:21:58 +02001509
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001510 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Philipp Maier606f07d2020-08-12 17:21:58 +02001511 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1512 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1513 setverdict(pass);
1514 } else {
1515 setverdict(fail, "immediate assignment not rejected");
1516 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001517
1518 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001519}
1520
Harald Welteae026692017-12-09 01:03:01 +01001521/* Test behavior if MSC never answers to CR */
1522testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001523 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1524 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001525 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001526 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001527 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001528
Harald Welte89d42e82017-12-17 16:42:41 +01001529 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001530
1531 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001532 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001533
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001534 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001535
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001536 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload)));
Harald Welteae026692017-12-09 01:03:01 +01001537
1538 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001539 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001540 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001541 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001542}
1543
1544/* Test behavior if MSC answers with CREF to CR */
1545testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1546 var BSSAP_N_CONNECT_ind rx_c_ind;
1547 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001548 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001549
Harald Welte89d42e82017-12-17 16:42:41 +01001550 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001551
1552 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001553 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001554
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001555 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001556
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001557 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Harald Welteae026692017-12-09 01:03:01 +01001558 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1559
1560 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001561 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001562 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001563}
1564
Harald Welte618ef642017-12-14 14:58:20 +01001565/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1566testcase TC_chan_act_nack() runs on test_CT {
1567 var RSL_Message rx_rsl;
1568 var integer chact_nack;
1569
Harald Welte89d42e82017-12-17 16:42:41 +01001570 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001571
1572 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1573
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001574 f_ipa_tx(ts_RSL_CHAN_RQD('33'O, 33));
1575 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte618ef642017-12-14 14:58:20 +01001576 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1577
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001578 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte618ef642017-12-14 14:58:20 +01001579
1580 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1581 f_sleep(0.5);
1582
1583 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1584
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001585 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001586}
1587
Harald Welte799c97b2017-12-14 17:50:30 +01001588/* Test for channel exhaustion due to RACH overload */
1589testcase TC_chan_exhaustion() runs on test_CT {
1590 var ASP_RSL_Unitdata rsl_ud;
1591 var integer i;
1592 var integer chreq_total, chreq_nochan;
1593
Harald Welte89d42e82017-12-17 16:42:41 +01001594 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001595
1596 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1597 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1598
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001599 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001600 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1601 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001602 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 +01001603 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001604 }
1605
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001606 IPA_RSL[0][0].clear;
Harald Welte799c97b2017-12-14 17:50:30 +01001607
Harald Weltedd8cbf32018-01-28 12:07:52 +01001608 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001609 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001610
1611 /* now expect additional channel activations to fail */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001612 f_ipa_tx(ts_RSL_CHAN_RQD('42'O, 42));
Harald Welte799c97b2017-12-14 17:50:30 +01001613
1614 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001615 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001616 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1617 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001618 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001619 var GsmRrMessage rr;
1620 /* match on IMM ASS REJ */
1621 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1622 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1623 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001624 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001625 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1626 chreq_nochan+1);
1627 setverdict(pass);
1628 } else {
1629 repeat;
1630 }
1631 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001632 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte799c97b2017-12-14 17:50:30 +01001633 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001634 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001635}
1636
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001637/* Test channel deactivation due to silence from MS */
1638testcase TC_chan_deact_silence() runs on test_CT {
1639 var RslChannelNr chan_nr;
1640
1641 f_init(1);
1642
1643 /* Request for a dedicated channel */
1644 chan_nr := f_chreq_act_ack('23'O);
1645
1646 /* Wait some time until the channel is released */
1647 f_sleep(2.0);
1648
1649 /* Expect CHANnel RELease */
1650 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001651 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001652 log("Received CHANnel RELease");
1653 setverdict(pass);
1654 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001655 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001656 /* See OS#3709, OsmoBSC should not send Immediate
1657 * Assignment Reject since a dedicated channel was
1658 * already allocated, and Immediate Assignment was
1659 * already sent. */
1660 setverdict(fail, "Unexpected Immediate Assignment!");
1661 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001662 [] IPA_RSL[0][0].receive {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001663 setverdict(fail, "Unexpected RSL message!");
1664 }
1665 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001666 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001667}
1668
Harald Weltecfe2c962017-12-15 12:09:32 +01001669/***********************************************************************
1670 * Assignment Testing
1671 ***********************************************************************/
1672
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001673/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1674 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001675testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001676 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001677
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001678 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1679 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001680 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001681 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001682}
1683
Harald Welte16a4adf2017-12-14 18:54:01 +01001684/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001685testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001686 var BSSAP_N_CONNECT_ind rx_c_ind;
1687 var RSL_Message rx_rsl;
1688 var DchanTuple dt;
1689
Harald Welte89d42e82017-12-17 16:42:41 +01001690 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001691
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001692 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001693 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001694 /* send assignment without AoIP IEs */
1695 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1696 } else {
Pau Espin Pedrol35609792023-01-03 16:56:59 +01001697 /* Send assignment without CIC in IPA case */
Harald Welte17b27da2018-05-25 20:33:53 +02001698 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1699 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1700 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1701 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001702 alt {
1703 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1704 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1705 }
Harald Welte235ebf12017-12-15 14:18:16 +01001706 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001707 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1708 setverdict(pass);
1709 }
1710 [] BSSAP.receive { repeat; }
1711 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001712 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001713 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001714}
1715
Harald Welteed848512018-05-24 22:27:58 +02001716/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001717function 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 +02001718 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001719 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001720 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001721 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001722 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001723 if (osmux_enabled) {
1724 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1725 } else {
1726 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1727 }
Harald Welteed848512018-05-24 22:27:58 +02001728 } else {
1729 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001730 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001731 }
1732 return ass_cmd;
1733}
1734
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001735function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001736 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001737 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1738 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001739 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001740
1741 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1742 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001743 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1744 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001745 if (ispresent(enc)) {
1746 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001747 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1748 if (ispresent(v_enc.enc_alg_chosen)) {
1749 chosenEncryptionAlgorithm := valueof(
1750 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1751 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1752 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001753 if (ispresent(v_enc.enc_kc128)) {
1754 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1755 }
1756 }
1757
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001758 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001759 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001760 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001761 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1762 cell_id_source := cell_id_source,
1763 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001764 encryptionInformation := encryptionInformation,
1765 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001766 kC128 := kc128,
1767 /* on AoIP, allow "all" codecs (until we add more concise
1768 * tests) */
1769 codecList := ts_BSSMAP_IE_CodecList(
1770 {ts_CodecAMR_F, ts_CodecAMR_H,
1771 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001772 } else {
1773 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001774 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1775 cell_id_source := cell_id_source,
1776 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001777 encryptionInformation := encryptionInformation,
1778 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1779 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001780 }
1781 return ho_req;
1782}
1783
Harald Welteed848512018-05-24 22:27:58 +02001784/* generate an assignment complete template for either AoIP or SCCPlite */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001785function f_gen_exp_compl(integer bssap_idx := 0)
1786runs on MSC_ConnHdlr return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001787 var template PDU_BSSAP exp_compl;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001788 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001789 var template BSSMAP_IE_Osmo_OsmuxCID exp_osmux_cid := omit;
1790 if (g_pars.use_osmux_cn) {
1791 var template (present) INT1 exp_cid := ?;
1792 if (isbound(g_media.mgcp_conn[0].local_osmux_cid) and isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1793 exp_cid := (g_media.mgcp_conn[0].local_osmux_cid, g_media.mgcp_conn[1].local_osmux_cid);
1794 } else if (isbound(g_media.mgcp_conn[0].local_osmux_cid)) {
1795 exp_cid := g_media.mgcp_conn[0].local_osmux_cid;
1796 } else if (isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1797 exp_cid := g_media.mgcp_conn[1].local_osmux_cid;
1798 }
1799 exp_osmux_cid := tr_OsmuxCID(exp_cid);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001800 }
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001801 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, exp_osmux_cid);
Harald Welteed848512018-05-24 22:27:58 +02001802 } else {
1803 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001804 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit, omit);
Harald Welteed848512018-05-24 22:27:58 +02001805 }
1806 return exp_compl;
1807}
1808
Harald Welte235ebf12017-12-15 14:18:16 +01001809/* Run everything required up to sending a caller-specified assignment command and expect response */
1810function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001811runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001812 var BSSAP_N_CONNECT_ind rx_c_ind;
1813 var RSL_Message rx_rsl;
1814 var DchanTuple dt;
1815
Harald Welte89d42e82017-12-17 16:42:41 +01001816 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001817
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001818 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte235ebf12017-12-15 14:18:16 +01001819 /* send assignment without AoIP IEs */
1820 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1821 alt {
1822 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1823 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1824 setverdict(pass);
1825 } else {
1826 setverdict(fail, fail_text);
1827 }
1828 }
1829 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1830 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1831 setverdict(pass);
1832 } else {
1833 setverdict(fail, fail_text);
1834 }
1835 }
1836 [] BSSAP.receive { repeat; }
1837 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001838 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001839}
1840testcase TC_assignment_csd() runs on test_CT {
1841 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001842 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001843 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1844 //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 +01001845 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1846 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001847 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001848}
1849
1850testcase TC_assignment_ctm() runs on test_CT {
1851 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001852 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001853 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1854 //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 +01001855 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1856 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001857 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001858}
1859
Harald Welte4003d112017-12-09 22:35:39 +01001860type record DchanTuple {
1861 integer sccp_conn_id,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001862 RslChannelNr rsl_chan_nr,
1863 BtsTrxIdx idx
Harald Weltea5d2ab22017-12-09 14:21:42 +01001864}
1865
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001866type record of DchanTuple DchanTuples;
1867
Harald Welted6939652017-12-13 21:02:46 +01001868/* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001869private function f_chreq_act_ack(OCT1 ra := '23'O,
1870 GsmFrameNumber fn := 23,
1871 BtsTrxIdx idx := {0, 0})
Harald Welted6939652017-12-13 21:02:46 +01001872runs on test_CT return RslChannelNr {
1873 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001874 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
1875 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Harald Welted6939652017-12-13 21:02:46 +01001876 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001877 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10), idx);
1878 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Harald Welted6939652017-12-13 21:02:46 +01001879 return chan_nr;
1880}
1881
Harald Welte4003d112017-12-09 22:35:39 +01001882/* helper function to establish a dedicated channel via BTS and MSC */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001883function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1884 BtsTrxIdx idx := {0, 0})
Harald Welte4003d112017-12-09 22:35:39 +01001885runs on test_CT return DchanTuple {
1886 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001887 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001888
Harald Welte4003d112017-12-09 22:35:39 +01001889 /* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001890 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn, idx);
Harald Welte4003d112017-12-09 22:35:39 +01001891
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001892 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 +01001893
1894 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1895 dt.sccp_conn_id := rx_c_ind.connectionId;
1896 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1897
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001898 dt.idx := idx;
Harald Welte4003d112017-12-09 22:35:39 +01001899 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001900}
1901
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001902/* 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 +06001903function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1904 BtsTrxIdx idx := {0, 0})
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001905runs on test_CT return DchanTuple {
1906 var BSSAP_N_CONNECT_ind rx_c_ind;
1907 var DchanTuple dt;
1908
1909 /* Send CHAN RQD */
1910 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001911 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001912
1913 /* The dyn TS first deactivates PDCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001914 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 +02001915 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001916 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001917
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001918 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001919 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1920
1921 /* Now activates the signalling channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001922 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10), idx);
1923 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001924
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001925 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 +02001926
1927 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1928 dt.sccp_conn_id := rx_c_ind.connectionId;
1929 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1930
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001931 dt.idx := idx;
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001932 return dt;
1933}
1934
Harald Welte641fcbe2018-06-14 10:58:35 +02001935/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001936private function f_exp_chan_rel_and_clear(DchanTuple dt)
1937runs on test_CT {
Harald Welte641fcbe2018-06-14 10:58:35 +02001938 var RSL_Message rx_rsl;
1939 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001940 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 +02001941 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001942 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), dt.idx);
Harald Welte641fcbe2018-06-14 10:58:35 +02001943
1944 /* expect Clear Complete from BSC */
1945 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1946
1947 /* MSC disconnects as instructed. */
1948 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1949}
1950
Harald Welte4003d112017-12-09 22:35:39 +01001951/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1952testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001953 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001954 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001955
Harald Welte89d42e82017-12-17 16:42:41 +01001956 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001957
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001958 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01001959
1960 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001961 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Harald Welte4003d112017-12-09 22:35:39 +01001962
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001963 /* expect Clear Request on MSC side */
1964 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1965
1966 /* Instruct BSC to clear channel */
1967 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1968 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1969
Harald Welte4003d112017-12-09 22:35:39 +01001970 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001971 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001972
1973 /* wait for SCCP emulation to do its job */
1974 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001975
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001976 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001977}
1978
1979/* Test behavior of channel release after CONN FAIL IND from BTS */
1980testcase TC_chan_rel_conn_fail() runs on test_CT {
1981 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001982 var DchanTuple dt;
1983
Harald Welte89d42e82017-12-17 16:42:41 +01001984 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001985
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001986 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01001987
Vadim Yanitskiy01d0a902022-12-14 22:41:42 +07001988 /* Sending CONN FAIL IND immediately may trigger a race condition.
1989 * Give the BSC some time to process a new SCCP connection (OS#5823). */
1990 f_sleep(0.2);
1991
Harald Welte4003d112017-12-09 22:35:39 +01001992 /* simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001993 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001994 /* TODO: different cause values? */
1995
Harald Welte4003d112017-12-09 22:35:39 +01001996 /* expect Clear Request from BSC */
1997 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1998
1999 /* Instruct BSC to clear channel */
2000 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
2001 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2002
Harald Welte6ff76ea2018-01-28 13:08:01 +01002003 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002004 f_exp_chan_rel_and_clear(dt);
Harald Welte4003d112017-12-09 22:35:39 +01002005
2006 /* wait for SCCP emulation to do its job */
2007 f_sleep(1.0);
2008
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002009 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002010}
2011
Harald Welte99f3ca02018-06-14 13:40:29 +02002012/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
2013/* See also https://www.osmocom.org/issues/3182 */
2014testcase TC_early_conn_fail() runs on test_CT {
2015 var RSL_Message rx_rsl;
2016 var DchanTuple dt;
2017
2018 f_init(1);
2019
2020 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02002021 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02002022
2023 /* BTS->BSC: simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002024 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002025
2026 /* BTS->BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002027 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002028
2029 /* BTS<-BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002030 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002031
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002032 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002033}
2034
2035/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
2036/* See also https://www.osmocom.org/issues/3182 */
2037testcase TC_late_conn_fail() runs on test_CT {
2038 var RSL_Message rx_rsl;
2039 var DchanTuple dt;
2040
2041 f_init(1);
2042
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002043 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99f3ca02018-06-14 13:40:29 +02002044
2045 /* BSC<-MSC: Instruct BSC to clear connection */
2046 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
2047
2048 /* BTS->BSC: expect BSC to deactivate SACCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002049 rx_rsl := f_exp_ipa_rx(tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002050
2051 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002052 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002053
2054 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002055 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002056 /* BTS->BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002057 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002058
2059 /* BSC->MSC: expect Clear Complete from BSC */
2060 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2061
2062 /* BSC<-MSC: MSC disconnects as requested. */
2063 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2064
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002065 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002066}
2067
Oliver Smithaf03bef2021-08-24 15:34:51 +02002068private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
2069 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
2070 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2071
2072 f_statsd_reset();
2073
2074 /* Establish SDCCH */
2075 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
2076 f_establish_fully(ass_cmd, exp_fail);
2077
2078 /* Expect stats to be 0 */
2079 var StatsDExpects expect := {
2080 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
2081 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
2082 };
2083 f_statsd_expect(expect);
2084
2085 /* Simulate CONN FAIL IND on SDCCH */
2086 RSL.send(ts_ASP_RSL_UD(
2087 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2088 IPAC_PROTO_RSL_TRX0));
2089
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002090 f_sleep(1.0);
2091
Oliver Smithaf03bef2021-08-24 15:34:51 +02002092 /* Expect stats to be 1 */
2093 expect := {
2094 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2095 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2096 };
2097 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002098 BSSAP.receive(tr_BSSMAP_ClearRequest);
2099 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002100}
2101testcase TC_stats_conn_fail() runs on test_CT {
2102 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2103 var MSC_ConnHdlr vc_conn;
2104
2105 f_init(1, true);
2106 f_sleep(1.0);
2107
2108 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2109 vc_conn.done;
2110
2111 f_shutdown_helper();
2112}
2113
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002114function f_expect_chan_rel(RslChannelNr rsl_chan_nr,
2115 BtsTrxIdx idx := {0, 0},
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002116 boolean expect_deact_sacch := true,
2117 boolean expect_rr_chan_rel := true,
2118 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002119 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002120 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002121 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002122 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002123
2124 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002125 var boolean got_deact_sacch := false;
2126 var boolean got_rr_chan_rel := false;
2127 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002128 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002129 var RSL_IE_Body l3_ie;
2130 var PDU_ML3_NW_MS l3;
2131 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002132 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2133 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002134 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002135 [] 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 +01002136 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002137 repeat;
2138 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002139 [] 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 +01002140 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002141
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002142 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2143 setverdict(fail, "cannot find L3");
2144 mtc.stop;
2145 }
2146 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2147
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002148 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002149 var CellSelIndValue cells := dec_CellSelIndValue(
2150 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2151
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002152 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2153 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002154 setverdict(pass);
2155 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002156 log("EXPECTED CELLS: ", expect_cells);
2157 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002158 }
2159 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002160
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002161 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2162 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2163 if (match(got_cause, expect_rr_cause)) {
2164 setverdict(pass);
2165 } else {
2166 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2167 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002168 }
Harald Welte99787102019-02-04 10:41:36 +01002169 repeat;
2170 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002171 [] 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 +01002172 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002173 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002174 if (handle_rll_rel) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002175 f_ipa_tx(ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002176 }
Harald Welte91d54a52018-01-28 15:35:07 +01002177 repeat;
2178 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002179 [] 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 +01002180 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002181 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
Harald Welte91d54a52018-01-28 15:35:07 +01002182 }
2183 /* ignore any user data */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002184 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002185 repeat;
2186 }
2187 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002188
2189 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2190 " got_rll_rel_req=", got_rll_rel_req);
2191
2192 if (expect_deact_sacch != got_deact_sacch) {
2193 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2194 }
2195 if (expect_rr_chan_rel != got_rr_chan_rel) {
2196 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2197 }
2198 if (expect_rll_rel_req != got_rll_rel_req) {
2199 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2200 }
Harald Welte91d54a52018-01-28 15:35:07 +01002201}
2202
Harald Welte4003d112017-12-09 22:35:39 +01002203/* Test behavior of channel release after hard Clear Command from MSC */
2204testcase TC_chan_rel_hard_clear() runs on test_CT {
2205 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002206 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002207
Harald Welte89d42e82017-12-17 16:42:41 +01002208 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002209
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002210 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01002211
2212 /* Instruct BSC to clear channel */
2213 var BssmapCause cause := 0;
2214 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2215
2216 /* expect Clear Complete from BSC on A */
2217 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2218 /* release the SCCP connection */
2219 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2220 }
2221
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002222 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002223 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002224}
2225
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002226function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2227 var BSSAP_N_DATA_ind rx_di;
2228 var DchanTuple dt;
2229
2230 f_init(1);
2231
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002232 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002233 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2234 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2235 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2236
2237 /* Instruct BSC to clear channel */
2238 var BssmapCause cause := 0;
2239 if (tx_csfb_ind) {
2240 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2241 } else {
2242 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2243 }
2244
2245 /* expect Clear Complete from BSC on A */
2246 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2247 /* release the SCCP connection */
2248 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2249 }
2250
2251 /* 1 neighbor is added by default in osmo-bts.cfg and
2252 SystemInformationConfig_default, use that: */
2253 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2254
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002255 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 +02002256 f_shutdown_helper();
2257}
2258
2259/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2260 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2261 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2262 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2263 Indicator or not shouldn't matter at all. */
2264testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2265 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2266}
2267
2268/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2269 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2270 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2271 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2272testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2273 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2274}
2275
2276/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2277 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2278 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2279 CSFB Indicator should not be used anymore, and hence, there should be no
2280 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2281 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002282testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2283 var BSSAP_N_DATA_ind rx_di;
2284 var DchanTuple dt;
2285
2286 f_init(1);
2287
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002288 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99787102019-02-04 10:41:36 +01002289
2290 /* Instruct BSC to clear channel */
2291 var BssmapCause cause := 0;
2292 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2293
2294 /* expect Clear Complete from BSC on A */
2295 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2296 /* release the SCCP connection */
2297 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2298 }
2299
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002300 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002301 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002302}
2303
Harald Welted8c36cd2017-12-09 23:05:31 +01002304/* Test behavior of channel release after hard RLSD from MSC */
2305testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002306 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002307
Harald Welte89d42e82017-12-17 16:42:41 +01002308 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002309
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002310 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welted8c36cd2017-12-09 23:05:31 +01002311
2312 /* release the SCCP connection */
2313 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2314
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002315 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002316 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002317}
2318
Harald Welte550daf92018-06-11 19:22:13 +02002319/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2320testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2321 var DchanTuple dt;
2322
2323 f_init(1);
2324
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002325 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte550daf92018-06-11 19:22:13 +02002326
2327 /* release the SCCP connection */
2328 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2329
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002330 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002331 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002332}
2333
Harald Welte85804d42017-12-10 14:11:58 +01002334/* Test behavior of channel release after BSSMAP RESET from MSC */
2335testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002336 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002337
Harald Welte89d42e82017-12-17 16:42:41 +01002338 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002339
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002340 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte85804d42017-12-10 14:11:58 +01002341
2342 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002343 IPA_RSL[0][0].clear;
Harald Welte85804d42017-12-10 14:11:58 +01002344
2345 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002346 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 +01002347 interleave {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002348 [] 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 +01002349 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2350 }
2351
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002352 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002353 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002354}
2355
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002356/* Verify T(iar) triggers and releases the channel */
2357testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2358 var DchanTuple dt;
2359
2360 /* Set T(iar) in BSC low enough that it will trigger before other side
2361 has time to keep alive with a T(ias). Keep recommended ratio of
2362 T(iar) >= T(ias)*2 */
2363 g_bsc_sccp_timer_ias := 2;
2364 g_bsc_sccp_timer_iar := 5;
2365
2366 f_init(1);
2367
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002368 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002369 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002370 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002371}
2372
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002373private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2374 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002375runs on test_CT
2376{
2377 var DchanTuple dt;
2378
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002379 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002380 var BssmapCause cause := 0;
2381 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2382 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2383 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2384 }
2385
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002386 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 +02002387}
2388
2389/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2390testcase TC_chan_rel_rr_cause() runs on test_CT {
2391 f_init(1);
2392
2393 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2394 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2395 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2396 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2397 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2398 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002399
2400 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002401}
2402
Harald Welte5cd20ed2017-12-13 21:03:20 +01002403/* Test behavior if RSL EST IND for non-active channel */
2404testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2405 timer T := 2.0;
2406
Harald Welte89d42e82017-12-17 16:42:41 +01002407 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002408
Harald Welte5cd20ed2017-12-13 21:03:20 +01002409 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002410 var octetstring l3_payload := gen_l3_valid_payload();
2411 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002412
2413 T.start;
2414 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002415 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002416 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2417 }
2418 [] BSSAP.receive {}
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002419 [] IPA_RSL[0][0].receive {}
Harald Welte5cd20ed2017-12-13 21:03:20 +01002420 [] T.timeout {}
2421 }
2422
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002423 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002424}
2425
2426/* Test behavior if RSL EST IND for invalid SAPI */
2427testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2428 var RslChannelNr chan_nr;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002429 var octetstring l3_payload;
Harald Welte5cd20ed2017-12-13 21:03:20 +01002430
Harald Welte89d42e82017-12-17 16:42:41 +01002431 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002432
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002433 chan_nr := f_chreq_act_ack();
2434 l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002435
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002436 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002437
2438 timer T := 2.0;
2439 T.start;
2440 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002441 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002442 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2443 }
2444 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002445 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002446 [] T.timeout {}
2447 }
2448
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002449 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002450}
2451
2452/* Test behavior if RSL EST IND for invalid SAPI */
2453testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2454 timer T := 2.0;
2455
Harald Welte89d42e82017-12-17 16:42:41 +01002456 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002457
2458 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002459 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002460
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002461 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002462
2463 T.start;
2464 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002465 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002466 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2467 }
2468 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002469 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002470 [] T.timeout {}
2471 }
2472
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002473 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002474}
2475
2476/* Test behavior if RSL EST IND for invalid SACCH */
2477testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2478 timer T := 2.0;
2479
Harald Welte89d42e82017-12-17 16:42:41 +01002480 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002481
2482 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002483 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002484
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002485 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002486
2487 T.start;
2488 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002489 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002490 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2491 }
2492 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002493 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002494 [] T.timeout {}
2495 }
2496
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002497 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002498}
2499
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002500/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2501private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2502 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2503 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2504
2505 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2506 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2507
2508 f_establish_fully(ass_cmd, exp_compl);
2509
2510 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2511 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2512 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2513 BSSAP.receive(PDU_BSSAP:{
2514 discriminator := '1'B,
2515 spare := '0000000'B,
2516 dlci := 'C3'O,
2517 lengthIndicator := ?,
2518 pdu := { dtap := '0904'O }
2519 });
2520
2521 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2522 for (var integer i := 0; i < 32; i := i + 1) {
2523 var octetstring l3 := '09'O & f_rnd_octstring(14);
2524 var template (value) RslLinkId link_id;
2525 var template (value) OCT1 dlci;
2526
2527 if (i mod 2 == 0) {
2528 /* SAPI0 on FACCH or SDCCH */
2529 link_id := ts_RslLinkID_DCCH(0);
2530 dlci := '80'O;
2531 } else {
2532 /* SAPI3 on SACCH */
2533 link_id := ts_RslLinkID_SACCH(3);
2534 dlci := 'C3'O;
2535 }
2536
2537 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002538 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002539 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002540 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002541 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002542 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002543}
2544testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2545 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2546 var MSC_ConnHdlr vc_conn;
2547
2548 f_init(1, true);
2549 f_sleep(1.0);
2550
2551 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2552 vc_conn.done;
2553
2554 f_shutdown_helper();
2555}
2556
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002557private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002558 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002559 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002560 float T_val := 2.0)
2561runs on test_CT {
2562 var BSSAP_N_DATA_ind rx_di;
2563 timer T;
2564
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002565 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2566 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002567
2568 T.start(T_val);
2569 alt {
2570 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2571 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2572 if (not match(rx_cause, tr_cause)) {
2573 setverdict(fail, "Rx unexpected Cause IE: ",
2574 rx_cause, " vs expected ", tr_cause);
2575 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002576
2577 /* Who ever on the earth decided to define this field as two separate bits?!? */
2578 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2579 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2580 if (not match(rx_cc, cc)) {
2581 setverdict(fail, "Rx unexpected Control Channel type: ",
2582 rx_cc, " vs expected ", cc);
2583 }
2584
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002585 setverdict(pass);
2586 }
2587 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2588 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2589 }
2590 [] T.timeout {
2591 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2592 }
2593 }
2594}
2595
2596/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2597testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002598 var RSL_Message rx_rsl;
2599 var DchanTuple dt;
2600
2601 f_init(1);
2602
2603 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002604 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002605
2606 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002607 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 +07002608 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002609 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 +07002610
2611 /* MS sends unexpected RELease INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002612 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002613 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2614 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2615
2616 /* Clean up the connection */
2617 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002618 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002619
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002620 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002621}
2622
2623/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2624testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002625 var RSL_Message rx_rsl;
2626 var DchanTuple dt;
2627
2628 f_init(1);
2629
2630 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002631 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002632
2633 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002634 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 +07002635 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002636 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 +07002637
2638 /* BTS sends unexpected ERROR INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002639 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002640 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2641 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2642
2643 /* Clean up the connection */
2644 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002645 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002646
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002647 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002648}
2649
2650/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2651testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002652 var RSL_Message rx_rsl;
2653 var DchanTuple dt;
2654
2655 f_init(1);
2656
2657 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002658 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002659
2660 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002661 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 +07002662 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002663 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 +07002664
2665 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2666 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2667
2668 /* Clean up the connection */
2669 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002670 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002671
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002672 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002673}
2674
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002675/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2676testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002677 var RSL_Message rx_rsl;
2678 var DchanTuple dt;
2679
2680 f_init(1);
2681
2682 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002683 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002684
2685 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002686 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 +07002687 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002688 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 +07002689
2690 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002691 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002692 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002693
2694 /* Clean up the connection */
2695 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002696 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002697
2698 f_shutdown_helper();
2699}
2700
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002701testcase TC_si_default() runs on test_CT {
2702 f_init(0);
2703 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002704 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002705}
Harald Welte4003d112017-12-09 22:35:39 +01002706
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002707/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2708 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2709private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2710{
2711 select (earfcn_index) {
2712 case (0) {
2713 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2714 return 111;
2715 }
2716 case (1) {
2717 return 1;
2718 }
2719 case (2) {
2720 return 0;
2721 }
2722 case (3) {
2723 return 65535;
2724 }
2725 case else {
2726 return 23 * (earfcn_index - 3);
2727 }
2728 }
2729}
2730
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002731function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2732 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002733
2734 f_init(0);
2735
2736 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2737 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002738 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2739 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002740 }
2741
2742 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2743
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002744 if (not istemplatekind(expect_cells, "omit")) {
2745 /* Also check that RR Channel Release contains these EARFCNs.
2746 * (copied code from TC_chan_rel_hard_clear_csfb) */
2747 var BSSAP_N_DATA_ind rx_di;
2748 var DchanTuple dt;
2749
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002750 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002751 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2752 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2753 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002754
2755 /* Instruct BSC to clear channel */
2756 var BssmapCause cause := 0;
2757 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2758
2759 /* expect Clear Complete from BSC on A */
2760 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2761 /* release the SCCP connection */
2762 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2763 }
2764
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002765 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002766 }
2767
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002768 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002769 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 +02002770 }
2771}
2772
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002773private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2774{
2775 var template SI2quaterRestOctetsList si2quater := {};
2776 var integer si2quater_count := (count + 2) / 3;
2777
2778 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002779 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002780 var integer index := i / 3;
2781 var integer earfcn_index := i mod 3;
2782 if (index >= lengthof(si2quater)) {
2783 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2784 }
2785 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);
2786 }
2787
2788 return si2quater;
2789}
2790
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002791private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2792{
2793 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2794
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002795 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002796 for (var integer i := 0; i < count; i := i + 1) {
2797 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002798 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002799 }
2800
2801 return tr_CellSelIndValue_EUTRAN(cells);
2802}
2803
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002804private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2805{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002806 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002807 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002808 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2809 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002810}
2811
2812testcase TC_si2quater_2_earfcns() runs on test_CT {
2813 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002814 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002815}
2816
2817testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002818 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002819 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002820}
2821
2822testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002823 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002824 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002825}
2826
2827testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002828 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002829 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002830}
2831
2832testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002833 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002834 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002835}
2836
2837testcase TC_si2quater_12_earfcns() runs on test_CT {
2838 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002839 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002840}
2841
2842testcase TC_si2quater_23_earfcns() runs on test_CT {
2843 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002844 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002845}
2846
2847testcase TC_si2quater_32_earfcns() runs on test_CT {
2848 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002849 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002850}
2851
2852testcase TC_si2quater_33_earfcns() runs on test_CT {
2853 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002854 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002855}
2856
2857testcase TC_si2quater_42_earfcns() runs on test_CT {
2858 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002859 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002860}
2861
2862testcase TC_si2quater_48_earfcns() runs on test_CT {
2863 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002864 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002865}
2866
2867/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2868 * 48 EARFCNs. */
2869testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002870 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002871 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2872 f_init(0);
2873
2874 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002875 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2876 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002877 }
2878
2879 /* The 49th EARFCN no longer fits, expect VTY error */
2880 f_vty_enter_cfg_bts(BSCVTY, 0);
2881 var charstring vty_error;
2882 vty_error := f_vty_transceive_ret(BSCVTY,
2883 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2884 f_vty_transceive(BSCVTY, "end");
2885
2886 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2887 log("Got expected VTY error: ", vty_error);
2888 setverdict(pass);
2889 } else {
2890 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2891 }
2892
2893 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2894
2895 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002896 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 +02002897 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002898 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002899}
2900
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002901private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2902{
2903 var uint8_t count := 0;
2904 for (var integer i := 5; i < 16; i := i + 1) {
2905 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2906 count := count + 1;
2907 }
2908 }
2909 return count;
2910}
2911
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002912private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2913{
2914 var ASP_RSL_Unitdata rx_rsl_ud;
2915 var SystemInformationType1 last_si1;
2916
2917 timer T := 30.0;
2918 T.start;
2919 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002920 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2921 tr_RSL_BCCH_INFO,
2922 tr_RSL_NO_SACCH_FILL,
2923 tr_RSL_SACCH_FILL))) -> value rx_rsl_ud {
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002924 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2925 if (g_system_information[rsl_idx].si1 == omit) {
2926 repeat;
2927 }
2928 last_si1 := g_system_information[rsl_idx].si1;
2929 g_system_information[rsl_idx].si1 := omit;
2930 T.stop;
2931 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002932 [] IPA_RSL[rsl_idx][0].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002933 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2934 }
2935 return last_si1;
2936}
2937
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002938/* verify ACC rotate feature */
2939testcase TC_si_acc_rotate() runs on test_CT {
2940 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002941 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002942 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002943 var uint8_t count;
2944 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2945
2946 f_init(0, guard_timeout := 60.0);
2947
2948 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2949 "access-control-class-rotate 3",
2950 "access-control-class-rotate-quantum 1"});
2951
2952 /* Init and get first sysinfo */
2953 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2954
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002955 for (var integer i:= 0; i < 20; i := i + 1) {
2956 last_si1 := f_recv_next_si1(0);
2957 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002958 count := f_acc09_count_allowed(acc);
2959 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2960
2961 if (count != 3) {
2962 log("RSL: EXPECTED SI ACC len=3");
2963 setverdict(fail, "received SI does not match expectations");
2964 break;
2965 }
2966
2967 for (var integer j := 0; j < 10; j := j + 1) {
2968 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2969 times_allowed[j] := times_allowed[j] + 1;
2970 }
2971 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002972 }
2973
2974 for (var integer j := 0; j < 10; j := j + 1) {
2975 log("ACC", j, " allowed ", times_allowed[j], " times" );
2976 if (j != 5 and times_allowed[j] < 3) {
2977 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2978 } else if (j == 5 and times_allowed[j] > 0) {
2979 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2980 }
2981 }
2982
2983 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2984 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002985 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002986}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002987
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002988/* verify ACC startup ramp+rotate feature */
2989testcase TC_si_acc_ramp_rotate() runs on test_CT {
2990 var template SystemInformationConfig sic := SystemInformationConfig_default;
2991 var SystemInformationType1 last_si1;
2992 var AccessControlClass acc;
2993 var ASP_RSL_Unitdata rx_rsl_ud;
2994 var uint8_t count;
2995 var uint8_t prev_count;
2996 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2997
2998 f_init(0, guard_timeout := 80.0);
2999
3000 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
3001 "access-control-class-rotate 0",
3002 "access-control-class-rotate-quantum 1",
3003 "access-control-class-ramping",
3004 "access-control-class-ramping-step-interval 5",
3005 "access-control-class-ramping-step-size 5"});
3006
3007 /* Init and get first sysinfo */
3008 f_init_bts_and_check_sysinfo(0, expect_si := ?);
3009 last_si1 := g_system_information[0].si1;
3010 acc := last_si1.rach_control.acc;
3011 count := f_acc09_count_allowed(acc);
3012 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
3013 while (count > 0) {
3014 last_si1 := f_recv_next_si1(0);
3015 acc := last_si1.rach_control.acc;
3016 count := f_acc09_count_allowed(acc);
3017 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
3018 }
3019
3020 /* Increase adm subset size, we should see ramping start up */
3021 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
3022 prev_count := 0;
3023 while (true) {
3024 last_si1 := f_recv_next_si1(0);
3025 acc := last_si1.rach_control.acc;
3026 count := f_acc09_count_allowed(acc);
3027 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
3028
3029 if (prev_count > count) {
3030 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
3031 break;
3032 }
3033
3034 if (count == 9) {
3035 break; /* Maximum reached (10 - 1 perm barred), done here */
3036 }
3037
3038 prev_count := count;
3039 }
3040
3041 setverdict(pass);
3042
3043 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
3044 "rach access-control-class 4 allowed",
3045 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003046 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003047}
3048
Harald Welte4003d112017-12-09 22:35:39 +01003049testcase TC_ctrl_msc_connection_status() runs on test_CT {
3050 var charstring ctrl_resp;
3051
Harald Welte89d42e82017-12-17 16:42:41 +01003052 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003053
3054 /* See https://osmocom.org/issues/2729 */
3055 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003056 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01003057}
3058
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003059testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3060 var charstring ctrl_resp;
3061
3062 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003063
3064 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003065 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003066}
3067
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003068/* Verify correct stats on the number of configured and connected MSCs */
3069private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3070 g_pars := f_gen_test_hdlr_pars();
3071 var StatsDExpects expect := {
3072 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3073 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3074 };
3075 f_statsd_expect(expect);
3076}
3077
3078private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3079{
3080 var MSC_ConnHdlr vc_conn;
3081
3082 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3083 f_sleep(1.0);
3084 vc_conn := f_start_handler(tc_fn);
3085 vc_conn.done;
3086
3087 /* Also verify stat exposed on CTRL interface */
3088 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3089 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3090
3091 f_shutdown_helper();
3092}
3093
3094/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3095private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3096 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3097}
3098testcase TC_stat_num_msc_connected_1() runs on test_CT {
3099 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3100}
3101
3102/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3103private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3104 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3105}
3106testcase TC_stat_num_msc_connected_2() runs on test_CT {
3107 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3108}
3109
3110/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3111private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3112 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3113}
3114testcase TC_stat_num_msc_connected_3() runs on test_CT {
3115 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3116}
3117
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003118/* Verify correct stats on the number of configured and connected MSCs */
3119private 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 +06003120 var integer num_trx_connected := 0;
3121 var integer num_trx_total := 0;
3122
3123 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3124 var integer trx_num := c_BtsParams[i].trx_num;
3125 num_trx_total := num_trx_total + trx_num;
3126 if (i < expect_num_bts_connected) {
3127 num_trx_connected := num_trx_connected + trx_num;
3128 }
3129 }
3130
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003131 var StatsDExpects expect := {
3132 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3133 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3134 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003135 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := num_trx_connected, max := num_trx_connected },
3136 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := num_trx_total, max := num_trx_total }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003137 };
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003138
3139 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003140 f_statsd_expect(expect);
3141}
3142
3143private 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 +06003144 var integer num_trx_connected := 0;
3145 var integer num_trx_total := 0;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003146 var MSC_ConnHdlr vc_conn;
3147
3148 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3149 f_sleep(1.0);
3150 vc_conn := f_start_handler(tc_fn);
3151 vc_conn.done;
3152
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003153 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3154 var integer trx_num := c_BtsParams[i].trx_num;
3155 num_trx_total := num_trx_total + trx_num;
3156 if (i < nr_bts) {
3157 num_trx_connected := num_trx_connected + trx_num;
3158 }
3159 }
3160
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003161 /* Also verify stat exposed on CTRL interface */
3162 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3163 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 +06003164 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(num_trx_connected));
3165 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 +02003166
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003167 /* Verify rf_states exposed on CTRL interface */
3168 var charstring expect_net_rf_states := "";
3169 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003170 var charstring expect_bts_rf_states := "";
3171
3172 for (var integer j := 0; j < c_BtsParams[i].trx_num; j := j + 1) {
3173 expect_bts_rf_states := expect_bts_rf_states &
3174 int2str(i) & "," & int2str(j) & ",";
3175 if (i < NUM_BTS) {
3176 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3177 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3178 } else {
3179 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3180 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3181 }
3182 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3183 expect_bts_rf_states := expect_bts_rf_states & "on,";
3184 if (i < nr_bts) {
3185 /* For BTS where RSL is connected, the RSL state will be "up" */
3186 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3187 } else {
3188 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3189 }
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003190 }
3191
3192 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3193 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3194 }
3195 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3196
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003197 f_shutdown_helper();
3198}
3199
3200/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3201private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3202 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3203}
3204testcase TC_stat_num_bts_connected_1() runs on test_CT {
3205 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3206}
3207
3208/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3209private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3210 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3211}
3212testcase TC_stat_num_bts_connected_2() runs on test_CT {
3213 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3214}
3215
3216/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3217private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3218 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3219}
3220testcase TC_stat_num_bts_connected_3() runs on test_CT {
3221 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3222}
3223
Harald Welte4003d112017-12-09 22:35:39 +01003224testcase TC_ctrl() runs on test_CT {
3225 var charstring ctrl_resp;
3226
Harald Welte89d42e82017-12-17 16:42:41 +01003227 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003228
3229 /* all below values must match the osmo-bsc.cfg config file used */
3230
Harald Welte6a129692018-03-17 17:30:14 +01003231 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3232 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003233 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003234
3235 var integer bts_nr := 0;
3236 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3237 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3238 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3239 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3240 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3241 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3242 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3243
3244 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3245 f_sleep(2.0);
3246 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3247 setverdict(fail, "oml-uptime not incrementing as expected");
3248 }
3249 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3250
3251 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3252
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003253 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003254}
3255
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003256/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3257 "location-state" over the SCCPlite IPA conn */
3258testcase TC_ctrl_location() runs on test_CT {
3259 var MSC_ConnHdlr vc_conn;
3260 var integer bts_nr := 0;
3261
3262 f_init(1, true);
3263 f_sleep(1.0);
3264
3265 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3266 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3267 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3268
3269 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3270 f_sleep(2.0);
3271
3272 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3273 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3274 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3275
3276 /* should match the one from config */
3277 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3278
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003279 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003280}
3281
Harald Welte6f521d82017-12-11 19:52:02 +01003282
3283/***********************************************************************
3284 * Paging Testing
3285 ***********************************************************************/
3286
3287type record Cell_Identity {
3288 GsmMcc mcc,
3289 GsmMnc mnc,
3290 GsmLac lac,
3291 GsmCellId ci
3292};
Harald Welte24135bd2018-03-17 19:27:53 +01003293private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003294private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003295
Harald Welte5d1a2202017-12-13 19:51:29 +01003296type set of integer BtsIdList;
3297
3298private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3299 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3300 if (bts_id == bts_ids[j]) {
3301 return true;
3302 }
3303 }
3304 return false;
3305}
Harald Welte6f521d82017-12-11 19:52:02 +01003306
3307/* core paging test helper function; used by most paging test cases */
3308private function f_pageing_helper(hexstring imsi,
3309 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003310 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003311 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003312 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003313{
3314 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003315 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003316 var RSL_Message rx_rsl;
3317 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003318 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003319
3320 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003321
3322 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003323 for (i := 0; i < NUM_BTS; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003324 IPA_RSL[i][0].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003325 }
Harald Welte6f521d82017-12-11 19:52:02 +01003326
3327 if (isvalue(rsl_chneed)) {
3328 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3329 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3330 } else {
3331 bssmap_chneed := omit;
3332 }
3333
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003334 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3335 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003336
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003337 if (not istemplatekind(tmsi, "omit")) {
3338 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003339 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003340 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003341 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003342
Harald Welte5d1a2202017-12-13 19:51:29 +01003343 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003344 rx_rsl := f_exp_ipa_rx(tr_RSL_PAGING_CMD(mi), idx := {bts_ids[i], 0});
Harald Welte5d1a2202017-12-13 19:51:29 +01003345 /* check channel type, paging group */
3346 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3347 setverdict(fail, "Paging for wrong paging group");
3348 }
3349 if (ispresent(rsl_chneed) and
3350 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3351 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3352 }
Harald Welte6f521d82017-12-11 19:52:02 +01003353 }
Harald Welte2fccd982018-01-31 15:48:19 +01003354 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003355 /* do a quick check on all not-included BTSs if they received paging */
3356 for (i := 0; i < NUM_BTS; i := i + 1) {
3357 timer T := 0.1;
3358 if (f_bts_in_list(i, bts_ids)) {
3359 continue;
3360 }
3361 T.start;
3362 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003363 [] IPA_RSL[i][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003364 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3365 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003366 [] IPA_RSL[i][0].receive { repeat; }
Harald Welte5d1a2202017-12-13 19:51:29 +01003367 [] T.timeout { }
3368 }
Harald Welte6f521d82017-12-11 19:52:02 +01003369 }
3370
3371 setverdict(pass);
3372}
3373
Harald Welte5d1a2202017-12-13 19:51:29 +01003374const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003375const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003376const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3377const BtsIdList c_BtsId_LAC2 := { 2 };
3378
Harald Welte6f521d82017-12-11 19:52:02 +01003379/* PAGING by IMSI + TMSI */
3380testcase TC_paging_imsi_nochan() runs on test_CT {
3381 var BSSMAP_FIELD_CellIdentificationList cid_list;
3382 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003383 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003384 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003385}
3386
3387/* PAGING by IMSI + TMSI */
3388testcase TC_paging_tmsi_nochan() runs on test_CT {
3389 var BSSMAP_FIELD_CellIdentificationList cid_list;
3390 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003391 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003392 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003393}
3394
3395/* Paging with different "channel needed' values */
3396testcase TC_paging_tmsi_any() runs on test_CT {
3397 var BSSMAP_FIELD_CellIdentificationList cid_list;
3398 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003399 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003400 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003401}
3402testcase TC_paging_tmsi_sdcch() runs on test_CT {
3403 var BSSMAP_FIELD_CellIdentificationList cid_list;
3404 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003405 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003406 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003407}
3408testcase TC_paging_tmsi_tch_f() runs on test_CT {
3409 var BSSMAP_FIELD_CellIdentificationList cid_list;
3410 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003411 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003412 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003413}
3414testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3415 var BSSMAP_FIELD_CellIdentificationList cid_list;
3416 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003417 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003418 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003419}
3420
3421/* Paging by CGI */
3422testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3423 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3424 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003425 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003426 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003427}
3428
3429/* Paging by LAC+CI */
3430testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3431 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3432 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003433 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003434 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003435}
3436
3437/* Paging by CI */
3438testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3439 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3440 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003441 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003442 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003443}
3444
3445/* Paging by LAI */
3446testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3447 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3448 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003449 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003450 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003451}
3452
3453/* Paging by LAC */
3454testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3455 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3456 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003457 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003458 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003459}
3460
3461/* Paging by "all in BSS" */
3462testcase TC_paging_imsi_nochan_all() runs on test_CT {
3463 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3464 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003465 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003466 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003467}
3468
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003469/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003470testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3471 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3472 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 +01003473 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003474 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003475}
Harald Welte6f521d82017-12-11 19:52:02 +01003476
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003477/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003478testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3479 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3480 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003481 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003482 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003483}
3484
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003485/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003486testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3487 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3488 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003489 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003490 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003491}
3492
Harald Welte6f521d82017-12-11 19:52:02 +01003493/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003494testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3495 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3496 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3497 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003498 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003499}
3500
3501/* Paging on empty list: Verify none of them page */
3502testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3503 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3504 cid_list := { cIl_LAC := { } };
3505 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003506 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003507}
3508
Stefan Sperling049a86e2018-03-20 15:51:00 +01003509/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3510testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3511 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3512 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3513 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3514 f_shutdown_helper();
3515}
3516
Pau Espin Pedrol07657ae2023-01-03 12:08:05 +01003517/* Send paging response containing invalid (wrongly formatted) MobileIdentity IE. */
3518testcase TC_paging_imsi_nochan_ci_resp_invalid_mi() runs on test_CT {
3519 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3520 var BSSAP_N_CONNECT_ind rx_c_ind;
3521 var DchanTuple dt;
3522 var octetstring rr_pag_resp := '06270003535992617965720000'O;
3523 /* { 06 27 } is { GSM48_PDISC_RR, GSM48_MT_RR_PAG_RESP }
3524 * see 3GPP TS 44.018, table 9.1.25.1
3525 * { 00 } or { 01 } is CKSN + Spare Half Octet, not important
3526 * { 03 53 59 92 } is Mobile Station Classmark
3527 * { 61 79 65 72 00 00 } is the invalid Mobile Identity IE (3GPP TS 24.008, 10.5.1.4),
3528 * Length is 0x61 (97 in decimal).
3529 */
3530
3531 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
3532 f_pageing_helper('001010000000008'H, cid_list, { 0 });
3533
3534 /* Send CHAN RQD and wait for allocation; acknowledge it */
3535 dt.rsl_chan_nr := f_chreq_act_ack();
3536 dt.idx := {0, 0};
3537
3538 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3539 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), rr_pag_resp));
3540
3541 /* Expevct a CR with a matching Paging response on the A-Interface */
3542 timer T := 5.0;
3543 T.start;
3544 alt {
3545 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
3546 setverdict(pass);
3547 dt.sccp_conn_id := rx_c_ind.connectionId;
3548 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
3549 }
3550 [] BSSAP.receive {
3551 setverdict(fail, "Received unexpected message on A-Interface!");
3552 }
3553 [] T.timeout {
3554 setverdict(fail, "Received nothing on A-Interface!");
3555 }
3556 }
3557
3558 f_perform_clear_test_ct(dt);
3559 f_shutdown_helper();
3560}
3561
Harald Welte6f521d82017-12-11 19:52:02 +01003562/* Verify paging retransmission interval + count */
3563/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003564/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003565
Harald Weltee65d40e2017-12-13 00:09:06 +01003566/* Verify PCH load */
3567testcase TC_paging_imsi_load() runs on test_CT {
3568 var BSSMAP_FIELD_CellIdentificationList cid_list;
3569 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003570 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003571 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003572 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003573
3574 /* tell BSC there is no paging space anymore */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003575 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003576 f_sleep(0.2);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003577 IPA_RSL[0][0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003578
3579 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3580 * there would be 8 retransmissions during 4 seconds */
3581 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003582 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003583 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003584 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003585 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003586 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003587 }
Harald Welte2caa1062018-03-17 18:19:05 +01003588 [] T_retrans.timeout {
3589 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003590 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte2caa1062018-03-17 18:19:05 +01003591 T_retrans.start;
3592 repeat;
3593 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003594 [] T.timeout {
3595 setverdict(pass);
3596 }
3597 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003598
3599 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003600}
3601
Harald Welte235ebf12017-12-15 14:18:16 +01003602/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003603testcase TC_paging_counter() runs on test_CT {
3604 var BSSMAP_FIELD_CellIdentificationList cid_list;
3605 timer T := 4.0;
3606 var integer i;
3607 var integer paging_attempted_bsc;
3608 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003609 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003610 var integer paging_expired_bts[NUM_BTS];
3611 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3612
3613 f_init();
3614
3615 /* read counters before paging */
3616 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01003617 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
Harald Welte1ff69992017-12-14 12:31:17 +01003618 for (i := 0; i < NUM_BTS; i := i+1) {
3619 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3620 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3621 }
3622
3623 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3624
3625 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3626 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3627 for (i := 0; i < NUM_BTS; i := i+1) {
3628 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3629 paging_attempted_bts[i]+1);
3630 }
3631
3632 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3633 f_sleep(12.0);
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01003634 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
Harald Welte1ff69992017-12-14 12:31:17 +01003635 for (i := 0; i < NUM_BTS; i := i+1) {
3636 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3637 paging_expired_bts[i]+1);
3638 }
Harald Welte1ff69992017-12-14 12:31:17 +01003639
Philipp Maier282ca4b2018-02-27 17:17:00 +01003640 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003641}
3642
3643
Harald Welte10985002017-12-12 09:29:15 +01003644/* Verify paging stops after A-RESET */
3645testcase TC_paging_imsi_a_reset() runs on test_CT {
3646 var BSSMAP_FIELD_CellIdentificationList cid_list;
3647 timer T := 3.0;
3648 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003649 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003650
3651 /* Perform a BSSMAP Reset and wait for ACK */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003652 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 +01003653 alt {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003654 [] 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 +01003655 [] BSSAP.receive { repeat; }
3656 }
3657
Daniel Willmanncbef3982018-07-30 09:22:40 +02003658 /* Wait to avoid a possible race condition if a paging message is
3659 * received right before the reset ACK. */
3660 f_sleep(0.2);
3661
Harald Welte10985002017-12-12 09:29:15 +01003662 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003663 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003664 IPA_RSL[i][0].clear;
Philipp Maier1e6b4422018-02-23 14:02:13 +01003665 }
Harald Welte10985002017-12-12 09:29:15 +01003666
3667 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3668 T.start;
3669 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003670 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003671 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003672 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003673 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003674 [] IPA_RSL[1][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003675 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003676 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003677 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003678 [] IPA_RSL[2][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003679 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003680 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003681 }
Harald Welte10985002017-12-12 09:29:15 +01003682 [] T.timeout {
3683 setverdict(pass);
3684 }
3685 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003686
3687 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003688}
Harald Welteae026692017-12-09 01:03:01 +01003689
Philipp Maierf45824a2019-08-14 14:44:10 +02003690/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3691 * paging response we can not know which MSC is in charge, so we will blindly
3692 * pick the first configured MSC. This behavior is required in order to make
3693 * MT-CSFB calls working because in those cases the BSC can not know that the
3694 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3695 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003696 */
3697testcase TC_paging_resp_unsol() runs on test_CT {
3698
3699 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003700 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003701
3702 var BSSAP_N_CONNECT_ind rx_c_ind;
3703 var DchanTuple dt;
3704 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003705 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003706
3707 /* Send CHAN RQD and wait for allocation; acknowledge it */
3708 dt.rsl_chan_nr := f_chreq_act_ack();
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003709 dt.idx := {0, 0};
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003710
3711 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
Pau Espin Pedrole8a51012023-01-03 11:59:59 +01003712 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 +01003713
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003714
Philipp Maierf45824a2019-08-14 14:44:10 +02003715 /* Expevct a CR with a matching Paging response on the A-Interface */
3716 T.start;
3717 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003718 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003719 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003720 dt.sccp_conn_id := rx_c_ind.connectionId;
3721 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003722 }
3723 [] BSSAP.receive {
3724 setverdict(fail, "Received unexpected message on A-Interface!");
3725 }
3726 [] T.timeout {
3727 setverdict(fail, "Received nothing on A-Interface!");
3728 }
3729 }
3730
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003731 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003732 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003733}
3734
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003735/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3736function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003737 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003738 var Hexstrings imsis := {};
3739 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003740 var integer rx_paging_num := 0;
3741 var integer i;
3742 timer T_rx := 60.0;
3743 timer T_load_ind := 1.0;
3744
3745 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003746 imsis := imsis & {f_gen_imsi(i)};
3747 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003748 }
3749
3750 f_init(1, guard_timeout := 100.0);
3751
3752 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003753 IPA_RSL[0][0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003754 if (send_pag_load_ind) {
3755 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003756 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(65535));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003757 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003758
3759 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003760 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003761 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 +02003762 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3763 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003764 }
3765
3766 T_rx.start;
3767 T_load_ind.start;
3768 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003769 [] 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 +02003770 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3771 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3772 var charstring imsi_str := hex2str(imsi_suffix);
3773 var integer imsi_idx := str2int(imsi_str);
3774 if (rx_paging_done[imsi_idx] == false) {
3775 rx_paging_done[imsi_idx] := true;
3776 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003777 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003778 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 +02003779 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003780 }
3781 if (rx_paging_num < num_subscribers) {
3782 repeat;
3783 }
3784 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003785 [] IPA_RSL[0][0].receive { repeat; }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003786 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003787 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3788 if (send_pag_load_ind) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003789 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(40));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003790 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003791 T_load_ind.start;
3792 repeat;
3793 }
3794 [] T_rx.timeout {
3795 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3796 mtc.stop;
3797 }
3798 }
3799
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003800 /* Drop OML connection to have all paging requests flushed: */
3801 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3802
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003803 f_shutdown_helper();
3804}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003805/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3806testcase TC_paging_500req() runs on test_CT {
3807 f_TC_paging_Nreq(500, true);
3808}
3809/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3810 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3811 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3812 * for current config yields ~8req/sec, so 480req/min maximum. */
3813testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3814 f_TC_paging_Nreq(450, false);
3815}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003816
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003817/* Test RSL link drop causes counter increment */
3818testcase TC_rsl_drop_counter() runs on test_CT {
3819 var integer rsl_fail;
3820
Harald Welte89d42e82017-12-17 16:42:41 +01003821 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003822
3823 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3824
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003825 f_ipa_rsl_stop(bts[0][0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003826
3827 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3828
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003829 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003830}
3831
3832/* TODO: Test OML link drop causes counter increment */
3833
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003834/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3835function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003836 var IPA_Client client;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003837 timer T := 10.0;
3838
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003839 client.id := "IPA-BTS0-TRX0-RSL";
3840 client.vc_IPA := IPA_Emulation_CT.create(client.id & "-IPA") alive;
3841 client.ccm_pars := c_IPA_default_ccm_pars;
3842 client.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
3843 client.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003844
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003845 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003846
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003847 f_init_mgcp(0, "VirtMGW");
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003848
3849 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003850 map(client.vc_IPA:IPA_PORT, system:IPA);
3851 connect(client.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0][0]);
3852 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 +01003853
3854 /* wait for IPA OML link to connect and then disconnect */
3855 T.start;
3856 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003857 [] IPA_RSL[0][0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003858 T.stop;
3859 return true;
3860 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003861 [] IPA_RSL[0][0].receive { repeat }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003862 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003863 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003864 }
3865 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003866 return false;
3867}
3868
3869/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3870testcase TC_rsl_unknown_unit_id() runs on test_CT {
3871 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3872 setverdict(pass);
3873 } else {
3874 setverdict(fail, "Timeout RSL waiting for connection to close");
3875 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003876 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003877}
3878
3879
3880/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3881testcase TC_oml_unknown_unit_id() runs on test_CT {
3882 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3883 setverdict(pass);
3884 } else {
3885 setverdict(fail, "Timeout OML waiting for connection to close");
3886 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003887 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003888}
3889
3890
Harald Weltec1a2fff2017-12-17 11:06:19 +01003891/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003892 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003893 ***********************************************************************/
3894
Harald Welte6811d102019-04-14 22:23:14 +02003895import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003896import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003897import from RSL_Emulation all;
3898import from MSC_ConnectionHandler all;
3899
3900type function void_fn(charstring id) runs on MSC_ConnHdlr;
3901
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003902/* helper function to create and connect a MSC_ConnHdlr component
3903 * TODO: allow connecting to TRX1..N, not only TRX0 */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003904private 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 +02003905 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003906 connect(vc_conn:RSL, bts[0][0].rsl.vc_RSL:CLIENT_PT);
3907 connect(vc_conn:RSL_PROC, bts[0][0].rsl.vc_RSL:RSL_PROC);
3908 if (isvalue(bts[1][0])) {
3909 connect(vc_conn:RSL1, bts[1][0].rsl.vc_RSL:CLIENT_PT);
3910 connect(vc_conn:RSL1_PROC, bts[1][0].rsl.vc_RSL:RSL_PROC);
Philipp Maier956a92f2018-02-16 10:58:07 +01003911 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003912 if (isvalue(bts[2][0])) {
3913 connect(vc_conn:RSL2, bts[2][0].rsl.vc_RSL:CLIENT_PT);
3914 connect(vc_conn:RSL2_PROC, bts[2][0].rsl.vc_RSL:RSL_PROC);
Neels Hofmeyr91401012019-07-11 00:42:35 +02003915 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003916 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003917 if (mp_enable_lcs_tests) {
3918 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3919 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3920 }
Daniel Willmannebdecc02020-08-12 15:30:17 +02003921 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003922 connect(vc_conn:MGCP_PROC, vc_MGCP[mgwpool_idx]:MGCP_PROC);
3923 connect(vc_conn:MGCP, vc_MGCP[mgwpool_idx]:MGCP_CLIENT);
3924 connect(vc_conn:MGCP_MULTI, vc_MGCP[mgwpool_idx]:MGCP_CLIENT_MULTI);
Harald Welte336820c2018-05-31 20:34:52 +02003925}
3926
Neels Hofmeyrda436782021-07-20 22:09:06 +02003927function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003928runs on test_CT return MSC_ConnHdlr {
3929 var charstring id := testcasename();
3930 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003931 var integer bssap_idx := 0;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003932 var integer mgwpool_idx := 0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003933 if (isvalue(pars)) {
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003934 var TestHdlrParams pars_val := valueof(pars);
3935 bssap_idx := pars_val.mscpool.bssap_idx;
3936 mgwpool_idx := pars_val.mgwpool_idx;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003937 }
Harald Welte336820c2018-05-31 20:34:52 +02003938 vc_conn := MSC_ConnHdlr.create(id);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003939 f_connect_handler(vc_conn, bssap_idx, mgwpool_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003940 return vc_conn;
3941}
3942
3943function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3944runs on test_CT return MSC_ConnHdlr {
3945 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003946 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003947 return vc_conn;
3948}
3949
Neels Hofmeyrda436782021-07-20 22:09:06 +02003950function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3951runs on test_CT return MSC_ConnHdlr {
3952 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3953}
3954
Harald Weltea0630032018-03-20 21:09:55 +01003955/* first function inside ConnHdlr component; sets g_pars + starts function */
3956private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3957runs on MSC_ConnHdlr {
3958 if (isvalue(pars)) {
3959 g_pars := valueof(pars);
3960 }
3961 fn.apply(id);
3962}
3963
Oliver Smith26a3db72021-07-09 13:51:29 +02003964private function f_vty_encryption_a5(charstring options) runs on test_CT {
3965 f_vty_transceive(BSCVTY, "configure terminal");
3966 f_vty_transceive(BSCVTY, "network");
3967 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3968 f_vty_transceive(BSCVTY, "exit");
3969 f_vty_transceive(BSCVTY, "exit");
3970}
3971
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003972const charstring VTY_A5_DEFAULT := "0 1 3";
3973
Oliver Smith26a3db72021-07-09 13:51:29 +02003974private function f_vty_encryption_a5_reset() runs on test_CT {
3975 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003976 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003977}
3978
Harald Welte3c86ea02018-05-10 22:28:05 +02003979/* Establish signalling channel (non-assignment case) followed by cipher mode */
3980private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003981 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3982 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003983 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003984 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3985 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3986 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3987 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003988
Philipp Maier23000732018-05-18 11:25:37 +02003989 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003990 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003991}
3992testcase TC_ciph_mode_a5_0() runs on test_CT {
3993 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003994 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003995 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3996
3997 f_init(1, true);
3998 f_sleep(1.0);
3999 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4000 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004001 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004002}
4003testcase TC_ciph_mode_a5_1() runs on test_CT {
4004 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004005 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004006 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
4007
4008 f_init(1, true);
4009 f_sleep(1.0);
4010 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4011 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004012 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004013}
Oliver Smith50b98122021-07-09 15:00:28 +02004014/* OS#4975: verify that A5/2 is preferred over A5/0 */
4015testcase TC_ciph_mode_a5_2_0() runs on test_CT {
4016 var MSC_ConnHdlr vc_conn;
4017 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4018
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01004019 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02004020
4021 f_init(1, true);
4022 f_vty_encryption_a5("0 1 2 3");
4023 f_sleep(1.0);
4024 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4025 vc_conn.done;
4026 f_vty_encryption_a5_reset();
4027 f_shutdown_helper();
4028}
Oliver Smith1dff88d2021-07-09 08:45:51 +02004029/* OS#4975: verify that A5/1 is preferred over A5/2 */
4030testcase TC_ciph_mode_a5_2_1() runs on test_CT {
4031 var MSC_ConnHdlr vc_conn;
4032 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4033
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01004034 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02004035
4036 f_init(1, true);
4037 f_vty_encryption_a5("1 2");
4038 f_sleep(1.0);
4039 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4040 vc_conn.done;
4041 f_vty_encryption_a5_reset();
4042 f_shutdown_helper();
4043}
Harald Welte3c86ea02018-05-10 22:28:05 +02004044testcase TC_ciph_mode_a5_3() runs on test_CT {
4045 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004046 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004047 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
4048
4049 f_init(1, true);
4050 f_sleep(1.0);
4051 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4052 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004053 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004054}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004055/* Establish a Signalling channel with A5/4 encryption. */
4056testcase TC_ciph_mode_a5_4() runs on test_CT {
4057 var MSC_ConnHdlr vc_conn;
4058 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4059 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02004060
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004061 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02004062 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004063 f_sleep(1.0);
4064 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4065 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02004066 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004067 f_shutdown_helper();
4068}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004069/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
4070private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
4071 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4072 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
4073 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4074 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4075
4076 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004077 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004078}
4079testcase TC_assignment_aoip_tla_v6() runs on test_CT {
4080 var MSC_ConnHdlr vc_conn;
4081 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4082
4083 f_init(1, true);
4084 f_sleep(1.0);
4085 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
4086 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004087 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004088}
4089
Harald Welte3c86ea02018-05-10 22:28:05 +02004090
4091/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02004092private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004093 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4094 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004095
Harald Welte552620d2017-12-16 23:21:36 +01004096 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4097 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01004098
Harald Weltea0630032018-03-20 21:09:55 +01004099 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004100 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004101}
Harald Welte552620d2017-12-16 23:21:36 +01004102testcase TC_assignment_fr_a5_0() runs on test_CT {
4103 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004104 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004105 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01004106
Harald Welte89d42e82017-12-17 16:42:41 +01004107 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004108 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004109 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004110 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004111 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004112}
Harald Welte552620d2017-12-16 23:21:36 +01004113testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01004114 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004115 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004116 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004117
Harald Welte89d42e82017-12-17 16:42:41 +01004118 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004119 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004120 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4121 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004122 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02004123}
4124testcase TC_assignment_fr_a5_3() runs on test_CT {
4125 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004126 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004127 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004128
Harald Welte651fcdc2018-05-10 20:23:16 +02004129 f_init(1, true);
4130 f_sleep(1.0);
4131 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004132 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004133 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004134}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004135/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
4136testcase TC_assignment_fr_a5_4() runs on test_CT {
4137 var MSC_ConnHdlr vc_conn;
4138 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4139 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
4140
4141 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004142 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004143 f_sleep(1.0);
4144 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4145 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02004146 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004147 f_shutdown_helper();
4148}
Harald Weltec1a2fff2017-12-17 11:06:19 +01004149
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02004150/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
4151testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
4152 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4153 var MSC_ConnHdlr vc_conn;
4154
4155 f_init(1, true);
4156 f_sleep(1.0);
4157
4158 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4159 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4160 vc_conn.done;
4161 f_shutdown_helper();
4162}
4163
Harald Welte552620d2017-12-16 23:21:36 +01004164/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4165private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004166 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004167 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004168 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004169
4170 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004171 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4172
Harald Weltea0630032018-03-20 21:09:55 +01004173 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004174 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004175}
Harald Welte552620d2017-12-16 23:21:36 +01004176testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4177 var MSC_ConnHdlr vc_conn;
4178
Harald Welte89d42e82017-12-17 16:42:41 +01004179 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004180 f_sleep(1.0);
4181
Harald Welte8863fa12018-05-10 20:15:27 +02004182 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004183 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004184 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004185}
4186
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004187private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4188 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4189 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004190
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004191 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4192 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4193
4194 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4195
4196 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004197
4198 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4199 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4200
4201 f_create_chan_and_exp();
4202 /* we should now have a COMPL_L3 at the MSC */
4203
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004204 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004205 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004206 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004207}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004208testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4209 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004210 var MSC_ConnHdlr vc_conn;
4211
Harald Welte89d42e82017-12-17 16:42:41 +01004212 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004213 f_sleep(1.0);
4214
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004215 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004216 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004217 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004218 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004219}
4220
4221
Harald Welte4532e0a2017-12-23 02:05:44 +01004222private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004223 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004224 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004225 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004226 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004227
4228 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004229 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004230
4231 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004232 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4233 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004234 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4235 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4236 };
4237 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004238 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004239}
4240
4241testcase TC_assignment_sign() runs on test_CT {
4242 var MSC_ConnHdlr vc_conn;
4243
4244 f_init(1, true);
4245 f_sleep(1.0);
4246
Harald Welte8863fa12018-05-10 20:15:27 +02004247 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004248 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004249 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004250}
4251
Harald Welte60aa5762018-03-21 19:33:13 +01004252/***********************************************************************
4253 * Codec (list) testing
4254 ***********************************************************************/
4255
4256/* check if the given rsl_mode is compatible with the a_elem */
4257private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4258return boolean {
4259 select (a_elem.codecType) {
4260 case (GSM_FR) {
4261 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4262 return true;
4263 }
4264 }
4265 case (GSM_HR) {
4266 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4267 return true;
4268 }
4269 }
4270 case (GSM_EFR) {
4271 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4272 return true;
4273 }
4274 }
4275 case (FR_AMR) {
4276 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4277 return true;
4278 }
4279 }
4280 case (HR_AMR) {
4281 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4282 return true;
4283 }
4284 }
4285 case else { }
4286 }
4287 return false;
4288}
4289
4290/* check if the given rsl_mode is compatible with the a_list */
4291private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4292return boolean {
4293 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4294 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4295 return true;
4296 }
4297 }
4298 return false;
4299}
4300
4301/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004302function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004303return BSSMAP_IE_ChannelType {
4304 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4305 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4306 select (a_elem.codecType) {
4307 case (GSM_FR) {
4308 ret.channelRateAndType := ChRate_TCHF;
4309 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4310 }
4311 case (GSM_HR) {
4312 ret.channelRateAndType := ChRate_TCHH;
4313 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4314 }
4315 case (GSM_EFR) {
4316 ret.channelRateAndType := ChRate_TCHF;
4317 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4318 }
4319 case (FR_AMR) {
4320 ret.channelRateAndType := ChRate_TCHF;
4321 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4322 }
4323 case (HR_AMR) {
4324 ret.channelRateAndType := ChRate_TCHH;
4325 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4326 }
4327 case else {
4328 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004329 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004330 }
4331 }
4332 return ret;
4333}
4334
Harald Weltea63b9102018-03-22 20:36:16 +01004335private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4336return template RSL_IE_Body {
4337 var template RSL_IE_Body mode_ie := {
4338 chan_mode := {
4339 len := ?,
4340 reserved := ?,
4341 dtx_d := ?,
4342 dtx_u := ?,
4343 spd_ind := RSL_SPDI_SPEECH,
4344 ch_rate_type := -,
4345 coding_alg_rate := -
4346 }
4347 }
4348
4349 select (a_elem.codecType) {
4350 case (GSM_FR) {
4351 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4352 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4353 }
4354 case (GSM_HR) {
4355 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4356 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4357 }
4358 case (GSM_EFR) {
4359 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4360 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4361 }
4362 case (FR_AMR) {
4363 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4364 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4365 }
4366 case (HR_AMR) {
4367 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4368 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4369 }
4370 }
4371 return mode_ie;
4372}
4373
Harald Welte60aa5762018-03-21 19:33:13 +01004374type record CodecListTest {
4375 BSSMAP_IE_SpeechCodecList codec_list,
4376 charstring id
4377}
4378type record of CodecListTest CodecListTests
4379
4380private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004381 f_assignment_codec(id);
4382}
4383
4384private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02004385 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02004386 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Harald Welte60aa5762018-03-21 19:33:13 +01004387
4388 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004389 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004390 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4391 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4392 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004393 if (isvalue(g_pars.expect_mr_s0_s7)) {
4394 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4395 g_pars.expect_mr_s0_s7;
4396 }
Harald Welte79f3f542018-05-25 20:02:37 +02004397 }
Harald Welte60aa5762018-03-21 19:33:13 +01004398 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4399 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004400 log("expecting ASS COMPL like this: ", exp_compl);
4401
4402 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004403
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004404 if (not g_pars.expect_channel_mode_modify) {
4405 /* Verify that the RSL-side activation actually matches our expectations */
4406 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004407
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004408 var RSL_IE_Body mode_ie;
4409 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4410 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004411 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004412 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004413 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4414 if (not match(mode_ie, t_mode_ie)) {
4415 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4416 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004417 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004418
4419 var RSL_IE_Body mr_conf;
4420 if (g_pars.expect_mr_conf_ie != omit) {
4421 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4422 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4423 mtc.stop;
4424 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004425 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004426
4427 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
Vadim Yanitskiy8b189372022-09-14 17:31:17 +07004428 setverdict(fail, "RSL MR CONFIG IE does not match expectation. ",
4429 "Expected: ", g_pars.expect_mr_conf_ie, ", got: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004430 }
4431 } else {
4432 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4433 log("found RSL MR CONFIG IE: ", mr_conf);
4434 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4435 mtc.stop;
4436 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004437 }
4438 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004439
4440 if (do_perform_clear) {
4441 f_perform_clear();
4442 }
Harald Welte60aa5762018-03-21 19:33:13 +01004443}
4444
Philipp Maierd0e64b02019-03-13 14:15:23 +01004445private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4446
4447 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4448 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4449
4450 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004451 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004452 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4453 }
4454 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4455 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4456 log("expecting ASS FAIL like this: ", exp_fail);
4457
4458 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004459 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004460}
4461
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004462const CounterNameVals counternames_bsc_bts_assignment := {
4463 { "assignment:attempted", 0 },
4464 { "assignment:completed", 0 },
4465 { "assignment:stopped", 0 },
4466 { "assignment:no_channel", 0 },
4467 { "assignment:timeout", 0 },
4468 { "assignment:failed", 0 },
4469 { "assignment:error", 0 }
4470};
4471
4472const CounterNameVals counternames_bts_assignment := {
4473 { "assignment:attempted_sign", 0 },
4474 { "assignment:attempted_speech", 0 },
4475 { "assignment:completed_sign", 0 },
4476 { "assignment:completed_speech", 0 },
4477 { "assignment:stopped_sign", 0 },
4478 { "assignment:stopped_speech", 0 },
4479 { "assignment:no_channel_sign", 0 },
4480 { "assignment:no_channel_speech", 0 },
4481 { "assignment:timeout_sign", 0 },
4482 { "assignment:timeout_speech", 0 },
4483 { "assignment:failed_sign", 0 },
4484 { "assignment:failed_speech", 0 },
4485 { "assignment:error_sign", 0 },
4486 { "assignment:error_speech", 0 }
4487};
4488
4489function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4490 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4491 f_ctrs_bts_init(bts_count, bts_names);
4492 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4493}
4494
Harald Welte60aa5762018-03-21 19:33:13 +01004495testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004496 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004497 var MSC_ConnHdlr vc_conn;
4498
4499 f_init(1, true);
4500 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004501 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004502
4503 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004504 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004505 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004506
4507 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4508 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4509 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4510 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4511 f_ctrs_bts_verify();
4512
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004513 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004514}
4515
4516testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004517 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004518 var MSC_ConnHdlr vc_conn;
4519
4520 f_init(1, true);
4521 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004522 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004523
4524 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004525 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004526 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004527
4528 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4529 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4530 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4531 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4532 f_ctrs_bts_verify();
4533
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004534 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004535}
4536
4537testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004538 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004539 var MSC_ConnHdlr vc_conn;
4540
4541 f_init(1, true);
4542 f_sleep(1.0);
4543
4544 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004545 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004546 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004547 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004548}
4549
Philipp Maierd0e64b02019-03-13 14:15:23 +01004550/* Allow 5,90k only (current default config) */
4551private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004552 f_vty_cfg_msc(BSCVTY, 0, {
4553 "amr-config 12_2k forbidden",
4554 "amr-config 10_2k forbidden",
4555 "amr-config 7_95k forbidden",
4556 "amr-config 7_40k forbidden",
4557 "amr-config 6_70k forbidden",
4558 "amr-config 5_90k allowed",
4559 "amr-config 5_15k forbidden",
4560 "amr-config 4_75k forbidden"
4561 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004562}
4563
4564/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4565 * ("Config-NB-Code = 1") */
4566private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004567 f_vty_cfg_msc(BSCVTY, 0, {
4568 "amr-config 12_2k allowed",
4569 "amr-config 10_2k forbidden",
4570 "amr-config 7_95k forbidden",
4571 "amr-config 7_40k allowed",
4572 "amr-config 6_70k forbidden",
4573 "amr-config 5_90k allowed",
4574 "amr-config 5_15k forbidden",
4575 "amr-config 4_75k allowed"
4576 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004577}
4578
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004579private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4580 var charstring tch;
4581 if (fr) {
4582 tch := "tch-f";
4583 } else {
4584 tch := "tch-h";
4585 }
4586 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4587}
4588
4589/* Set the AMR start-mode for this TCH back to the default configuration. */
4590private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4591 f_vty_amr_start_mode_set(fr, "auto");
4592}
4593
Harald Welte60aa5762018-03-21 19:33:13 +01004594testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004595 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004596 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004597
4598 /* Note: This setups the codec configuration. The parameter payload in
4599 * mr_conf must be consistant with the parameter codecElements in pars
4600 * and also must match the amr-config in osmo-bsc.cfg! */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004601 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004602 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004603 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004604 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004605
Harald Welte60aa5762018-03-21 19:33:13 +01004606 f_init(1, true);
4607 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004608 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004609 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004610
Harald Welte8863fa12018-05-10 20:15:27 +02004611 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004612 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004613
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004614 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4615 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4616 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4617 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4618 f_ctrs_bts_verify();
4619
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004620 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004621 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004622}
4623
4624testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004625 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004626 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004627
4628 /* See note above */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004629 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004630 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004631 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004632 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004633
Harald Welte60aa5762018-03-21 19:33:13 +01004634 f_init(1, true);
4635 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004636 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004637 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004638
Harald Welte8863fa12018-05-10 20:15:27 +02004639 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004640 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004641
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004642 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4643 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4644 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4645 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4646 f_ctrs_bts_verify();
4647
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004648 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004649 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004650}
4651
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004652/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4653testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4654 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4655 var MSC_ConnHdlr vc_conn;
4656
4657 f_init(1, true);
4658 f_sleep(1.0);
4659
4660 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4661 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4662 * expecting a Channel Mode Modify if the channel type is compatible. */
4663 f_disable_all_sdcch();
4664 f_disable_all_tch_h();
4665
4666 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4667 pars.expect_channel_mode_modify := true;
4668 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4669 vc_conn.done;
4670
4671 f_enable_all_sdcch();
4672 f_enable_all_tch();
4673 f_shutdown_helper();
4674}
4675
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004676/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4677testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4678 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4679 var MSC_ConnHdlr vc_conn;
4680
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004681 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4682 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4683 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy36fe9582022-09-14 15:25:04 +07004684 pars.expect_mr_conf_ie := c_mr_conf_5_90;
4685 pars.expect_mr_conf_ie.multirate_cfg.icmi := false; /* expect ICMI=0, smod=00: */
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004686
4687 f_init(1, true);
4688 f_sleep(1.0);
4689
4690 /* First set nonzero start mode bits */
4691 f_vty_amr_start_mode_set(true, "4");
4692 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4693 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4694 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4695 f_vty_amr_start_mode_set(true, "auto");
4696
4697 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4698 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004699
4700 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4701 f_vty_amr_start_mode_set(true, "1");
4702 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004703 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004704}
4705
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004706function f_TC_assignment_codec_amr(boolean fr, RSL_IE_MultirateCfg mr_cfg,
4707 bitstring s8_s0, bitstring exp_s8_s0,
4708 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004709runs on test_CT {
4710
4711 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4712 var MSC_ConnHdlr vc_conn;
4713
Philipp Maierd0e64b02019-03-13 14:15:23 +01004714 if (fr) {
4715 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4716 } else {
4717 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4718 }
4719 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4720 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004721 pars.expect_mr_conf_ie := { multirate_cfg := mr_cfg };
Philipp Maierd0e64b02019-03-13 14:15:23 +01004722 pars.expect_mr_s0_s7 := exp_s8_s0;
4723
4724 f_init(1, true);
4725 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004726 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004727 f_sleep(1.0);
4728
4729 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4730 vc_conn.done;
4731 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004732 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004733}
4734
4735function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4736runs on test_CT {
4737
4738 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4739 var MSC_ConnHdlr vc_conn;
4740
4741 if (fr) {
4742 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4743 } else {
4744 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4745 }
4746 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4747 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4748
4749 f_init(1, true);
4750 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004751 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004752 f_sleep(1.0);
4753
4754 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4755 vc_conn.done;
4756 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004757 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004758}
4759
Philipp Maierd0e64b02019-03-13 14:15:23 +01004760/* Set S1, we expect an AMR multirate configuration IE with all four rates
4761 * set. */
4762testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004763 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4764 params := '20882208'O));
4765 f_TC_assignment_codec_amr(true, mr_cfg, '00000011'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004766 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004767}
4768
4769/* Set S1, we expect an AMR multirate configuration IE with the lower three
4770 * rates set. */
4771testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004772 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4773 params := '208820'O));
4774 f_TC_assignment_codec_amr(false, mr_cfg, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004775 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004776}
4777
4778/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4779 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4780testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004781 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4782 params := '20882208'O));
4783 f_TC_assignment_codec_amr(true, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004784 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004785}
4786
4787/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4788 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4789testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004790 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4791 params := '208820'O));
4792 f_TC_assignment_codec_amr(false, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004793 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004794}
4795
4796/* The following block of tests selects more and more rates until all four
4797 * possible rates are in the active set (full rate) */
4798testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004799 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4800 f_TC_assignment_codec_amr(true, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004801 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004802}
4803
4804testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004805 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4806 params := '2080'O));
4807 f_TC_assignment_codec_amr(true, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004808 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004809}
4810
4811testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004812 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4813 params := '208820'O));
4814 f_TC_assignment_codec_amr(true, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004815 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004816}
4817
4818testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004819 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4820 params := '20882208'O));
4821 f_TC_assignment_codec_amr(true, mr_cfg, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004822 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004823}
4824
4825/* The following block of tests selects more and more rates until all three
4826 * possible rates are in the active set (half rate) */
4827testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004828 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4829 f_TC_assignment_codec_amr(false, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004830 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004831}
4832
4833testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004834 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4835 params := '2080'O));
4836 f_TC_assignment_codec_amr(false, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004837 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004838}
4839
4840testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004841 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4842 params := '208820'O));
4843 f_TC_assignment_codec_amr(false, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004844 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004845}
4846
4847/* The following block tests what happens when the MSC does offer rate
4848 * configurations that are not supported by the BSC. Normally such situations
4849 * should not happen because the MSC gets informed by the BSC in advance via
4850 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4851 * to offer rates that are not applicable anyway. */
4852
4853testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004854 /* Try to include 12,2k in into the active set even though the channel
4855 * is half rate only. The BSC is expected to remove the 12,0k */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004856 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4857 params := '208820'O));
4858 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004859 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004860}
4861
4862testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004863 /* See what happens when all rates are selected at once. Since then
4864 * Also S1 is selected, this setting will be prefered and we should
4865 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004866 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4867 params := '20882208'O));
4868 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004869 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004870}
4871
4872testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004873 /* Same as above, but with S1 missing, the MSC is then expected to
4874 * select the currently supported rates, which are also 12.2k, 7,40k,
4875 * 5,90k, and 4,75k, into the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004876 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4877 params := '20882208'O));
4878 f_TC_assignment_codec_amr(true, mr_cfg, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004879 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004880}
4881
4882testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004883 /* Try to select no rates at all */
4884 f_TC_assignment_codec_amr_fail(true, '00000000'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_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004889 /* Try to select only unsupported rates */
4890 f_TC_assignment_codec_amr_fail(true, '01101000'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_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004895 /* Try to select 12,2k for half rate */
4896 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004897 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004898}
4899
Neels Hofmeyr21863562020-11-26 00:34:33 +00004900testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004901 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4902 codec_modes := '10010101'B,
4903 params := '20882208'O));
4904 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004905 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004906}
4907
4908testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004909 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4910 codec_modes := '00010101'B,
4911 params := '208820'O));
4912 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B,
Neels Hofmeyr21863562020-11-26 00:34:33 +00004913 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004914 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004915}
4916
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004917testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004918 /* "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 +07004919 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 3,
4920 codec_modes := '10010101'B,
4921 params := '20882208'O));
4922 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004923 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004924}
4925
4926testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004927 /* "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 +07004928 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 2,
4929 codec_modes := '00010101'B,
4930 params := '208820'O));
4931 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004932 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004933}
4934
Philipp Maierac09bfc2019-01-08 13:41:39 +01004935private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004936 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4937 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4938 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4939 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004940}
4941
4942private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004943 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4944 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004945}
4946
4947private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004948 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4949 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4950 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4951 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4952 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4953 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004954}
4955
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004956private function f_disable_all_sdcch() runs on test_CT {
4957 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4958 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4959 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4960 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4961}
4962
4963private function f_enable_all_sdcch() runs on test_CT {
4964 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4965 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4966 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4967 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4968}
4969
Philipp Maierac09bfc2019-01-08 13:41:39 +01004970/* Allow HR only */
4971private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4972 g_pars := f_gen_test_hdlr_pars();
4973 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4974 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4975 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4976 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4977 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4978 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4979 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004980 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004981}
4982
4983/* Allow FR only */
4984private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4985 g_pars := f_gen_test_hdlr_pars();
4986 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4987 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4988 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4989 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4990 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4991 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4992 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004993 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004994}
4995
4996/* Allow HR only (expect assignment failure) */
4997private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4998 g_pars := f_gen_test_hdlr_pars();
4999 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5000 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
5001 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5002 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
5003 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
5004 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5005 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005006 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005007}
5008
5009/* Allow FR only (expect assignment failure) */
5010private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
5011 g_pars := f_gen_test_hdlr_pars();
5012 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5013 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
5014 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5015 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
5016 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
5017 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5018 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005019 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005020}
5021
5022/* Allow FR and HR, but prefer FR */
5023private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5024 g_pars := f_gen_test_hdlr_pars();
5025 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5026 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5027 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5028 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5029 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5030 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5031 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5032 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005033 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005034}
5035
5036/* Allow FR and HR, but prefer HR */
5037private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5038 g_pars := f_gen_test_hdlr_pars();
5039 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5040 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5041 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5042 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5043 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5044 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5045 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5046 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005047 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005048}
5049
5050/* Allow FR and HR, but prefer FR */
5051private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5052 g_pars := f_gen_test_hdlr_pars();
5053 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5054 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5055 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5056 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5057 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5058 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5059 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5060 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005061 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005062}
5063
5064/* Allow FR and HR, but prefer HR */
5065private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5066 g_pars := f_gen_test_hdlr_pars();
5067 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5068 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5069 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5070 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5071 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5072 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5073 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5074 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005075 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005076}
5077
5078/* Request a HR channel while all FR channels are exhausted, this is expected
5079 * to work without conflicts */
5080testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
5081 var MSC_ConnHdlr vc_conn;
5082 f_init(1, true);
5083 f_sleep(1.0);
5084 f_enable_all_tch();
5085 f_disable_all_tch_f();
5086 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
5087 vc_conn.done;
5088 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005089 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005090}
5091
5092/* Request a FR channel while all FR channels are exhausted, this is expected
5093 * to fail. */
5094testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
5095 var MSC_ConnHdlr vc_conn;
5096 f_init(1, true);
5097 f_sleep(1.0);
5098 f_enable_all_tch();
5099 f_disable_all_tch_f();
5100 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
5101 vc_conn.done;
5102 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005103 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005104}
5105
5106/* Request a FR (prefered) or alternatively a HR channel while all FR channels
5107 * are exhausted, this is expected to be resolved by selecting a HR channel. */
5108testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
5109 var MSC_ConnHdlr vc_conn;
5110 f_init(1, true);
5111 f_sleep(1.0);
5112 f_enable_all_tch();
5113 f_disable_all_tch_f();
5114 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
5115 vc_conn.done;
5116 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005117 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005118}
5119
5120/* Request a HR (prefered) or alternatively a FR channel while all FR channels
5121 * are exhausted, this is expected to work without conflicts. */
5122testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
5123 var MSC_ConnHdlr vc_conn;
5124 f_init(1, true);
5125 f_sleep(1.0);
5126 f_enable_all_tch();
5127 f_disable_all_tch_f();
5128 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
5129 vc_conn.done;
5130 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005131 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005132}
5133
5134/* Request a FR channel while all HR channels are exhausted, this is expected
5135 * to work without conflicts */
5136testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
5137 var MSC_ConnHdlr vc_conn;
5138 f_init(1, true);
5139 f_sleep(1.0);
5140 f_enable_all_tch();
5141 f_disable_all_tch_h();
5142 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
5143 vc_conn.done;
5144 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005145 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005146}
5147
5148/* Request a HR channel while all HR channels are exhausted, this is expected
5149 * to fail. */
5150testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
5151 var MSC_ConnHdlr vc_conn;
5152 f_init(1, true);
5153 f_sleep(1.0);
5154 f_enable_all_tch();
5155 f_disable_all_tch_h();
5156 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
5157 vc_conn.done;
5158 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005159 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005160}
5161
5162/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5163 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5164testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5165 var MSC_ConnHdlr vc_conn;
5166 f_init(1, true);
5167 f_sleep(1.0);
5168 f_enable_all_tch();
5169 f_disable_all_tch_h();
5170 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5171 vc_conn.done;
5172 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005173 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005174}
5175
5176/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5177 * are exhausted, this is expected to work without conflicts. */
5178testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5179 var MSC_ConnHdlr vc_conn;
5180 f_init(1, true);
5181 f_sleep(1.0);
5182 f_enable_all_tch();
5183 f_disable_all_tch_h();
5184 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5185 vc_conn.done;
5186 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005187 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005188}
5189
5190/* Allow FR and HR, but prefer HR */
5191private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5192 g_pars := f_gen_test_hdlr_pars();
5193 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5194 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5195 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5196 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5197 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5198 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5199 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5200 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005201 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005202}
5203
5204/* Allow FR and HR, but prefer FR */
5205private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5206 g_pars := f_gen_test_hdlr_pars();
5207 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5208 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5209 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5210 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5211 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5212 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5213 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5214 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005215 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005216}
5217
5218/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5219 * HR, which is the prefered type, is selected. */
5220testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5221 var MSC_ConnHdlr vc_conn;
5222 f_init(1, true);
5223 f_sleep(1.0);
5224 f_enable_all_tch();
5225 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5226 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005227 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005228}
5229
5230/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5231 * FR, which is the prefered type, is selected. */
5232testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5233 var MSC_ConnHdlr vc_conn;
5234 f_init(1, true);
5235 f_sleep(1.0);
5236 f_enable_all_tch();
5237 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5238 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005239 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005240}
5241
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005242/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5243private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5244 g_pars := f_gen_test_hdlr_pars();
5245 g_pars.ra := '02'O; /* RA containing reason=LU */
5246
5247 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5248 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5249 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5250 var template uint3_t tsc := ?;
5251
5252 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5253 f_create_bssmap_exp(l3_enc);
5254 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5255 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5256
5257 /* we should now have a COMPL_L3 at the MSC */
5258 timer T := 10.0;
5259 T.start;
5260 alt {
5261 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5262 [] T.timeout {
5263 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5264 }
5265 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005266
5267 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005268}
5269testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5270 var MSC_ConnHdlr vc_conn;
5271 f_init(1, true);
5272 f_sleep(1.0);
5273 f_disable_all_sdcch();
5274 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5275 vc_conn.done;
5276 f_enable_all_sdcch();
5277 f_shutdown_helper();
5278}
5279
5280/* Request a signalling channel with all SDCCH exhausted, it is
5281 expected that no TCH will be selected for signalling and assigment will fail
5282 because it's dictated by VTY config */
5283testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5284 var RSL_Message rsl_unused, rsl_msg;
5285 var GsmRrMessage rr;
5286 f_init(1, false);
5287 f_sleep(1.0);
5288 f_vty_allow_tch_for_signalling(false, 0);
5289 f_disable_all_sdcch();
5290
5291 /* RA containing reason=LU */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005292 f_ipa_tx(ts_RSL_CHAN_RQD('02'O, 2342));
5293 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005294 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5295 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5296 setverdict(fail, "Expected reject");
5297 }
5298
5299 f_vty_allow_tch_for_signalling(true, 0);
5300 f_enable_all_sdcch();
5301 f_shutdown_helper();
5302}
5303
5304/* Request a voice channel with all SDCCH exhausted, it is
5305 * expected that TCH channel will be allocated since the VTY option is only
5306 * aimed at signalling requests */
5307private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5308 g_pars := f_gen_test_hdlr_pars();
5309 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5310
5311 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5312 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5313 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5314 var template uint3_t tsc := ?;
5315
5316 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5317 f_create_bssmap_exp(l3_enc);
5318 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5319 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5320
5321 /* we should now have a COMPL_L3 at the MSC */
5322 timer T := 10.0;
5323 T.start;
5324 alt {
5325 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5326 [] T.timeout {
5327 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5328 }
5329 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005330 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005331}
5332testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5333 var MSC_ConnHdlr vc_conn;
5334 f_init(1, true);
5335 f_sleep(1.0);
5336 f_vty_allow_tch_for_signalling(false, 0);
5337 f_disable_all_sdcch();
5338
5339 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5340 vc_conn.done;
5341
5342 f_vty_allow_tch_for_signalling(true, 0);
5343 f_enable_all_sdcch();
5344 f_shutdown_helper();
5345}
5346
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005347/* Test Osmux setup BSC<->MSC */
5348testcase TC_assignment_osmux_cn() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005349 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5350 var MSC_ConnHdlr vc_conn;
5351
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005352 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5353 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5354 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiyb9bf00f2022-09-14 15:35:37 +07005355 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02005356 pars.use_osmux_cn := true;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005357
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02005358 g_osmux_enabled_cn := true;
5359 f_init(1, true);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005360 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005361 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005362
5363 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5364 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005365
5366 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005367 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005368}
5369
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005370/* Test Osmux setup BTS<->BSC */
5371testcase TC_assignment_osmux_bts() runs on test_CT {
5372 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5373 var MSC_ConnHdlr vc_conn;
5374
5375 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5376 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5377 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005378 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005379 pars.use_osmux_bts := true;
5380
5381 g_osmux_enabled_bts := true;
5382 f_init(1, true);
5383 f_sleep(1.0);
5384 f_vty_amr_start_mode_set(false, "1");
5385
5386 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5387 vc_conn.done;
5388
5389 f_vty_amr_start_mode_restore(false);
5390 f_shutdown_helper();
5391}
5392
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +02005393/* Test non-AMR codecs still work fine as RTP when Osmux is enabled BTS<->BSC<->MSC */
5394testcase TC_assignment_codec_hr_osmux_on() runs on test_CT {
5395 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5396 var MSC_ConnHdlr vc_conn;
5397
5398 g_osmux_enabled_cn := true;
5399 g_osmux_enabled_bts := true;
5400 f_init(1, true);
5401 f_sleep(1.0);
5402 f_ctrs_bsc_and_bts_assignment_init(1);
5403
5404 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5405 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5406 vc_conn.done;
5407
5408 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
5409 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
5410 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
5411 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
5412 f_ctrs_bts_verify();
5413
5414 f_shutdown_helper();
5415}
5416
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005417/* Test Osmux setup BTS<->BSC<->MSC */
5418testcase TC_assignment_osmux() runs on test_CT {
5419 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5420 var MSC_ConnHdlr vc_conn;
5421
5422 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5423 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5424 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005425 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005426 pars.use_osmux_cn := true;
5427 pars.use_osmux_bts := true;
5428
5429 g_osmux_enabled_cn := true;
5430 g_osmux_enabled_bts := true;
5431 f_init(1, true);
5432 f_sleep(1.0);
5433 f_vty_amr_start_mode_set(false, "1");
5434
5435 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5436 vc_conn.done;
5437
5438 f_vty_amr_start_mode_restore(false);
5439 f_shutdown_helper();
5440}
5441
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005442/* test the procedure of the MSC requesting a Classmark Update:
5443 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5444 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005445private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005446 g_pars := f_gen_test_hdlr_pars();
5447
Harald Weltea0630032018-03-20 21:09:55 +01005448 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005449 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005450
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005451 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5452 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5453
Harald Welte898113b2018-01-31 18:32:21 +01005454 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5455 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5456 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005457
5458 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005459}
5460testcase TC_classmark() runs on test_CT {
5461 var MSC_ConnHdlr vc_conn;
5462 f_init(1, true);
5463 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005464 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005465 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005466 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005467}
5468
Harald Welteeddf0e92020-06-21 19:42:15 +02005469/* Send a CommonID from the simulated MSC and verify that the information is used to
5470 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5471private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5472 g_pars := f_gen_test_hdlr_pars();
5473 f_MscConnHdlr_init_vty();
5474
5475 f_create_chan_and_exp();
5476 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005477
5478 /* Send CommonID */
5479 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5480
5481 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5482 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5483 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5484
5485 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005486
5487 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005488}
5489testcase TC_common_id() runs on test_CT {
5490 var MSC_ConnHdlr vc_conn;
5491 f_init(1, true);
5492 f_sleep(1.0);
5493 vc_conn := f_start_handler(refers(f_tc_common_id));
5494 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005495 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005496}
5497
Harald Weltee3bd6582018-01-31 22:51:25 +01005498private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005499 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005500 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005501 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005502
Harald Weltee3bd6582018-01-31 22:51:25 +01005503 /* send the single message we want to send */
5504 f_rsl_send_l3(l3);
5505}
5506
5507private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5508 timer T := sec;
5509 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005510 T.start;
5511 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005512 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5513 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005514 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005515 }
5516 [] T.timeout {
5517 setverdict(pass);
5518 }
5519 }
5520}
5521
Harald Weltee3bd6582018-01-31 22:51:25 +01005522/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5523private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5524 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5525 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005526 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005527}
Harald Welte898113b2018-01-31 18:32:21 +01005528testcase TC_unsol_ass_fail() runs on test_CT {
5529 var MSC_ConnHdlr vc_conn;
5530 f_init(1, true);
5531 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005532 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005533 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005534 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005535}
Harald Welte552620d2017-12-16 23:21:36 +01005536
Harald Welteea99a002018-01-31 20:46:43 +01005537
5538/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5539private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005540 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5541 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005542 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005543}
5544testcase TC_unsol_ass_compl() runs on test_CT {
5545 var MSC_ConnHdlr vc_conn;
5546 f_init(1, true);
5547 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005548 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005549 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005550 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005551}
5552
5553
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005554/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5555private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005556 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5557 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005558 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005559}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005560testcase TC_unsol_ho_fail() runs on test_CT {
5561 var MSC_ConnHdlr vc_conn;
5562 f_init(1, true);
5563 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005564 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005565 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005566 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005567}
5568
5569
Harald Weltee3bd6582018-01-31 22:51:25 +01005570/* short message from MS should be ignored */
5571private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005572 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005573 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005574 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005575
5576 /* send short message */
5577 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5578 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005579 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005580}
5581testcase TC_err_82_short_msg() runs on test_CT {
5582 var MSC_ConnHdlr vc_conn;
5583 f_init(1, true);
5584 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005585 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005586 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005587 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005588}
5589
5590
Harald Weltee9e02e42018-01-31 23:36:25 +01005591/* 24.008 8.4 Unknown message must trigger RR STATUS */
5592private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5593 f_est_single_l3(ts_RRM_UL_REL('00'O));
5594 timer T := 3.0
5595 alt {
5596 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5597 setverdict(pass);
5598 }
5599 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005600 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005601 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005602 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005603}
5604testcase TC_err_84_unknown_msg() runs on test_CT {
5605 var MSC_ConnHdlr vc_conn;
5606 f_init(1, true);
5607 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005608 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005609 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005610 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005611}
5612
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005613/***********************************************************************
5614 * Handover
5615 ***********************************************************************/
5616
Harald Welte94e0c342018-04-07 11:33:23 +02005617/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5618private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5619runs on test_CT {
5620 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5621 " timeslot "&int2str(ts_nr)&" ";
5622 f_vty_transceive(BSCVTY, cmd & suffix);
5623}
5624
Harald Welte261af4b2018-02-12 21:20:39 +01005625/* 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 +07005626private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5627 uint8_t bts_nr, uint8_t trx_nr,
5628 in RslChannelNr chan_nr)
5629{
Harald Welte261af4b2018-02-12 21:20:39 +01005630 /* FIXME: resolve those from component-global state */
5631 var integer ts_nr := chan_nr.tn;
5632 var integer ss_nr;
5633 if (ischosen(chan_nr.u.ch0)) {
5634 ss_nr := 0;
5635 } else if (ischosen(chan_nr.u.lm)) {
5636 ss_nr := chan_nr.u.lm.sub_chan;
5637 } else if (ischosen(chan_nr.u.sdcch4)) {
5638 ss_nr := chan_nr.u.sdcch4.sub_chan;
5639 } else if (ischosen(chan_nr.u.sdcch8)) {
5640 ss_nr := chan_nr.u.sdcch8.sub_chan;
5641 } else {
5642 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005643 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005644 }
5645
5646 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5647 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005648 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005649}
5650
Neels Hofmeyr91401012019-07-11 00:42:35 +02005651/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5652 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5653 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5654 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5655 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005656private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5657 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5658{
5659 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005660}
5661
5662/* intra-BSC hand-over between BTS0 and BTS1 */
5663private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005664 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5665 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005666
5667 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5668 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5669
Harald Weltea0630032018-03-20 21:09:55 +01005670 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005671 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005672
5673 var HandoverState hs := {
5674 rr_ho_cmpl_seen := false,
5675 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005676 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005677 expect_target_tsc := c_BtsParams[1].tsc
Harald Welte261af4b2018-02-12 21:20:39 +01005678 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005679 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005680 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005681 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5682 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005683
5684 /* From the MGW perspective, a handover is is characterized by
5685 * performing one MDCX operation with the MGW. So we expect to see
5686 * one more MDCX during handover. */
5687 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5688
Harald Welte261af4b2018-02-12 21:20:39 +01005689 alt {
5690 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005691 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005692
Philipp Maier4dae0652018-11-12 12:03:26 +01005693 /* Since this is an internal handover we expect the BSC to inform the
5694 * MSC about the event */
5695 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5696
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005697 /* Check the amount of MGCP transactions is still consistant with the
5698 * test expectation */
5699 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005700
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005701 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5702
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005703 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5704 * 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 +02005705 f_verify_encr_info(chan_act);
5706
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005707 f_chan_act_verify_tsc(chan_act, c_BtsParams[1].tsc);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005708
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005709 f_perform_clear(RSL1, RSL1_PROC);
5710
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005711 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005712}
5713
5714testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005715 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005716 var MSC_ConnHdlr vc_conn;
5717 f_init(2, true);
5718 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005719
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005720 pars.expect_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005721
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005722 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005723
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005724 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005725 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005726
5727 /* from f_establish_fully() */
5728 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5729 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5730 /* from handover */
5731 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5732 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5733 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5734 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005735 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5736 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005737 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005738 f_shutdown_helper(ho := true);
Harald Welte261af4b2018-02-12 21:20:39 +01005739}
Harald Weltee9e02e42018-01-31 23:36:25 +01005740
Oliver Smith7eabd312021-07-12 14:18:56 +02005741function 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 +02005742 var MSC_ConnHdlr vc_conn;
5743 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5744 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5745
5746 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005747 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005748 f_sleep(1.0);
5749
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005750 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005751
5752 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5753 vc_conn.done;
5754
5755 /* from f_establish_fully() */
5756 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5757 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5758 /* from handover */
5759 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5760 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5761 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5762 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005763 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5764 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005765 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005766 f_vty_encryption_a5_reset();
Oliver Smith39f53072022-10-27 14:44:04 +02005767 f_shutdown_helper(ho := true);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005768}
5769
5770testcase TC_ho_int_a5_0() runs on test_CT {
5771 f_tc_ho_int_a5('01'O);
5772}
5773
5774testcase TC_ho_int_a5_1() runs on test_CT {
5775 f_tc_ho_int_a5('02'O);
5776}
5777
5778testcase TC_ho_int_a5_3() runs on test_CT {
5779 f_tc_ho_int_a5('08'O);
5780}
5781
5782testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005783 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005784}
5785
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005786/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5787private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5788 g_pars := f_gen_test_hdlr_pars();
5789 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5790 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005791
5792 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5793 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5794
5795 f_establish_fully(ass_cmd, exp_compl);
5796 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5797
5798 var HandoverState hs := {
5799 rr_ho_cmpl_seen := false,
5800 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005801 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005802 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005803 };
5804 /* issue hand-over command on VTY */
5805 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5806 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5807 f_rslem_suspend(RSL1_PROC);
5808
5809 /* From the MGW perspective, a handover is is characterized by
5810 * performing one MDCX operation with the MGW. So we expect to see
5811 * one more MDCX during handover. */
5812 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5813
5814 var RSL_Message rsl;
5815 var PDU_ML3_NW_MS l3;
5816 var RslChannelNr new_chan_nr;
5817 var GsmArfcn arfcn;
5818 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5819 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5820 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5821 setverdict(fail, "Expected handoverCommand");
5822 mtc.stop;
5823 }
5824 }
5825 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5826 new_chan_nr, arfcn);
5827
5828 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5829
5830 /* resume processing of RSL DChan messages, which was temporarily suspended
5831 * before performing a hand-over */
5832 f_rslem_resume(RSL1_PROC);
5833 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5834
5835 f_sleep(1.0);
5836
5837 /* Handover fails because no HANDO DET appears on the new lchan,
5838 * and the old lchan reports a Radio Link Failure. */
5839 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5840
5841 var PDU_BSSAP rx_clear_request;
5842 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5843 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5844 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5845
5846 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5847
5848 var MgcpCommand mgcp;
5849 interleave {
5850 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5851 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005852 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005853 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005854 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005855 }
5856 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005857 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005858 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005859 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005860 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005861 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5862 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5863 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005864 }
5865
5866 f_sleep(0.5);
5867 setverdict(pass);
5868}
5869testcase TC_ho_int_radio_link_failure() runs on test_CT {
5870 var MSC_ConnHdlr vc_conn;
5871 f_init(2, true);
5872 f_sleep(1.0);
5873
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005874 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005875
5876 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5877 vc_conn.done;
5878
5879 /* from f_establish_fully() */
5880 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5881 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5882 /* from handover */
5883 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5884 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5885 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5886 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005887 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5888 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005889 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005890 f_shutdown_helper(ho := true);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005891}
5892
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005893/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005894private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005895 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005896 var template MgcpResponse mgcp_resp;
5897 var MGCP_RecvFrom mrf;
5898 var template MgcpMessage msg_resp;
5899 var template MgcpMessage msg_dlcx := {
5900 command := tr_DLCX()
5901 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005902
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005903 if (g_pars.aoip) {
5904 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005905 log("Got first DLCX: ", mgcp);
5906 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005907 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005908
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005909 MGCP.receive(tr_DLCX()) -> value mgcp {
5910 log("Got second DLCX: ", mgcp);
5911 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5912 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005913 } else {
5914 /* For SCCPLite, BSC doesn't handle the MSC-side */
5915 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5916 log("Got first DLCX: ", mrf.msg.command);
5917 msg_resp := {
5918 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5919 }
5920 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5921 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005922 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005923}
5924
Oliver Smithc9a5f532022-10-21 11:32:23 +02005925private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit,
5926 boolean skip_meas_rep := false) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005927
Oliver Smithc9a5f532022-10-21 11:32:23 +02005928 if (not skip_meas_rep) {
5929 var NcellReports neighbor_rep := {
5930 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5931 };
5932 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5933 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5934 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005935
Oliver Smithc9a5f532022-10-21 11:32:23 +02005936 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
5937 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005938
5939 f_sleep(0.5);
5940 /* The MSC negotiates Handover Request and Handover Request Ack with
5941 * the other BSS and comes back with a BSSMAP Handover Command
5942 * containing an RR Handover Command coming from the target BSS... */
5943
5944 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5945 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5946 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5947 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5948 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5949
5950 /* expect the Handover Command to go out on RR */
5951 var RSL_Message rsl_ho_cmd
5952 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5953 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5954 var RSL_IE_Body rsl_ho_cmd_l3;
5955 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5956 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5957 setverdict(fail);
5958 } else {
5959 log("Found L3 Info: ", rsl_ho_cmd_l3);
5960 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5961 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5962 setverdict(fail);
5963 } else {
5964 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5965 setverdict(pass);
5966 }
5967 }
5968
5969 /* When the other BSS has reported a completed handover, this side is
5970 * torn down. */
5971
5972 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5973 var BssmapCause cause := enum2int(cause_val);
5974 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5975
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005976 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005977
5978 interleave {
5979 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5980 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5981 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005982 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5983 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5984 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005985 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005986 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005987}
5988
5989private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5990 g_pars := f_gen_test_hdlr_pars();
5991 var PDU_BSSAP ass_req := f_gen_ass_req();
5992 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5993 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5994 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5995 f_establish_fully(ass_req, exp_compl);
5996
5997 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005998}
5999testcase TC_ho_out_of_this_bsc() runs on test_CT {
6000 var MSC_ConnHdlr vc_conn;
6001
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01006002 f_init_vty();
6003 f_bts_0_cfg(BSCVTY,
6004 {"neighbor-list mode automatic",
6005 "handover 1",
6006 "handover algorithm 2",
6007 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006008 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01006009 "neighbor lac 99 arfcn 123 bsic any"});
6010 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6011
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006012 f_init(1, true);
6013 f_sleep(1.0);
6014
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006015 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006016
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006017 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
6018 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006019
6020 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6021 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6022 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6023 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6024 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6025 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
6026 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006027 f_shutdown_helper(ho := true);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006028}
6029
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006030private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6031 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07006032 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07006033 octetstring l3 := '0123456789'O)
6034runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02006035 /* The old lchan and conn should still be active. See that arbitrary L3
6036 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006037 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02006038 var template PDU_BSSAP exp_data := {
6039 discriminator := '1'B,
6040 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07006041 dlci := dlci,
6042 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02006043 pdu := {
6044 dtap := l3
6045 }
6046 };
6047 BSSAP.receive(exp_data);
6048 setverdict(pass);
6049}
6050
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006051private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6052 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006053 template (value) OCT1 dlci := '00'O,
6054 octetstring l3 := '0123456789'O)
6055runs on MSC_ConnHdlr {
6056 BSSAP.send(PDU_BSSAP:{
6057 discriminator := '1'B,
6058 spare := '0000000'B,
6059 dlci := dlci,
6060 lengthIndicator := lengthof(l3),
6061 pdu := {
6062 dtap := l3
6063 }
6064 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006065 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006066 setverdict(pass);
6067}
6068
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006069/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
6070 * simply never sends a BSSMAP Handover Command. */
6071private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006072 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006073
6074 var PDU_BSSAP ass_req := f_gen_ass_req();
6075 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6076 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6077 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6078 f_establish_fully(ass_req, exp_compl);
6079
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006080 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006081 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6082
6083 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6084
6085 /* osmo-bsc should time out 10 seconds after the handover started.
6086 * Let's give it a bit extra. */
6087 f_sleep(15.0);
6088
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006089 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006090 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006091 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006092}
6093testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
6094 var MSC_ConnHdlr vc_conn;
6095
6096 f_init(1, true);
6097 f_sleep(1.0);
6098
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006099 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006100
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006101 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
6102 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006103
6104 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6105 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6106 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6107 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6108 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6109 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6110 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006111 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006112}
6113
6114/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
6115 * RR Handover Failure. */
6116private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006117 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006118
6119 var PDU_BSSAP ass_req := f_gen_ass_req();
6120 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6121 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6122 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6123 f_establish_fully(ass_req, exp_compl);
6124
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006125 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006126 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6127
6128 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6129
6130 f_sleep(0.5);
6131 /* The MSC negotiates Handover Request and Handover Request Ack with
6132 * the other BSS and comes back with a BSSMAP Handover Command
6133 * containing an RR Handover Command coming from the target BSS... */
6134
6135 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6136 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6137 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6138 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6139 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6140
6141 /* expect the Handover Command to go out on RR */
6142 var RSL_Message rsl_ho_cmd
6143 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6144 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6145 var RSL_IE_Body rsl_ho_cmd_l3;
6146 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6147 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6148 setverdict(fail);
6149 } else {
6150 log("Found L3 Info: ", rsl_ho_cmd_l3);
6151 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6152 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6153 setverdict(fail);
6154 } else {
6155 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6156 setverdict(pass);
6157 }
6158 }
6159
6160 f_sleep(0.2);
6161 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6162
6163 /* Should tell the MSC about the failure */
6164 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6165
6166 f_sleep(1.0);
6167
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006168 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006169 f_sleep(1.0);
6170
6171 setverdict(pass);
6172 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006173 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006174}
6175testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
6176 var MSC_ConnHdlr vc_conn;
6177
6178 f_init(1, true);
6179 f_sleep(1.0);
6180
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006181 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006182
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006183 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
6184 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006185
6186 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6187 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6188 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6189 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6190 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6191 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
6192 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006193 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006194}
6195
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006196/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
6197 * (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 +02006198 * and the lchan is released. */
6199private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006200 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006201
6202 var PDU_BSSAP ass_req := f_gen_ass_req();
6203 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6204 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6205 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6206 f_establish_fully(ass_req, exp_compl);
6207
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006208 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006209 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6210
6211 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6212
6213 f_sleep(0.5);
6214 /* The MSC negotiates Handover Request and Handover Request Ack with
6215 * the other BSS and comes back with a BSSMAP Handover Command
6216 * containing an RR Handover Command coming from the target BSS... */
6217
6218 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6219 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6220 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6221 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6222 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6223
6224 /* expect the Handover Command to go out on RR */
6225 var RSL_Message rsl_ho_cmd
6226 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6227 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6228 var RSL_IE_Body rsl_ho_cmd_l3;
6229 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6230 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6231 setverdict(fail);
6232 } else {
6233 log("Found L3 Info: ", rsl_ho_cmd_l3);
6234 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6235 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6236 setverdict(fail);
6237 } else {
6238 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6239 setverdict(pass);
6240 }
6241 }
6242
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006243 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6244 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6245 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006246
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006247 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006248 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6249 log("Got BSSMAP Clear Request");
6250 /* Instruct BSC to clear channel */
6251 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6252 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6253
6254 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006255 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006256 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6257 log("Got Deact SACCH");
6258 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006259 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006260 log("Got RR Release");
6261 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006262 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006263 log("Got RF Chan Rel");
6264 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006265 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006266 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006267 }
6268
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006269 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006270 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006271 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006272
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006273 setverdict(pass);
6274 f_sleep(1.0);
6275}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006276testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006277 var MSC_ConnHdlr vc_conn;
6278
6279 f_init(1, true);
6280 f_sleep(1.0);
6281
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006282 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006283
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006284 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006285 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006286
6287 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6288 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6289 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6290 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6291 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6292 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6293 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006294 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006295}
6296
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006297private 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 +01006298 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006299 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6300 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6301 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6302 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6303 * before we get started. */
6304 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6305 f_rslem_register(0, new_chan_nr);
6306 g_chan_nr := new_chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06006307 var uint3_t expect_target_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006308 f_sleep(1.0);
6309
6310 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6311 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006312 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006313
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006314 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6315 cell_id_source := g_pars.cell_id_source,
6316 oldToNewBSSIEs := oldToNewBSSIEs,
6317 enc := g_pars.encr);
6318 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6319 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6320 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6321 } else {
6322 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6323 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6324 BSSAP.send(ho_req);
6325 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006326
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006327 alt {
6328 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6329 if (g_pars.expect_ho_fail) {
6330 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6331 "Expected Handover Request to fail, but got Handover Request Ack")
6332 }
6333 }
6334 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6335 if (not g_pars.expect_ho_fail) {
6336 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6337 "Expected Handover Request to succeed, but got Handover Failure")
6338 }
6339 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6340 // For now just accept any cause.
6341 BSSAP.receive(tr_BSSMAP_ClearRequest);
6342 setverdict(pass);
6343 return;
6344 }
6345 }
6346
Oliver Smith7a8594a2023-02-13 14:30:49 +01006347 if (g_pars.expect_ho_fail_lchan_est) {
6348 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6349 setverdict(pass);
Oliver Smitha1cbec52023-02-21 12:44:12 +01006350
6351 /* When we let MGCP MDCX run into a timeout, it's still in the
6352 * queue and additionally after BSSAP HandoverFailure, two DLCX
6353 * get sent. */
6354 if (g_pars.ignore_mgw_mdcx) {
6355 MGCP.receive(tr_MDCX);
6356 MGCP.receive(tr_DLCX);
6357 MGCP.receive(tr_DLCX);
6358 }
Oliver Smith7a8594a2023-02-13 14:30:49 +01006359 return;
6360 }
6361
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006362 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6363
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006364 /* we're sure that the channel activation is done now, verify the parameters in it */
6365 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6366 f_verify_encr_info(chan_act);
6367 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006368
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006369 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6370 if (not g_pars.aoip) {
6371 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6372 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6373 }
6374 /* TODO: check actual codecs? */
6375 } else {
6376 if (g_pars.aoip) {
6377 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6378 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6379 }
6380 }
6381
6382 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6383 if (not g_pars.aoip) {
6384 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6385 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6386 }
6387 /* TODO: check actual codec? */
6388 } else {
6389 if (g_pars.aoip) {
6390 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6391 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6392 }
6393 }
6394
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006395 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006396 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6397 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6398 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6399 log("L3 Info in HO Request Ack is ", ho_command);
6400
6401 var GsmArfcn arfcn;
6402 var RslChannelNr actual_new_chan_nr;
6403 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6404 actual_new_chan_nr, arfcn);
6405
6406 if (actual_new_chan_nr != new_chan_nr) {
6407 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6408 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6409 setverdict(fail);
6410 return;
6411 }
6412 log("Handover Command chan_nr is", actual_new_chan_nr);
6413
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006414 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6415 if (not match(got_tsc, expect_target_tsc)) {
6416 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6417 expect_target_tsc, " got ", got_tsc);
6418 mtc.stop;
6419 } else {
6420 log("handoverCommand: verified TSC = ", got_tsc);
6421 }
6422
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006423 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6424 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6425 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6426 var template (present) CipherModeSetting_TV tr_cms := {
6427 sC := '0'B, /* no ciphering by default */
6428 algorithmIdentifier := '000'B,
6429 elementIdentifier := ?
6430 };
6431 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6432 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6433 tr_cms.sC := '1'B;
6434 }
6435 if (not match(cms, tr_cms)) {
6436 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6437 cms, ", expected: ", tr_cms);
6438 }
6439 } else {
6440 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6441 }
6442
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006443 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6444 * tells the MS to handover to the new lchan. Here comes the new MS on
6445 * the new lchan with a Handover RACH: */
6446
6447 /* send handover detect */
6448
6449 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6450
6451 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6452
6453 /* send handover complete over the new channel */
6454
6455 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6456 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6457 enc_PDU_ML3_MS_NW(l3_tx)));
6458
6459 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006460 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006461 setverdict(pass);
6462}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006463
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006464private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006465 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006466 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6467 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6468 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006469 }
6470 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006471 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006472 } else {
6473 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006474 }
6475 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006476 if (g_pars.expect_ho_fail) {
6477 f_perform_clear_no_lchan();
Oliver Smith7a8594a2023-02-13 14:30:49 +01006478 } else if (g_pars.expect_ho_fail_lchan_est) {
6479 BSSAP.receive(tr_BSSMAP_ClearRequest);
6480 f_perform_clear_no_lchan();
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006481 } else {
6482 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6483 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006484 setverdict(pass);
6485}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006486function 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 +01006487 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006488
6489 f_init(1, true);
6490 f_sleep(1.0);
6491
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006492 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006493 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006494
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006495 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6496 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006497
6498 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6499 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006500
6501 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006502 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006503 if (pars.expect_ho_fail) {
6504 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6505 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
Oliver Smith7a8594a2023-02-13 14:30:49 +01006506 } else if (pars.expect_ho_fail_lchan_est) {
6507 f_ctrs_bsc_and_bts_add(0, "handover:error");
6508 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006509 } else {
6510 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6511 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6512 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006513 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006514
6515 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006516}
6517
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006518testcase TC_ho_into_this_bsc() runs on test_CT {
6519 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6520 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006521 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006522}
6523
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006524function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6525 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006526 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006527 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006528 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006529 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Oliver Smith39f53072022-10-27 14:44:04 +02006530 f_shutdown_helper(ho := true);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006531}
6532
6533testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006534 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006535}
6536
6537testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006538 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006539}
6540
6541testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006542 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006543}
6544
6545testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006546 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006547}
6548
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006549/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6550 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6551 *
6552 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6553 * omitted.
6554 *
6555 * Related: SYS#5839
6556 */
6557testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6558 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6559}
6560
6561testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6562 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6563}
6564
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006565/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6566testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6567 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6568 expect_fail := true); // 0x18 = A5/3 and A5/4
6569}
6570
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006571testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6572 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6573 pars.host_aoip_tla := "::6";
6574 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006575 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006576}
6577
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006578/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006579 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006580 channel is later released (RR CHannel Release), should trigger inclusion of
6581 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6582 neighbors. */
6583testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6584 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6585 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006586 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006587 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006588
6589 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6590 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6591 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006592 f_shutdown_helper(ho := true);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006593}
6594
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006595/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6596testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6597 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6598 pars.encr := f_encr_params('08'O); /* only A5/3 */
6599 pars.last_used_eutran_plmn := '323454'O;
6600 pars.exp_fast_return := true;
6601 f_tc_ho_into_this_bsc_main(pars);
6602
6603 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6604 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6605 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006606 f_shutdown_helper(ho := true);
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006607}
6608
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006609/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6610 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6611 list when the channel is released. */
6612testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6613 f_init_vty();
6614 f_vty_allow_srvcc_fast_return(true, 0)
6615
6616 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6617 pars.last_used_eutran_plmn := '323454'O;
6618 pars.exp_fast_return := false;
6619 f_tc_ho_into_this_bsc_main(pars);
6620 f_vty_allow_srvcc_fast_return(false, 0);
6621 f_shutdown_helper();
6622}
6623
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006624/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6625testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6626 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6627 pars.last_used_eutran_plmn := '323454'O;
6628 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6629 f_tc_ho_into_this_bsc_main(pars);
6630
6631 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6632 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6633 f_ctrs_bsc_and_bts_verify();
6634 f_shutdown_helper();
6635}
6636
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006637private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6638 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6639 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6640 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6641 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6642 setverdict(pass);
6643}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006644
6645private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6646 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006647 var MSC_ConnHdlr vc_conn;
6648 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6649
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006650 f_init_vty();
6651 f_bts_0_cfg(BSCVTY,
6652 {"neighbor-list mode automatic",
6653 "handover 1",
6654 "handover algorithm 2",
6655 "handover2 window rxlev averaging 1",
6656 "no neighbors",
6657 "neighbor lac 99 arfcn 123 bsic any"});
6658 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6659
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006660 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006661 if (disable_fast_return) {
6662 f_vty_allow_srvcc_fast_return(true, 0);
6663 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006664 f_sleep(1.0);
6665
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006666 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006667
6668 pars.last_used_eutran_plmn := '323454'O;
6669 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6670 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6671
6672 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6673 vc_conn.done;
6674
6675 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6676 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6677 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6678 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6679 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6680 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006681
6682 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6683 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006684 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006685
6686 if (disable_fast_return) {
6687 f_vty_allow_srvcc_fast_return(false, 0);
6688 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006689 f_shutdown_helper();
6690}
6691
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006692/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6693 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6694 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6695 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6696testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6697 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6698}
6699/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6700 * independently of fast-reture allowed/forbidden in local BTS */
6701testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6702 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6703}
6704
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006705private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6706 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6707 f_rslem_register(0, new_chan_nr);
6708 g_chan_nr := new_chan_nr;
6709 f_sleep(1.0);
6710
6711 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6712 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6713 activate(as_Media());
6714
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006715 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006716 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006717 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006718
6719 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6720
6721 var PDU_BSSAP rx_bssap;
6722 var octetstring ho_command_str;
6723
6724 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6725
6726 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6727 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6728 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6729 log("L3 Info in HO Request Ack is ", ho_command);
6730
6731 var GsmArfcn arfcn;
6732 var RslChannelNr actual_new_chan_nr;
6733 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6734 actual_new_chan_nr, arfcn);
6735
6736 if (actual_new_chan_nr != new_chan_nr) {
6737 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6738 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6739 setverdict(fail);
6740 return;
6741 }
6742 log("Handover Command chan_nr is", actual_new_chan_nr);
6743
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006744 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6745 f_sleep(1.0);
6746
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006747 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6748 * tells the MS to handover to the new lchan. In this case, the MS
6749 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6750 * Handover Failure to the MSC. The procedure according to 3GPP TS
6751 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6752 * BSSMAP Clear Command: */
6753
6754 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6755 var BssmapCause cause := enum2int(cause_val);
6756 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6757
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006758 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006759 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006760 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006761
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006762 setverdict(pass);
6763 f_sleep(1.0);
6764
6765 setverdict(pass);
6766}
6767testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6768 var MSC_ConnHdlr vc_conn;
6769 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6770
6771 f_init(1, true);
6772 f_sleep(1.0);
6773
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006774 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006775
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006776 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6777 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006778
6779 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6780 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006781
6782 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6783 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6784 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6785 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6786 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006787 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006788}
6789
6790private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6791 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6792 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6793 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6794 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6795 * before we get started. */
6796 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6797 f_rslem_register(0, new_chan_nr);
6798 g_chan_nr := new_chan_nr;
6799 f_sleep(1.0);
6800
6801 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6802 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6803 activate(as_Media());
6804
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006805 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006806 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006807 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006808
6809 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6810
6811 var PDU_BSSAP rx_bssap;
6812 var octetstring ho_command_str;
6813
6814 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6815
6816 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6817 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6818 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6819 log("L3 Info in HO Request Ack is ", ho_command);
6820
6821 var GsmArfcn arfcn;
6822 var RslChannelNr actual_new_chan_nr;
6823 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6824 actual_new_chan_nr, arfcn);
6825
6826 if (actual_new_chan_nr != new_chan_nr) {
6827 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6828 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6829 setverdict(fail);
6830 return;
6831 }
6832 log("Handover Command chan_nr is", actual_new_chan_nr);
6833
6834 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6835 * tells the MS to handover to the new lchan. Here comes the new MS on
6836 * the new lchan with a Handover RACH: */
6837
6838 /* send handover detect */
6839
6840 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6841
6842 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6843
6844 /* The MSC chooses to clear the connection now, maybe we got the
6845 * Handover RACH on the new cell but the MS still signaled Handover
6846 * Failure to the old BSS? */
6847
6848 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6849 var BssmapCause cause := enum2int(cause_val);
6850 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6851
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006852 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006853 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006854 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006855
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006856 f_sleep(1.0);
6857}
6858testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6859 var MSC_ConnHdlr vc_conn;
6860 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6861
6862 f_init(1, true);
6863 f_sleep(1.0);
6864
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006865 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006866
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006867 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6868 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006869
6870 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6871 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006872
6873 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6874 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6875 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6876 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6877 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006878 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006879}
6880
6881/* The new BSS's lchan times out before the MSC decides that handover failed. */
6882private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6883 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6884 f_rslem_register(0, new_chan_nr);
6885 g_chan_nr := new_chan_nr;
6886 f_sleep(1.0);
6887
6888 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6889 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Oliver Smith735b47c2023-02-15 16:03:54 +01006890 activate(as_Media());
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006891
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006892 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006893 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006894 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006895
6896 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6897
6898 var PDU_BSSAP rx_bssap;
6899 var octetstring ho_command_str;
6900
6901 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6902
6903 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6904 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6905 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6906 log("L3 Info in HO Request Ack is ", ho_command);
6907
6908 var GsmArfcn arfcn;
6909 var RslChannelNr actual_new_chan_nr;
6910 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6911 actual_new_chan_nr, arfcn);
6912
6913 if (actual_new_chan_nr != new_chan_nr) {
6914 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6915 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6916 setverdict(fail);
6917 return;
6918 }
6919 log("Handover Command chan_nr is", actual_new_chan_nr);
6920
6921 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6922 * tells the MS to handover to the new lchan. But the MS never shows up
6923 * on the new lchan. */
6924
6925 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6926
6927 /* Did osmo-bsc also send a Clear Request? */
6928 timer T := 0.5;
6929 T.start;
6930 alt {
6931 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6932 [] T.timeout { }
6933 }
6934
6935 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6936 * asked for it, this is a Handover Failure after all). */
6937
6938 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6939 var BssmapCause cause := enum2int(cause_val);
6940 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6941
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006942 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006943 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006944 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006945
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006946 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006947}
6948testcase TC_ho_in_fail_no_detect() runs on test_CT {
6949 var MSC_ConnHdlr vc_conn;
6950 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6951
6952 f_init(1, true);
6953 f_sleep(1.0);
6954
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006955 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006956
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006957 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6958 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006959
6960 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6961 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006962
6963 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6964 f_ctrs_bsc_and_bts_add(0, "handover:error");
6965 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6966 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6967 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006968 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006969}
6970
6971/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6972private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6973 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6974 f_rslem_register(0, new_chan_nr);
6975 g_chan_nr := new_chan_nr;
6976 f_sleep(1.0);
6977
6978 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6979 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Oliver Smith735b47c2023-02-15 16:03:54 +01006980 activate(as_Media());
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006981
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006982 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006983 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006984 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006985
6986 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6987
6988 var PDU_BSSAP rx_bssap;
6989 var octetstring ho_command_str;
6990
6991 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6992
6993 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6994 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6995 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6996 log("L3 Info in HO Request Ack is ", ho_command);
6997
6998 var GsmArfcn arfcn;
6999 var RslChannelNr actual_new_chan_nr;
7000 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
7001 actual_new_chan_nr, arfcn);
7002
7003 if (actual_new_chan_nr != new_chan_nr) {
7004 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
7005 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
7006 setverdict(fail);
7007 return;
7008 }
7009 log("Handover Command chan_nr is", actual_new_chan_nr);
7010
7011 /* Now the MSC forwards the RR Handover Command to the other BSC, which
7012 * tells the MS to handover to the new lchan. But the MS never shows up
7013 * on the new lchan. */
7014
7015 BSSAP.receive(tr_BSSMAP_HandoverFailure);
7016
7017 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007018 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02007019
7020 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007021 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
7022 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
7023 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02007024 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007025 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007026 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007027
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007028 f_sleep(1.0);
7029}
7030testcase TC_ho_in_fail_no_detect2() runs on test_CT {
7031 var MSC_ConnHdlr vc_conn;
7032 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7033
Oliver Smith735b47c2023-02-15 16:03:54 +01007034 pars.fail_on_dlcx := false;
7035
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007036 f_init(1, true);
7037 f_sleep(1.0);
7038
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007039 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007040
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007041 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
7042 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007043
7044 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
7045 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007046
7047 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7048 f_ctrs_bsc_and_bts_add(0, "handover:error");
7049 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
7050 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
7051 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007052 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007053}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01007054
Oliver Smith7a8594a2023-02-13 14:30:49 +01007055testcase TC_ho_in_fail_mgw_mdcx_timeout() runs on test_CT {
7056 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7057
7058 pars.ignore_mgw_mdcx := true;
7059 pars.expect_ho_fail_lchan_est := true;
7060
7061 f_tc_ho_into_this_bsc_main(pars);
7062 f_shutdown_helper(ho := true);
7063}
7064
Oliver Smith4eed06f2023-02-15 15:43:19 +01007065testcase TC_ho_in_fail_ipa_crcx_timeout() runs on test_CT {
7066 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7067
7068 pars.ignore_ipa_media := true;
7069 pars.expect_ho_fail_lchan_est := true;
7070 pars.fail_on_dlcx := false;
7071
7072 f_tc_ho_into_this_bsc_main(pars);
7073 f_shutdown_helper(ho := true);
7074}
7075
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01007076/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
7077 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
7078 * empty N-Connect case. */
7079testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
7080 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7081 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
7082 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02007083 f_shutdown_helper(ho := true);
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01007084}
7085
Neels Hofmeyr91401012019-07-11 00:42:35 +02007086type record of charstring Commands;
7087
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007088private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02007089{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007090 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007091 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007092 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007093 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007094 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02007095}
7096
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01007097private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
7098{
7099 f_vty_enter_cfg_cs7_inst(pt, 0);
7100 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
7101 f_vty_transceive(pt, cmds[i]);
7102 }
7103 f_vty_transceive(pt, "end");
7104}
7105
Neels Hofmeyr91401012019-07-11 00:42:35 +02007106private function f_probe_for_handover(charstring log_label,
7107 charstring log_descr,
7108 charstring handover_vty_cmd,
7109 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007110 boolean is_inter_bsc_handover := false,
7111 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02007112runs on MSC_ConnHdlr
7113{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02007114 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
7115 * lchans to be established on bts 1 or bts 2. */
7116 f_rslem_suspend(RSL1_PROC);
7117 f_rslem_suspend(RSL2_PROC);
7118
Neels Hofmeyr91401012019-07-11 00:42:35 +02007119 var RSL_Message rsl;
7120
7121 var charstring log_msg := " (expecting handover)"
7122 if (not expect_handover) {
7123 log_msg := " (expecting NO handover)";
7124 }
7125 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
7126 f_vty_transceive(BSCVTY, handover_vty_cmd);
7127
Neels Hofmeyr91401012019-07-11 00:42:35 +02007128 timer T := 2.0;
7129 T.start;
7130
7131 alt {
7132 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
7133 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
7134 log("Rx L3 from net: ", l3);
7135 if (ischosen(l3.msgs.rrm.handoverCommand)) {
7136 var RslChannelNr new_chan_nr;
7137 var GsmArfcn arfcn;
7138 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
7139 new_chan_nr, arfcn);
7140 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
7141 log(l3.msgs.rrm.handoverCommand);
7142
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007143 /* Verify correct TSC in handoverCommand */
7144 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
7145 if (not match(got_tsc, expect_target_tsc)) {
7146 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
7147 expect_target_tsc, " got ", got_tsc);
7148 mtc.stop;
7149 } else {
7150 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
7151 expect_target_tsc, ")");
7152 }
7153
Neels Hofmeyr91401012019-07-11 00:42:35 +02007154 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
7155 * matter on which BTS it really is, we're not going to follow through an entire handover
7156 * anyway. */
7157 f_rslem_register(0, new_chan_nr, RSL1_PROC);
7158 f_rslem_resume(RSL1_PROC);
7159 f_rslem_register(0, new_chan_nr, RSL2_PROC);
7160 f_rslem_resume(RSL2_PROC);
7161
7162 if (expect_handover and not is_inter_bsc_handover) {
7163 setverdict(pass);
7164 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
7165 } else {
7166 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
7167 & log_label & ": " & log_descr);
7168 }
7169
7170 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
7171 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
7172 * Handover Failure. */
7173 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
7174
7175 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
7176 f_sleep(0.5);
7177 RSL1.clear;
7178 RSL2.clear;
7179 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
7180 break;
7181 } else {
7182 repeat;
7183 }
7184 }
7185 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
7186 if (expect_handover and is_inter_bsc_handover) {
7187 setverdict(pass);
7188 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
7189 } else {
7190 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
7191 & log_label & ": " & log_descr);
7192 }
7193
7194 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
7195
7196 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
7197 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
7198 * setting a short timeout and waiting is the only way. */
7199 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
7200 f_sleep(1.5);
7201 log("f_probe_for_handover(" & log_label & "): ...done");
7202
7203 break;
7204 }
7205 [] T.timeout {
7206 if (expect_handover) {
7207 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
7208 & log_label & ": " & log_descr);
7209 } else {
7210 setverdict(pass);
7211 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
7212 }
7213 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
7214 break;
7215 }
7216 }
7217
7218 f_rslem_resume(RSL1_PROC);
7219 f_rslem_resume(RSL2_PROC);
7220 f_sleep(3.0);
7221 RSL.clear;
7222
7223 log("f_probe_for_handover(" & log_label & "): done clearing");
7224}
7225
7226/* Test the effect of various neighbor configuration scenarios:
7227 *
7228 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
7229 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
7230 */
7231private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
7232 g_pars := f_gen_test_hdlr_pars();
7233 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
7234 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007235
7236 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
7237 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
7238
7239 /* Establish lchan at bts 0 */
7240 f_establish_fully(ass_cmd, exp_compl);
7241
7242 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
7243 f_vty_enter_cfg_network(BSCVTY);
7244 f_vty_transceive(BSCVTY, "timer T7 1");
7245 f_vty_transceive(BSCVTY, "end");
7246}
7247
7248private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
7249 f_tc_ho_neighbor_config_start();
7250
7251 /*
7252 * bts 0 ARFCN 871 BSIC 10
7253 * bts 1 ARFCN 871 BSIC 11
7254 * bts 2 ARFCN 871 BSIC 12
7255 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7256 */
7257
7258 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007259 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007260 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
7261 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007262 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007263
7264 f_probe_for_handover("1.b", "HO to unknown cell does not start",
7265 "handover any to arfcn 13 bsic 39",
7266 false);
7267
7268 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
7269 "handover any to arfcn 871 bsic 12",
7270 false);
7271
7272 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
7273 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007274 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007275
7276 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007277}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007278testcase TC_ho_neighbor_config_1() runs on test_CT {
7279 var MSC_ConnHdlr vc_conn;
7280 f_init(3, true, guard_timeout := 60.0);
7281 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007282 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007283 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7284 vc_conn.done;
7285
7286 /* f_tc_ho_neighbor_config_start() */
7287 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7288 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7289
7290 /* 1.a */
7291 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7292 * handover quickly by sending a Handover Failure message. */
7293 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7294 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7295 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7296 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007297 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7298 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007299
7300 /* 1.b */
7301 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7302 f_ctrs_bsc_and_bts_add(0, "handover:error");
7303
7304 /* 1.c */
7305 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7306 f_ctrs_bsc_and_bts_add(0, "handover:error");
7307
7308 /* 1.d */
7309 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7310 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7311 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7312 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007313 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7314 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007315
7316 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007317 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007318}
7319
Neels Hofmeyr91401012019-07-11 00:42:35 +02007320private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7321 f_tc_ho_neighbor_config_start();
7322
7323 /*
7324 * bts 0 ARFCN 871 BSIC 10
7325 * bts 1 ARFCN 871 BSIC 11
7326 * bts 2 ARFCN 871 BSIC 12
7327 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7328 */
7329
7330 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007331 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007332 f_sleep(0.5);
7333
7334 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7335 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007336 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007337
7338 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7339 "handover any to arfcn 871 bsic 12",
7340 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007341 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007342}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007343testcase TC_ho_neighbor_config_2() runs on test_CT {
7344 var MSC_ConnHdlr vc_conn;
7345 f_init(3, true, guard_timeout := 50.0);
7346 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007347 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007348 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7349 vc_conn.done;
7350
7351 /* f_tc_ho_neighbor_config_start() */
7352 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7353 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7354
7355 /* 2.a */
7356 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7357 * handover quickly by sending a Handover Failure message. */
7358 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7359 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7360 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7361 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007362 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7363 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007364
7365 /* 2.b */
7366 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7367 f_ctrs_bsc_and_bts_add(0, "handover:error");
7368
7369 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007370 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007371}
7372
Neels Hofmeyr91401012019-07-11 00:42:35 +02007373private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7374 f_tc_ho_neighbor_config_start();
7375
7376 /*
7377 * bts 0 ARFCN 871 BSIC 10
7378 * bts 1 ARFCN 871 BSIC 11
7379 * bts 2 ARFCN 871 BSIC 12
7380 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7381 */
7382
7383 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007384 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007385 f_sleep(0.5);
7386
7387 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7388 "handover any to arfcn 871 bsic 11",
7389 false);
7390 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",
7391 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007392 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007393 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007394}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007395testcase TC_ho_neighbor_config_3() runs on test_CT {
7396 var MSC_ConnHdlr vc_conn;
7397 f_init(3, true, guard_timeout := 50.0);
7398 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007399 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007400 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7401 vc_conn.done;
7402
7403 /* f_tc_ho_neighbor_config_start() */
7404 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7405 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7406
7407 /* 3.a */
7408 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7409 f_ctrs_bsc_and_bts_add(0, "handover:error");
7410
7411 /* 3.b */
7412 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7413 * handover quickly by sending a Handover Failure message. */
7414 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7415 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7416 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7417 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007418 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7419 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007420
7421 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007422 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007423}
7424
Neels Hofmeyr91401012019-07-11 00:42:35 +02007425private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7426 f_tc_ho_neighbor_config_start();
7427
7428 /*
7429 * bts 0 ARFCN 871 BSIC 10
7430 * bts 1 ARFCN 871 BSIC 11
7431 * bts 2 ARFCN 871 BSIC 12
7432 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7433 */
7434
7435 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007436 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007437 f_sleep(0.5);
7438
7439 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7440 "handover any to arfcn 871 bsic 11",
7441 false);
7442 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7443 "handover any to arfcn 871 bsic 12",
7444 false);
7445 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7446 "handover any to arfcn 123 bsic 45",
7447 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007448 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007449}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007450testcase TC_ho_neighbor_config_4() runs on test_CT {
7451 var MSC_ConnHdlr vc_conn;
7452 f_init(3, true, guard_timeout := 50.0);
7453 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007454 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007455 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7456 vc_conn.done;
7457
7458 /* f_tc_ho_neighbor_config_start() */
7459 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7460 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7461
7462 /* 4.a */
7463 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7464 f_ctrs_bsc_and_bts_add(0, "handover:error");
7465
7466 /* 4.b */
7467 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7468 f_ctrs_bsc_and_bts_add(0, "handover:error");
7469
7470 /* 4.c */
7471 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7472 * handover quickly by timing out after the Handover Required message */
7473 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7474 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7475 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7476 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7477
7478 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007479 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007480}
7481
Neels Hofmeyr91401012019-07-11 00:42:35 +02007482private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7483 f_tc_ho_neighbor_config_start();
7484
7485 /*
7486 * bts 0 ARFCN 871 BSIC 10
7487 * bts 1 ARFCN 871 BSIC 11
7488 * bts 2 ARFCN 871 BSIC 12
7489 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7490 */
7491
7492 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 +02007493 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007494 f_sleep(0.5);
7495
7496 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7497 "handover any to arfcn 871 bsic 12",
7498 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007499 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007500}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007501testcase TC_ho_neighbor_config_5() runs on test_CT {
7502 var MSC_ConnHdlr vc_conn;
7503 f_init(3, true);
7504 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007505 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007506 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7507 vc_conn.done;
7508
7509 /* f_tc_ho_neighbor_config_start() */
7510 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7511 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7512
7513 /* 5 */
7514 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7515 * handover quickly by timing out after the Handover Required message */
7516 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7517 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7518 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7519 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7520
7521 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007522 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007523}
7524
Neels Hofmeyr91401012019-07-11 00:42:35 +02007525private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7526 f_tc_ho_neighbor_config_start();
7527
7528 /*
7529 * bts 0 ARFCN 871 BSIC 10
7530 * bts 1 ARFCN 871 BSIC 11
7531 * bts 2 ARFCN 871 BSIC 12
7532 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7533 */
7534
7535 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7536 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007537 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007538 f_sleep(0.5);
7539
7540 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7541 "handover any to arfcn 871 bsic 12",
7542 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007543 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007544}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007545testcase TC_ho_neighbor_config_6() runs on test_CT {
7546 var MSC_ConnHdlr vc_conn;
7547 f_init(3, true);
7548 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007549 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007550 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7551 vc_conn.done;
7552
7553 /* f_tc_ho_neighbor_config_start() */
7554 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7555 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7556
7557 /* 6.a */
7558 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7559 * handover quickly by timing out after the Handover Required message */
7560 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7561 f_ctrs_bsc_and_bts_add(0, "handover:error");
7562
7563 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007564 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007565}
7566
Neels Hofmeyr91401012019-07-11 00:42:35 +02007567private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7568 f_tc_ho_neighbor_config_start();
7569
7570 /*
7571 * bts 0 ARFCN 871 BSIC 10
7572 * bts 1 ARFCN 871 BSIC 11
7573 * bts 2 ARFCN 871 BSIC 12
7574 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7575 */
7576
7577 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7578 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007579 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007580 f_sleep(0.5);
7581
7582 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7583 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007584 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007585 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7586 "handover any to arfcn 123 bsic 45",
7587 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007588 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007589}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007590testcase TC_ho_neighbor_config_7() runs on test_CT {
7591 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007592 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007593 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007594 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007595 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7596 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007597
7598 /* f_tc_ho_neighbor_config_start() */
7599 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7600 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7601
7602 /* 7.a */
7603 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7604 * handover quickly by sending a Handover Failure message. */
7605 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7606 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7607 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7608 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007609 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7610 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007611
7612 /* 7.b */
7613 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7614 * handover quickly by timing out after the Handover Required message */
7615 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7616 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7617 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7618 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7619
7620 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007621 f_shutdown_helper(ho := true);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007622}
7623
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007624/* OS#3041: Open and close N connections in a normal fashion, and expect no
7625 * BSSMAP Reset just because of that. */
7626testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7627 var default d;
7628 var integer i;
7629 var DchanTuple dt;
7630
7631 f_init();
7632
7633 /* Wait for initial BSSMAP Reset to pass */
7634 f_sleep(4.0);
7635
7636 d := activate(no_bssmap_reset());
7637
7638 /* Setup up a number of connections and RLSD them again from the MSC
7639 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7640 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007641 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007642 /* Since we're doing a lot of runs, give each one a fresh
7643 * T_guard from the top. */
7644 T_guard.start;
7645
7646 /* Setup a BSSAP connection and clear it right away. This is
7647 * the MSC telling the BSC about a planned release, it's not an
7648 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007649 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007650
7651 /* MSC disconnects (RLSD). */
7652 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7653 }
7654
7655 /* In the buggy behavior, a timeout of 2 seconds happens between above
7656 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7657 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7658 f_sleep(4.0);
7659
7660 deactivate(d);
7661 f_shutdown_helper();
7662}
Harald Welte552620d2017-12-16 23:21:36 +01007663
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007664/* OS#3041: Open and close N connections in a normal fashion, and expect no
7665 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7666 * the MSC. */
7667testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7668 var default d;
7669 var integer i;
7670 var DchanTuple dt;
7671 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007672 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7673 var BssmapCause cause := enum2int(cause_val);
7674
7675 f_init();
7676
7677 /* Wait for initial BSSMAP Reset to pass */
7678 f_sleep(4.0);
7679
7680 d := activate(no_bssmap_reset());
7681
7682 /* Setup up a number of connections and RLSD them again from the MSC
7683 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7684 * Let's do it some more times for good measure. */
7685 for (i := 0; i < 8; i := i+1) {
7686 /* Since we're doing a lot of runs, give each one a fresh
7687 * T_guard from the top. */
7688 T_guard.start;
7689
7690 /* Setup a BSSAP connection and clear it right away. This is
7691 * the MSC telling the BSC about a planned release, it's not an
7692 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007693 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007694
7695 /* Instruct BSC to clear channel */
7696 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7697
7698 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007699 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007700 }
7701
7702 /* In the buggy behavior, a timeout of 2 seconds happens between above
7703 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7704 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7705 f_sleep(4.0);
7706
7707 deactivate(d);
7708 f_shutdown_helper();
7709}
7710
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007711/* OS#3041: Open and close N connections in a normal fashion, and expect no
7712 * BSSMAP Reset just because of that. Close connections from the MS side with a
7713 * Release Ind on RSL. */
7714testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7715 var default d;
7716 var integer i;
7717 var DchanTuple dt;
7718 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007719 var integer j;
7720
7721 f_init();
7722
7723 /* Wait for initial BSSMAP Reset to pass */
7724 f_sleep(4.0);
7725
7726 d := activate(no_bssmap_reset());
7727
7728 /* Setup up a number of connections and RLSD them again from the MSC
7729 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7730 * Let's do it some more times for good measure. */
7731 for (i := 0; i < 8; i := i+1) {
7732 /* Since we're doing a lot of runs, give each one a fresh
7733 * T_guard from the top. */
7734 T_guard.start;
7735
7736 /* Setup a BSSAP connection and clear it right away. This is
7737 * the MSC telling the BSC about a planned release, it's not an
7738 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007739 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007740
7741 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007742 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007743
7744 /* expect Clear Request on MSC side */
7745 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7746
7747 /* Instruct BSC to clear channel */
7748 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7749 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7750
7751 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007752 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007753 }
7754
7755 /* In the buggy behavior, a timeout of 2 seconds happens between above
7756 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7757 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7758 f_sleep(4.0);
7759
7760 deactivate(d);
7761 f_shutdown_helper();
7762}
7763
Harald Welte94e0c342018-04-07 11:33:23 +02007764/***********************************************************************
7765 * IPA style dynamic PDCH
7766 ***********************************************************************/
7767
7768private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7769 template (omit) RSL_Cause nack := omit)
7770runs on test_CT {
7771 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7772 var RSL_Message rsl_unused;
7773 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7774 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7775 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007776 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007777 if (istemplatekind(nack, "omit")) {
7778 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007779 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007780 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007781 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007782 }
7783}
7784
7785private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7786 template (omit) RSL_Cause nack := omit)
7787runs on test_CT {
7788 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7789 var RSL_Message rsl_unused;
7790 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7791 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7792 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007793 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_DEACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007794 if (istemplatekind(nack, "omit")) {
7795 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007796 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007797 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007798 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007799 }
7800}
7801
7802private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7803runs on test_CT return charstring {
7804 var charstring cmd, resp;
7805 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007806 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007807}
7808
7809private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7810 template charstring exp)
7811runs on test_CT {
7812 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7813 if (not match(mode, exp)) {
7814 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007815 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007816 }
7817}
7818
7819private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7820runs on test_CT {
7821 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7822 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7823 f_vty_transceive(BSCVTY, "end");
7824}
7825
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007826
7827private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7828 var integer i;
7829 for (i := 0; i < 8; i := i + 1) {
7830 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7831 }
7832}
7833
Harald Welte94e0c342018-04-07 11:33:23 +02007834private const charstring TCHF_MODE := "TCH/F mode";
7835private const charstring TCHH_MODE := "TCH/H mode";
7836private const charstring PDCH_MODE := "PDCH mode";
7837private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007838private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007839
7840/* Test IPA PDCH activation / deactivation triggered by VTY */
7841testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7842 var RSL_Message rsl_unused;
7843
7844 /* change Timeslot 6 before f_init() starts RSL */
7845 f_init_vty();
7846 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7847 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7848
7849 f_init(1, false);
7850 f_sleep(1.0);
7851
7852 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7853
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007854 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007855 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7856 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007857 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7858 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007859 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007860 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007861 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7862
7863 /* De-activate it via VTY */
7864 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7865 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007866 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007867 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7868
7869 /* re-activate it via VTY */
7870 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7871 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007872 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007873 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7874
7875 /* and finally de-activate it again */
7876 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7877 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007878 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007879 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7880
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007881 /* clean up config */
7882 f_ts_set_chcomb(0, 0, 6, "PDCH");
7883
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007884 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007885}
7886
7887/* Test IPA PDCH activation NACK */
7888testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7889 var RSL_Message rsl_unused;
7890
7891 /* change Timeslot 6 before f_init() starts RSL */
7892 f_init_vty();
7893 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7894 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7895
7896 f_init(1, false);
7897 f_sleep(1.0);
7898
7899 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7900
7901 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7902 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007903 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7904 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007905 f_sleep(1.0);
7906 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7907
7908 /* De-activate it via VTY */
7909 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7910 f_sleep(1.0);
7911 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7912
7913 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7914 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7915 f_sleep(1.0);
7916 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7917
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007918 /* clean up config */
7919 f_ts_set_chcomb(0, 0, 6, "PDCH");
7920
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007921 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007922}
7923
7924
7925/***********************************************************************
7926 * Osmocom style dynamic PDCH
7927 ***********************************************************************/
7928
7929private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7930 template (omit) RSL_Cause nack := omit)
7931runs on test_CT {
7932 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7933 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007934 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007935 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7936 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007937 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT(chan_nr, ?));
Harald Welte94e0c342018-04-07 11:33:23 +02007938 if (istemplatekind(nack, "omit")) {
7939 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007940 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007941 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007942 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007943 }
7944}
7945
7946private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7947 template (omit) RSL_Cause nack := omit)
7948runs on test_CT {
7949 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7950 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007951 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007952 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7953 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007954 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007955 if (istemplatekind(nack, "omit")) {
7956 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007957 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007958 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007959 //f_ipa_tx(ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007960 }
7961}
7962
7963/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7964testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7965 var RSL_Message rsl_unused;
7966
7967 /* change Timeslot 6 before f_init() starts RSL */
7968 f_init_vty();
7969 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7970 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7971
7972 f_init(1, false);
7973 f_sleep(1.0);
7974
7975 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7976
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007977 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007978 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7979 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007980 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007981
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007982 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007983 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007984 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 +02007985 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7986
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007987 /* clean up config */
7988 f_ts_set_chcomb(0, 0, 6, "PDCH");
7989
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007990 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007991}
7992
7993/* Test Osmocom dyn PDCH activation NACK behavior */
7994testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7995 var RSL_Message rsl_unused;
7996
7997 /* change Timeslot 6 before f_init() starts RSL */
7998 f_init_vty();
7999 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
8000 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8001
8002 f_init(1, false);
8003 f_sleep(1.0);
8004
8005 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
8006
8007 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
8008 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008009 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02008010
8011 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008012 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte94e0c342018-04-07 11:33:23 +02008013 f_sleep(1.0);
8014 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
8015
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02008016 /* clean up config */
8017 f_ts_set_chcomb(0, 0, 6, "PDCH");
8018
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008019 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02008020}
8021
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008022/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
8023testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
8024 var RSL_Message rsl_unused, rsl_msg;
8025 var DchanTuple dt;
8026 var BSSAP_N_CONNECT_ind rx_c_ind;
8027
8028 /* change Timeslot 6 before f_init() starts RSL */
8029 f_init_vty();
8030 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8031 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8032
8033 f_init(1, false);
8034 f_sleep(1.0);
8035
8036 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8037
8038 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8039 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8040 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008041 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008042
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008043 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008044 f_sleep(1.0);
8045 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8046 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8047
8048 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8049 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008050 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008051 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008052 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008053 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008054 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008055 }
8056
8057 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008058 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8059 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8060 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008061
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008062 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008063 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008064 dt.idx := {0, 0};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008065
8066 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008067 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8068 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008069 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
8070
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008071 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 +02008072 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8073 dt.sccp_conn_id := rx_c_ind.connectionId;
8074 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8075
8076 /* Instruct BSC to clear channel */
8077 var BssmapCause cause := 0;
8078 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008079 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008080
8081 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008082 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8083 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008084 f_sleep(1.0);
8085 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8086
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008087 /* Clean up SDCCH lchans */
8088 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
8089 f_perform_clear_test_ct(sdcch_cleanup[i]);
8090 }
8091
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008092 /* clean up config */
8093 f_ts_set_chcomb(0, 0, 6, "PDCH");
8094
8095 f_shutdown_helper();
8096}
8097
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008098/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
8099testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
8100 var ASP_RSL_Unitdata rsl_ud;
8101 var integer i;
8102 var integer chreq_total, chreq_nochan;
8103
8104 f_init_vty();
8105 for (i := 1; i < 8; i := i + 1) {
8106 if (i == 2) {
8107 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8108 } else {
8109 f_ts_set_chcomb(0, 0, i, "PDCH");
8110 }
8111 }
8112 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8113
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008114 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008115
8116 /* The dyn TS want to activate PDCH mode, ACK that. */
8117 var RslChannelNr chan_nr;
8118 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008119 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
8120 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008121
8122 f_sleep(1.0);
8123
8124 /* Exhaust all dedicated SDCCH lchans.
8125 /* GSM 44.018 Table 9.1.8.2:
8126 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
8127 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008128 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008129 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008130 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 +02008131 }
8132
8133 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008134 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 +02008135 /* Also occupy the seven other SDCCH of the dyn TS */
8136 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008137 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 +01008138 }
8139
8140 /* Clean up SDCCH lchans */
8141 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8142 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008143 }
8144
8145 /* clean up config */
8146 f_ts_reset_chcomb(0);
8147
8148 f_shutdown_helper();
8149}
8150
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008151/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
8152 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
8153 it as TCH directly instead. SYS#5309. */
8154testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
8155 var RSL_Message rsl_unused, rsl_msg;
8156 var DchanTuple dt;
8157 var BSSAP_N_CONNECT_ind rx_c_ind;
8158 var integer i;
8159
8160 /* change Timeslot 6 before f_init() starts RSL */
8161 f_init_vty();
8162 for (i := 1; i < 8; i := i + 1) {
8163 if (i == 6) {
8164 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8165 } else {
8166 f_ts_set_chcomb(0, 0, i, "PDCH");
8167 }
8168 }
8169 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8170
8171 f_init(1, false);
8172 f_sleep(1.0);
8173
8174 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8175
8176 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8177 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8178 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008179 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008180
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008181 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008182 f_sleep(1.0);
8183 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8184 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8185
8186 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8187 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008188 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008189 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008190 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008191 dt := f_est_dchan(ra, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008192 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008193 }
8194
8195 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008196 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
8197 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8198 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008199
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008200 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008201 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008202 dt.idx := {0, 0};
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008203
8204 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008205 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8206 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008207 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
8208
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008209 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 +02008210 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8211 dt.sccp_conn_id := rx_c_ind.connectionId;
8212 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8213
8214 /* Instruct BSC to clear channel */
8215 var BssmapCause cause := 0;
8216 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008217 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008218
8219 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008220 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8221 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008222 f_sleep(1.0);
8223 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8224
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008225 /* Clean up SDCCH lchans */
8226 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8227 f_perform_clear_test_ct(chan_cleanup[i]);
8228 }
8229
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008230 /* clean up config */
8231 f_ts_reset_chcomb(0);
8232 /* TODO: clean up other channels? */
8233
8234 f_shutdown_helper();
8235}
8236
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008237/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
8238testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
8239 var RSL_Message rsl_unused, rsl_msg;
8240 var DchanTuple dt;
8241 var BSSAP_N_CONNECT_ind rx_c_ind;
8242 var GsmRrMessage rr;
8243
8244 /* change Timeslot 6 before f_init() starts RSL */
8245 f_init_vty();
8246 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8247 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8248
8249 f_init(1, false);
8250 f_sleep(1.0);
8251
8252 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8253
8254 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8255 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8256 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008257 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008258
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008259 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008260 f_sleep(1.0);
8261 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8262 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8263
8264 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8265 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008266 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008267 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008268 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008269 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008270 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008271 }
8272
8273 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008274 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8275 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8276 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008277
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008278 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008279 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008280 dt.idx := {0, 0};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008281
8282 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008283 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8284 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008285 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8286 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8287 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8288 }
8289
8290 /* FIXME? Currently the TS stays in state BORKEN: */
8291
8292 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008293 /* rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8294 * f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008295 * f_sleep(1.0);
8296 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8297 */
8298
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008299 /* Clean up SDCCH lchans */
8300 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8301 f_perform_clear_test_ct(chan_cleanup[i]);
8302 }
8303
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008304 /* clean up config */
8305 f_ts_set_chcomb(0, 0, 6, "PDCH");
8306
8307 f_shutdown_helper();
8308}
8309
Stefan Sperling0796a822018-10-05 13:01:39 +02008310testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008311 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008312 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8313 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8314 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008315 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008316}
8317
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008318testcase TC_chopped_ipa_payload() runs on test_CT {
8319 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8320 /* TODO: mp_bsc_ctrl_port does not work yet */};
8321 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8322 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8323 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008324 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008325}
8326
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008327/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8328 the BTS does autonomous MS power control loop */
8329testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8330 var MSC_ConnHdlr vc_conn;
8331 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8332 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8333 pars.exp_ms_power_params := true;
8334
8335 f_init(1, true);
8336 f_sleep(1.0);
8337 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8338 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008339 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008340}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008341
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008342/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8343testcase TC_c0_power_red_mode() runs on test_CT {
8344 f_init(1);
8345
8346 for (var integer red := 6; red >= 0; red := red - 2) {
8347 /* Configure BCCH carrier power reduction mode via the VTY */
8348 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8349
8350 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008351 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008352 chan_nr := t_RslChanNr_BCCH(0),
8353 bs_power := tr_RSL_IE_BS_Power(red / 2));
8354 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008355 var RSL_Message unused := f_exp_ipa_rx(tr_rsl_pdu);
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008356
8357 /* Additionally verify the applied value over the CTRL interface */
8358 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8359 if (cred != int2str(red)) {
8360 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8361 cred, " (expected ", red, ")");
8362 }
8363 }
8364
8365 f_shutdown_helper();
8366}
8367
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008368/***********************************************************************
8369 * MSC Pooling
8370 ***********************************************************************/
8371
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008372template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008373 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 +02008374
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008375private 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 +02008376runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008377 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008378 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008379 f_logp(BSCVTY, "Got RSL RR Release");
8380 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008381 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008382 f_logp(BSCVTY, "Got RSL Deact SACCH");
8383 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008384 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008385 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008386 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8387 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008388 break;
8389 }
8390 }
8391}
8392
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008393private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8394 var MgcpCommand mgcp_cmd;
8395 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8396 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8397 repeat;
8398 }
8399}
8400
8401private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8402 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8403 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8404 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8405 repeat;
8406 }
8407}
8408
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008409friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8410 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008411runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008412 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8413 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008414 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008415 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8416 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008417 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008418 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008419 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008420 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008421 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008422 }
8423 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008424 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008425 /* Also drop the SCCP connection */
8426 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8427 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008428 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008429 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008430 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8431 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008432 }
8433 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008434 deactivate(ack_dlcx);
8435 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008436}
8437
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008438friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8439runs on MSC_ConnHdlr {
8440 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8441 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8442 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8443 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8444 interleave {
8445 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8446 f_logp(BSCVTY, "Got RSL Deact SACCH");
8447 }
8448 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8449 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8450 /* Also drop the SCCP connection */
8451 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8452 }
8453 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8454 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8455 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8456 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8457 }
8458 }
8459 deactivate(ack_dlcx);
8460 deactivate(ack_rel_req);
8461}
8462
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008463friend function f_perform_clear_no_lchan()
8464runs on MSC_ConnHdlr {
8465 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8466 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8467 BSSAP.receive(tr_BSSMAP_ClearComplete);
8468 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8469 /* Also drop the SCCP connection */
8470 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8471}
8472
Vadim Yanitskiy65d879d2022-06-23 18:15:39 +07008473friend function f_perform_clear_test_ct(DchanTuple dt)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008474 runs on test_CT
8475{
8476 /* Instruct BSC to clear channel */
8477 var BssmapCause cause := 0;
8478 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008479 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008480}
8481
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008482private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8483 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008484runs on MSC_ConnHdlr {
8485 timer T := 10.0;
8486 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8487
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008488 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008489 f_create_bssmap_exp(l3_enc);
8490
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008491 /* RSL_Emulation.f_chan_est() on rsl_pt:
8492 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008493 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8494 */
8495 var RSL_Message rx_rsl;
8496 var GsmRrMessage rr;
8497
8498 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008499 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008500 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008501 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008502 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8503 */
8504 timer Tt := 10.0;
8505
8506 /* request a channel to be established */
8507 Tt.start;
8508 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008509 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008510 Tt.stop;
8511 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008512 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008513 setverdict(fail, "Unexpected RSL message on DCHAN");
8514 mtc.stop;
8515 }
8516 [] Tt.timeout {
8517 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8518 mtc.stop;
8519 }
8520 }
8521 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8522 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008523 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008524
8525
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008526 if (expect_bssmap_l3) {
8527 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8528 var template PDU_BSSAP exp_l3_compl;
8529 exp_l3_compl := tr_BSSMAP_ComplL3()
8530 if (g_pars.aoip == false) {
8531 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8532 } else {
8533 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8534 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008535
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008536 var PDU_BSSAP bssap;
8537 T.start;
8538 alt {
8539 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8540 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8541 log("rx exp_l3_compl = ", bssap);
8542 }
8543 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8544 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8545 }
8546 [] T.timeout {
8547 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8548 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008549 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008550
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008551 /* start ciphering, if requested */
8552 if (ispresent(g_pars.encr)) {
8553 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008554 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008555 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008556 }
8557
8558 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008559 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008560 }
8561 setverdict(pass);
8562 f_sleep(1.0);
8563}
8564
8565private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8566 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8567 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008568 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008569 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008570 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008571 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008572 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008573 }
8574}
8575
8576/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8577private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8578 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008579 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8580 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8581 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8582 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 +02008583}
8584testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8585
8586 f_init(1, true);
8587 f_sleep(1.0);
8588 var MSC_ConnHdlr vc_conn;
8589 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008590
8591 f_ctrs_msc_init();
8592
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008593 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8594 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008595
8596 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008597 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008598}
8599
8600/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8601/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8602 * just as well using only RSL. */
8603testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8604
8605 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8606 f_sleep(1.0);
8607
8608 /* Control which MSC gets chosen next by the round-robin, otherwise
8609 * would be randomly affected by which other tests ran before this. */
8610 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8611
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008612 f_ctrs_msc_init();
8613
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008614 var MSC_ConnHdlr vc_conn1;
8615 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8616 pars1.mscpool.rsl_idx := 0;
8617 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8618 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8619 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008620 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008621
8622 var MSC_ConnHdlr vc_conn2;
8623 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8624 pars2.mscpool.rsl_idx := 1;
8625 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8626 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8627 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008628 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008629
8630 /* Test round-robin wrap to the first MSC */
8631 var MSC_ConnHdlr vc_conn3;
8632 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8633 pars3.mscpool.rsl_idx := 2;
8634 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8635 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8636 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008637 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008638 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008639}
8640
8641/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8642 * (configured in osmo-bsc.cfg). */
8643/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8644 * just as well using only RSL. */
8645testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8646
8647 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8648 f_sleep(1.0);
8649
8650 /* Control which MSC gets chosen next by the round-robin, otherwise
8651 * would be randomly affected by which other tests ran before this. */
8652 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8653
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008654 f_ctrs_msc_init();
8655
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008656 var MSC_ConnHdlr vc_conn1;
8657 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8658 pars1.mscpool.rsl_idx := 0;
8659 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8660 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8661 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008662 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008663
8664 var MSC_ConnHdlr vc_conn2;
8665 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8666 pars2.mscpool.rsl_idx := 1;
8667 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8668 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8669 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008670 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008671
8672 /* Test round-robin wrap to the first MSC */
8673 var MSC_ConnHdlr vc_conn3;
8674 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8675 pars3.mscpool.rsl_idx := 2;
8676 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8677 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8678 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008679 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008680 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008681}
8682
8683/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8684 * (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
8685 * NULL-NRI setting is stronger than that. */
8686/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8687 * just as well using only RSL. */
8688testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8689
8690 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8691 f_sleep(1.0);
8692
8693 /* Control which MSC gets chosen next by the round-robin, otherwise
8694 * would be randomly affected by which other tests ran before this. */
8695 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8696
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008697 f_ctrs_msc_init();
8698
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008699 var MSC_ConnHdlr vc_conn1;
8700 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8701 pars1.mscpool.rsl_idx := 0;
8702 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8703 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8704 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008705 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008706
8707 var MSC_ConnHdlr vc_conn2;
8708 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8709 pars2.mscpool.rsl_idx := 1;
8710 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8711 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8712 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008713 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008714
8715 /* Test round-robin wrap to the first MSC */
8716 var MSC_ConnHdlr vc_conn3;
8717 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8718 pars3.mscpool.rsl_idx := 2;
8719 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8720 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8721 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008722 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008723 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008724}
8725
8726/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8727 * assigned to any MSC (configured in osmo-bsc.cfg). */
8728/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8729 * just as well using only RSL. */
8730testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8731
8732 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8733 f_sleep(1.0);
8734
8735 /* Control which MSC gets chosen next by the round-robin, otherwise
8736 * would be randomly affected by which other tests ran before this. */
8737 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8738
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008739 f_ctrs_msc_init();
8740
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008741 var MSC_ConnHdlr vc_conn1;
8742 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8743 pars1.mscpool.rsl_idx := 0;
8744 /* An NRI that is not assigned to any MSC */
8745 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8746 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8747 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008748 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008749
8750 var MSC_ConnHdlr vc_conn2;
8751 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8752 pars2.mscpool.rsl_idx := 1;
8753 /* An NRI that is not assigned to any MSC */
8754 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8755 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8756 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008757 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008758
8759 /* Test round-robin wrap to the first MSC */
8760 var MSC_ConnHdlr vc_conn3;
8761 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8762 pars3.mscpool.rsl_idx := 2;
8763 /* An NRI that is not assigned to any MSC */
8764 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8765 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8766 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008767 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008768 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008769}
8770
8771/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8772 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8773/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8774 * just as well using only RSL. */
8775testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8776
8777 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8778 f_sleep(1.0);
8779
8780 /* Control which MSC gets chosen next by the round-robin, otherwise
8781 * would be randomly affected by which other tests ran before this. */
8782 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8783
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008784 f_ctrs_msc_init();
8785
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008786 var MSC_ConnHdlr vc_conn1;
8787 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8788 pars1.mscpool.rsl_idx := 0;
8789 /* An NRI that is assigned to an unconnected MSC */
8790 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8791 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8792 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008793 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8794 f_ctrs_msc_add(0, "mscpool:subscr:new");
8795 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008796
8797 var MSC_ConnHdlr vc_conn2;
8798 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8799 pars2.mscpool.rsl_idx := 1;
8800 /* An NRI that is assigned to an unconnected MSC */
8801 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8802 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8803 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008804 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8805 f_ctrs_msc_add(1, "mscpool:subscr:new");
8806 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008807
8808 /* Test round-robin wrap to the first MSC */
8809 var MSC_ConnHdlr vc_conn3;
8810 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8811 pars3.mscpool.rsl_idx := 2;
8812 /* An NRI that is assigned to an unconnected MSC */
8813 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8814 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8815 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008816 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8817 f_ctrs_msc_add(0, "mscpool:subscr:new");
8818 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008819 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008820}
8821
8822/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8823 * osmo-bsc.cfg). */
8824/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8825 * just as well using only RSL. */
8826testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8827
8828 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8829 f_sleep(1.0);
8830
8831 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8832 * this is not using round-robin. */
8833 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8834
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008835 f_ctrs_msc_init();
8836
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008837 var MSC_ConnHdlr vc_conn1;
8838 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8839 pars1.mscpool.rsl_idx := 0;
8840 /* An NRI of the second MSC's range (256-511) */
8841 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8842 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8843 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008844 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008845
8846 var MSC_ConnHdlr vc_conn2;
8847 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8848 pars2.mscpool.rsl_idx := 1;
8849 /* An NRI of the second MSC's range (256-511) */
8850 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8851 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8852 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008853 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008854
8855 var MSC_ConnHdlr vc_conn3;
8856 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8857 pars3.mscpool.rsl_idx := 2;
8858 /* An NRI of the second MSC's range (256-511) */
8859 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8860 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8861 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008862 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008863 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008864}
8865
8866/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8867 * while a round-robin remains unaffected by that. */
8868/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8869 * just as well using only RSL. */
8870testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8871
8872 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8873 f_sleep(1.0);
8874
8875 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8876 * this is not using round-robin. */
8877 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8878
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008879 f_ctrs_msc_init();
8880
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008881 var MSC_ConnHdlr vc_conn1;
8882 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8883 pars1.mscpool.rsl_idx := 0;
8884 /* An NRI of the third MSC's range (512-767) */
8885 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8886 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8887 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008888 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008889
8890 var MSC_ConnHdlr vc_conn2;
8891 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8892 pars2.mscpool.rsl_idx := 1;
8893 /* An NRI of the third MSC's range (512-767) */
8894 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8895 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8896 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008897 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008898
8899 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8900 var MSC_ConnHdlr vc_conn3;
8901 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8902 pars3.mscpool.rsl_idx := 2;
8903 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8904 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8905 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008906 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008907 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008908}
8909
8910/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8911/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8912 * just as well using only RSL. */
8913testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8914
8915 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8916 f_sleep(1.0);
8917
8918 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8919 * instead, and hits msc 0. */
8920 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8921
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008922 f_ctrs_msc_init();
8923
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008924 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8925 var MSC_ConnHdlr vc_conn1;
8926 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8927 pars1.mscpool.rsl_idx := 0;
8928 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8929 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8930 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008931 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008932
8933 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8934 var MSC_ConnHdlr vc_conn2;
8935 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8936 pars2.mscpool.rsl_idx := 1;
8937 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8938 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8939 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008940 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008941 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008942}
8943
8944/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8945 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8946private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8947 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8948 //cid_list := { cIl_allInBSS := ''O };
8949 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8950 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8951 var BSSAP_N_UNITDATA_req paging;
8952 var hexstring imsi := '001010000000123'H;
8953
8954 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8955
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008956 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008957 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8958 BSSAP.send(paging);
8959
8960 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8961 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8962 * channel number is picked here. */
8963 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8964 f_rslem_register(0, new_chan_nr);
8965 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8966 f_rslem_unregister(0, new_chan_nr);
8967
8968 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8969 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008970 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008971 f_sleep(1.0);
8972}
8973testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8974 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8975 f_sleep(1.0);
8976
8977 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8978 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8979 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8980
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008981 f_ctrs_msc_init();
8982
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008983 var MSC_ConnHdlr vc_conn1;
8984 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8985 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008986 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8987 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008988 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8989 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008990 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008991 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008992}
8993
8994/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8995 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8996private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8997 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8998 //cid_list := { cIl_allInBSS := ''O };
8999 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
9000 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
9001 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01009002 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009003 var BSSAP_N_UNITDATA_req paging;
9004
9005 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9006
Neels Hofmeyr90f80962020-06-12 16:16:55 +02009007 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009008 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
9009 BSSAP.send(paging);
9010
9011 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
9012 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
9013 * channel number is picked here. */
9014 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
9015 f_rslem_register(0, new_chan_nr);
9016 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
9017 f_rslem_unregister(0, new_chan_nr);
9018
9019 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
9020 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
9021 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009022 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 +02009023 f_sleep(1.0);
9024}
9025testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
9026 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
9027 f_sleep(1.0);
9028
9029 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
9030 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
9031 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
9032
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009033 f_ctrs_msc_init();
9034
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009035 var MSC_ConnHdlr vc_conn1;
9036 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9037 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02009038 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
9039 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009040 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
9041 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009042 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009043 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009044}
9045
9046/* For round-robin, skip an MSC that has 'no allow-attach' set. */
9047/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
9048 * just as well using only RSL. */
9049testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
9050
9051 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9052 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009053 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9054 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009055
9056 /* Control which MSC gets chosen next by the round-robin, otherwise
9057 * would be randomly affected by which other tests ran before this. */
9058 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9059
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009060 f_ctrs_msc_init();
9061
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009062 var MSC_ConnHdlr vc_conn1;
9063 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9064 pars1.mscpool.rsl_idx := 0;
9065 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
9066 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9067 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009068 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009069
9070 var MSC_ConnHdlr vc_conn2;
9071 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
9072 pars2.mscpool.rsl_idx := 1;
9073 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9074 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9075 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009076 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009077
9078 var MSC_ConnHdlr vc_conn3;
9079 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
9080 pars3.mscpool.rsl_idx := 2;
9081 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
9082 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9083 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009084 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009085 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009086}
9087
9088/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
9089 * TMSI NRI. */
9090testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
9091
9092 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9093 f_sleep(1.0);
9094
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009095 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9096 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
9097
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009098 /* Control which MSC gets chosen next by the round-robin, otherwise
9099 * would be randomly affected by which other tests ran before this. */
9100 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9101
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009102 f_ctrs_msc_init();
9103
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009104 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
9105 var MSC_ConnHdlr vc_conn1;
9106 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
9107 pars1.mscpool.rsl_idx := 0;
9108 /* An NRI of the second MSC's range (256-511) */
9109 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
9110 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9111 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009112 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009113
9114 var MSC_ConnHdlr vc_conn2;
9115 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
9116 pars2.mscpool.rsl_idx := 1;
9117 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9118 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9119 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009120 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009121
9122 var MSC_ConnHdlr vc_conn3;
9123 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
9124 pars3.mscpool.rsl_idx := 2;
9125 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
9126 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9127 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009128 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009129 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009130}
9131
Philipp Maier783681c2020-07-16 16:47:06 +02009132/* Allow/Deny emergency calls globally via VTY */
9133private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
9134 f_vty_enter_cfg_msc(BSCVTY, 0);
9135 if (allow) {
9136 f_vty_transceive(BSCVTY, "allow-emergency allow");
9137 } else {
9138 f_vty_transceive(BSCVTY, "allow-emergency deny");
9139 }
9140 f_vty_transceive(BSCVTY, "exit");
9141 f_vty_transceive(BSCVTY, "exit");
9142}
9143
9144/* Allow/Deny emergency calls per BTS via VTY */
9145private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
9146 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9147 if (allow) {
9148 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
9149 } else {
9150 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
9151 }
9152 f_vty_transceive(BSCVTY, "exit");
9153 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00009154 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02009155}
9156
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02009157/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
9158private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
9159 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9160 if (allow) {
9161 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
9162 } else {
9163 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
9164 }
9165 f_vty_transceive(BSCVTY, "exit");
9166 f_vty_transceive(BSCVTY, "exit");
9167 f_vty_transceive(BSCVTY, "exit");
9168}
9169
Pau Espin Pedrol14475352021-07-22 15:48:16 +02009170/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
9171private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
9172 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9173 if (allow) {
9174 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
9175 } else {
9176 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
9177 }
9178 f_vty_transceive(BSCVTY, "exit");
9179 f_vty_transceive(BSCVTY, "exit");
9180 f_vty_transceive(BSCVTY, "exit");
9181}
9182
Pau Espin Pedrol35609792023-01-03 16:56:59 +01009183/* Begin assignment procedure and send an EMERGENCY SETUP (RR) */
Philipp Maier783681c2020-07-16 16:47:06 +02009184private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
9185 var PDU_ML3_MS_NW emerg_setup;
9186 var octetstring emerg_setup_enc;
9187 var RSL_Message emerg_setup_data_ind;
9188
9189 f_establish_fully(omit, omit);
9190
9191 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
9192 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
9193 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
9194
9195 RSL.send(emerg_setup_data_ind);
9196}
9197
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009198/* expect EmergencySetup on BSSAP after calling f_assignment_emerg_setup() */
9199private function f_assignment_emerg_setup_exp_bssap()
9200runs on MSC_ConnHdlr {
Philipp Maier783681c2020-07-16 16:47:06 +02009201 var PDU_BSSAP emerg_setup_data_ind_bssap;
9202 var PDU_ML3_MS_NW emerg_setup;
9203 timer T := 3.0;
9204
Philipp Maier783681c2020-07-16 16:47:06 +02009205 T.start;
9206 alt {
9207 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
9208 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
9209 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
9210 setverdict(fail, "no emergency setup");
9211 }
9212 }
9213 [] BSSAP.receive {
9214 setverdict(fail, "unexpected BSSAP message!");
9215 }
9216 [] T.timeout {
9217 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
9218 }
9219 }
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009220}
9221
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009222private function f_assignment_emerg_setup_voice()
9223runs on MSC_ConnHdlr {
9224 /* Go on with voice call assignment */
9225 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9226 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9227
9228 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
9229 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
9230 * seems a good idea to see how osmo-bsc reacts to this. */
9231 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
9232 elementIdentifier := '0B'O, /* overwritten */
9233 lengthIndicator := 0, /* overwritten */
9234 speechOrDataIndicator := '0001'B, /* speech */
9235 spare1_4 := '0000'B,
9236 channelRateAndType := ChRate_TCHForH_Fpref,
9237 speechId_DataIndicator := 'c2918105'O
9238 };
9239 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
9240 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
9241
9242 f_rslem_dchan_queue_enable();
9243
9244 var ExpectCriteria mgcpcrit := {
9245 connid := omit,
9246 endpoint := omit,
9247 transid := omit
9248 };
9249 f_create_mgcp_expect(mgcpcrit);
9250
9251 BSSAP.send(ass_cmd);
9252
9253 var AssignmentState st := valueof(ts_AssignmentStateInit);
9254 st.voice_call := true;
9255 st.is_assignment := false;
9256 alt {
9257 [] as_modify(st);
9258 [] as_Media();
9259 [st.modify_done] BSSAP.receive(exp_compl) {
9260 setverdict(pass);
9261 }
9262 }
9263
9264 /* Voice call carries on ... */
9265 f_sleep(2.0);
9266}
9267
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009268/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
9269 * CALLS are permitted by the BSC config. */
9270private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
9271
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009272 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
9273 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
9274 * another lchan. */
9275 g_pars.ra := f_rnd_ra_emerg();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009276 f_assignment_emerg_setup();
9277 f_assignment_emerg_setup_exp_bssap();
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009278 f_assignment_emerg_setup_voice();
Philipp Maier783681c2020-07-16 16:47:06 +02009279
9280 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009281 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02009282}
9283
9284/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
9285 * forbidden by the BSC config. */
9286private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
9287 var PDU_BSSAP emerg_setup_data_ind_bssap;
9288 timer T := 3.0;
9289
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009290 f_assignment_emerg_setup();
Philipp Maier783681c2020-07-16 16:47:06 +02009291
9292 T.start;
9293 alt {
9294 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9295 setverdict(pass);
9296 }
9297 [] RSL.receive {
9298 setverdict(fail, "unexpected RSL message!");
9299 }
9300 [] T.timeout {
9301 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
9302 }
9303 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009304 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01009305 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02009306}
9307
9308/* EMERGENCY CALL situation #1, allowed globally and by BTS */
9309testcase TC_assignment_emerg_setup_allow() runs on test_CT {
9310 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9311 var MSC_ConnHdlr vc_conn;
9312
9313 f_init(1, true);
9314 f_sleep(1.0);
9315
9316 f_vty_allow_emerg_msc(true);
9317 f_vty_allow_emerg_bts(true, 0);
9318 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9319 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009320 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009321}
9322
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +01009323/* Test MO emergency call using MobileIdentity=IMEI (possible for emergency
9324 * calls from phones without SIM card).
9325 * 3GPP TS 24.008 section 10.5.1.4, OS#5849 */
9326testcase TC_assignment_emerg_setup_allow_imei() runs on test_CT {
9327 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9328 var MSC_ConnHdlr vc_conn;
9329
9330 /* Remove IMSI set by f_gen_test_hdlr_pars(), then IMEI will be used to place the call */
9331 pars.imsi := omit;
9332
9333 f_init(1, true);
9334 f_sleep(1.0);
9335
9336 f_vty_allow_emerg_msc(true);
9337 f_vty_allow_emerg_bts(true, 0);
9338 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9339 vc_conn.done;
9340 f_shutdown_helper();
9341}
9342
Philipp Maier783681c2020-07-16 16:47:06 +02009343/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
9344testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
9345 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9346 var MSC_ConnHdlr vc_conn;
9347
9348 f_init(1, true);
9349 f_sleep(1.0);
9350
9351 f_vty_allow_emerg_msc(false);
9352 f_vty_allow_emerg_bts(true, 0);
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009353 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx): */
9354 pars.ra := f_rnd_ra_emerg();
Philipp Maier783681c2020-07-16 16:47:06 +02009355 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9356 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009357 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009358}
9359
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009360/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS.
9361 * The RACH req (and hence CHAN RQD) indicate other than emergency call.
9362 * Hence BSC only learns about it being an emergency call later during call setup.
9363 * If interested in the ra="emergency call" + deny bts policy case,
9364 * see TC_chan_rqd_emerg_deny.
9365 */
Philipp Maier783681c2020-07-16 16:47:06 +02009366testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9367 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9368 var MSC_ConnHdlr vc_conn;
9369
9370 /* Note: This simulates a spec violation by the MS, correct MS
9371 * implementations would not try to establish an emergency call because
9372 * the system information tells in advance that emergency calls are
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009373 * not allowed */
Philipp Maier783681c2020-07-16 16:47:06 +02009374
9375 f_init(1, true);
9376 f_sleep(1.0);
9377
9378 f_vty_allow_emerg_msc(true);
9379 f_vty_allow_emerg_bts(false, 0);
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009380 /* Note: Here we implicitly leave default g_pars.ra which is different than "emergency call" */
Philipp Maier783681c2020-07-16 16:47:06 +02009381 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9382 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009383 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009384}
9385
Philipp Maier82812002020-08-13 18:48:27 +02009386/* Test what happens when an emergency call arrives while all TCH channels are
9387 * busy, the BSC is expected to terminate one call in favor of the incoming
9388 * emergency call */
9389testcase TC_emerg_premption() runs on test_CT {
9390 var ASP_RSL_Unitdata rsl_ud;
9391 var integer i;
9392 var integer chreq_total, chreq_nochan;
9393 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009394 var octetstring l3_payload := gen_l3_valid_payload();
Philipp Maier82812002020-08-13 18:48:27 +02009395
9396 f_init(1);
9397 f_sleep(1.0);
9398
9399 f_vty_allow_emerg_msc(true);
9400 f_vty_allow_emerg_bts(true, 0);
9401
9402 /* Fill up all channels on the BTS */
9403 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9404 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9405 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 +02009406 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009407 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009408 IPA_RSL[0][0].clear;
Philipp Maier82812002020-08-13 18:48:27 +02009409 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9410 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9411
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009412 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9413 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009414 f_ipa_tx(ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009415
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009416 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9417 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009418 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009419 var integer sccp_conn_id := rx_c_ind.connectionId;
9420 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9421
Philipp Maier82812002020-08-13 18:48:27 +02009422 /* Send Channel request for emegergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009423 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier82812002020-08-13 18:48:27 +02009424
9425 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009426 f_expect_chan_rel(first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009427 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009428
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009429 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9430 var BSSAP_N_DATA_ind rx_clear_req;
9431 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9432 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9433 log("XXX ", rx_clear_req);
9434 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9435 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9436 }
9437
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009438 /* Expect the BSC to send activate/assign the channel for the emergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009439 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009440 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9441 setverdict(fail, "different TCH lchan activated than expected");
9442 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009443 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(first_tch, 33));
9444 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009445
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009446 /* complete the BSSMAP Clear to satisfy the conn leak check */
9447 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9448 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9449 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9450 }
9451
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009452 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009453}
9454
9455/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009456private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009457private type record FHParamsTs {
9458 boolean enabled,
9459 uint6_t hsn,
9460 uint6_t maio,
9461 ArfcnList ma
9462};
9463
9464/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009465private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009466 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009467 FHParamsTs ts[8]
9468};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009469
9470/* Randomly generate the hopping parameters for the given timeslot numbers */
9471private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9472runs on test_CT return FHParamsTrx {
9473 var FHParamsTrx fhp;
9474
Philipp Maier798d8952021-10-19 14:43:19 +02009475 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9476 * fall in the GSM900 band. */
9477 fhp.arfcn.arfcn := f_rnd_int(3);
9478 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009479
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009480 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9481 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009482 fhp.ts[tn].enabled := false;
9483 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009484 continue;
9485 }
9486
9487 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009488 fhp.ts[tn].hsn := f_rnd_int(64);
9489 fhp.ts[tn].maio := f_rnd_int(64);
9490 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009491
9492 /* Random Mobile Allocation (hopping channels) */
9493 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9494 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9495 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009496 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009497 }
9498
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009499 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009500 }
9501
9502 log("f_TC_fh_params_gen(): ", fhp);
9503 return fhp;
9504}
9505
9506/* Make sure that the given Channel Description IE matches the hopping configuration */
9507private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9508{
9509 var template (present) ChannelDescription tr_cd;
9510 var template (present) MaioHsn tr_maio_hsn;
9511 var uint3_t tn := cd.chan_nr.tn;
9512
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009513 if (fhp.ts[tn].enabled) {
9514 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009515 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9516 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009517 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009518 }
9519
9520 if (not match(cd, tr_cd)) {
9521 setverdict(fail, "Channel Description IE does not match: ",
9522 cd, " vs expected ", tr_cd);
9523 }
9524}
9525
9526/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9527private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9528 in MobileAllocationLV ma)
9529{
9530 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9531
9532 if (not match(ma, tr_ma)) {
9533 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9534 tn, "): ", ma, " vs expected: ", tr_ma);
9535 } else {
9536 setverdict(pass);
9537 }
9538}
9539
9540private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9541 in MobileAllocationLV ma)
9542return template MobileAllocationLV {
9543 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009544 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009545 return { len := 0, ma := ''B };
9546 }
9547
9548 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9549 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9550 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009551
9552 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009553 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9554 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9555 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009556 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009557 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009558 }
9559 }
9560
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009561 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009562 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009563
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009564 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009565 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9566 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009567 }
9568
9569 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009570 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009571 if (full_mask[i] != '1'B)
9572 { continue; }
9573
9574 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9575 if (slot_mask[i] == '1'B) {
9576 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009577 } else {
9578 ma_mask := ma_mask & '0'B;
9579 }
9580 }
9581
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009582 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9583 if (full_mask[0] == '1'B) {
9584 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9585 if (slot_mask[0] == '1'B) {
9586 ma_mask := ma_mask & '1'B;
9587 } else {
9588 ma_mask := ma_mask & '0'B;
9589 }
9590 }
9591
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009592 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009593 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009594 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9595
9596 return { len := ma_mask_len, ma := ma_mask };
9597}
9598
Philipp Maier798d8952021-10-19 14:43:19 +02009599/* Configure the appropriate band for a given arfcn, exc */
9600private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9601{
9602 var charstring band;
9603 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9604
9605 select (arfcn_) {
9606 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9607 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9608 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9609 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9610 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9611 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9612 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9613 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9614 case else { return; }
9615 }
9616
9617 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9618 f_vty_transceive(BSCVTY, "band " & band);
9619 f_vty_transceive(BSCVTY, "end");
9620}
9621
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009622/* Configure the hopping parameters in accordance with the given record */
9623private function f_TC_fh_params_set(in FHParamsTrx fhp,
9624 uint8_t bts_nr := 0,
9625 uint8_t trx_nr := 0)
9626runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009627
9628 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9629
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009630 /* Enter the configuration node for the given BTS/TRX numbers */
9631 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9632
Philipp Maier798d8952021-10-19 14:43:19 +02009633 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009634
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009635 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009636 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9637
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009638 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009639 f_vty_transceive(BSCVTY, "hopping enabled 0");
9640 f_vty_transceive(BSCVTY, "exit"); /* go back */
9641 continue;
9642 }
9643
9644 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009645 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9646 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009647
9648 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009649 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9650 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009651 }
9652
9653 f_vty_transceive(BSCVTY, "hopping enabled 1");
9654 f_vty_transceive(BSCVTY, "exit"); /* go back */
9655 }
9656
9657 f_vty_transceive(BSCVTY, "end");
9658}
9659
9660/* Disable frequency hopping on all timeslots */
9661private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9662 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009663 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009664 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009665runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009666
9667 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9668
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009669 /* Enter the configuration node for the given BTS/TRX numbers */
9670 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9671
Philipp Maier798d8952021-10-19 14:43:19 +02009672 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009673
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009674 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009675 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9676
9677 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009678 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9679 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009680 }
9681
9682 f_vty_transceive(BSCVTY, "hopping enabled 0");
9683 f_vty_transceive(BSCVTY, "exit"); /* go back */
9684 }
9685
9686 f_vty_transceive(BSCVTY, "end");
9687 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9688}
9689
9690/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9691 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9692testcase TC_fh_params_chan_activ() runs on test_CT {
9693 var FHParamsTrx fhp := f_TC_fh_params_gen();
9694 var RSL_Message rsl_msg;
9695 var RSL_IE_Body ie;
9696
9697 f_init_vty();
9698
9699 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9700 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9701
9702 f_init(1);
9703
9704 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9705 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009706 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9707 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009708
9709 /* Make sure that Channel Identification IE is present */
9710 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9711 setverdict(fail, "RSL Channel Identification IE is absent");
9712 continue;
9713 }
9714
9715 /* Make sure that hopping parameters (HSN/MAIO) match */
9716 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9717
9718 /* "Mobile Allocation shall be included but empty" - let's check this */
9719 if (ie.chan_ident.ma.v.len != 0) {
9720 setverdict(fail, "Mobile Allocation IE is not empty: ",
9721 ie.chan_ident.ma, ", despite it shall be");
9722 continue;
9723 }
9724 }
9725
9726 /* Disable frequency hopping */
9727 f_TC_fh_params_unset(fhp);
9728
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009729 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009730}
9731
9732/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9733testcase TC_fh_params_imm_ass() runs on test_CT {
9734 var FHParamsTrx fhp := f_TC_fh_params_gen();
9735 var RSL_Message rsl_msg;
9736 var RSL_IE_Body ie;
9737
9738 f_init_vty();
9739
9740 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9741 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9742
9743 f_init(1);
9744
9745 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9746 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009747 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9748 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009749
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009750 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9751 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009752
9753 /* Make sure that Full Immediate Assign Info IE is present */
9754 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9755 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9756 continue;
9757 }
9758
9759 /* Decode the actual Immediate Assignment message */
9760 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9761 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9762 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9763 continue;
9764 }
9765
9766 /* Make sure that hopping parameters (HSN/MAIO) match */
9767 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9768
9769 /* Make sure that the Mobile Allocation IE matches */
9770 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9771 rr_msg.payload.imm_ass.mobile_allocation);
9772 }
9773
9774 /* Disable frequency hopping */
9775 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009776
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009777 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009778}
9779
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009780/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9781testcase TC_fh_params_assignment_cmd() runs on test_CT {
9782 var FHParamsTrx fhp := f_TC_fh_params_gen();
9783 var RSL_Message rsl_msg;
9784 var RSL_IE_Body ie;
9785
9786 f_init_vty();
9787
9788 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9789 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9790
9791 f_init(1);
9792
9793 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02009794 vc_MGCP[0].stop;
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009795
9796 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9797 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9798
9799 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9800 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9801 for (var integer i := 0; i < 3; i := i + 1) {
9802 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009803 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009804
9805 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9806 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009807 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009808
9809 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009810 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9811 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009812
9813 /* Make sure that L3 Information IE is present */
9814 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9815 setverdict(fail, "RSL L3 Information IE is absent");
9816 continue;
9817 }
9818
9819 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9820 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9821 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9822 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9823 continue;
9824 }
9825
9826 /* Make sure that hopping parameters (HSN/MAIO) match */
9827 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9828 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9829
9830 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9831 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009832 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009833 continue;
9834 }
9835
9836 /* Make sure that the Mobile Allocation IE matches (if present) */
9837 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9838 if (chan_desc.h and ma_present) {
9839 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9840 l3_msg.payload.ass_cmd.mobile_allocation.v);
9841 } else if (chan_desc.h and not ma_present) {
9842 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9843 continue;
9844 } else if (not chan_desc.h and ma_present) {
9845 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9846 continue;
9847 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009848
9849 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009850 }
9851
9852 /* Give the IUT some time to release all channels */
9853 f_sleep(3.0);
9854
9855 /* Disable frequency hopping */
9856 f_TC_fh_params_unset(fhp);
9857
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009858 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009859}
9860
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009861/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9862private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9863runs on test_CT {
9864 var RSL_Message rsl_msg;
9865 var RSL_IE_Body ie;
9866 var DchanTuple dt;
9867
9868 /* Establish a dedicated channel, so we can trigger handover */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009869 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009870 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009871
9872 /* Trigger handover from BTS0 to BTS1 */
9873 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9874 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9875
9876 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009877 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx := {1, 0});
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009878
9879 /* ACKnowledge channel activation and expect (RR) Handover Command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009880 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33), idx := {1, 0});
9881 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009882
9883 /* Make sure that L3 Information IE is present */
9884 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9885 setverdict(fail, "RSL L3 Information IE is absent");
9886 return;
9887 }
9888
9889 /* Decode the L3 message and make sure it is (RR) Handover Command */
9890 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9891 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9892 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9893 return;
9894 }
9895
9896 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9897 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9898 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9899 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9900 return;
9901 }
9902
9903 /* Make sure that hopping parameters (HSN/MAIO) match */
9904 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9905
9906 /* Make sure that Cell Channel Description IE is present */
9907 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9908 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9909 return;
9910 }
9911
9912 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9913 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9914 if (ma_present) {
9915 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9916 l3_msg.payload.ho_cmd.mobile_allocation.v);
9917 } else {
9918 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9919 return;
9920 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009921
9922 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009923}
9924testcase TC_fh_params_handover_cmd() runs on test_CT {
9925 var FHParamsTrx fhp := f_TC_fh_params_gen();
9926
9927 f_init_vty();
9928
9929 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9930 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9931
9932 f_vty_transceive(BSCVTY, "timeslot 0");
9933 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9934 f_vty_transceive(BSCVTY, "exit"); /* go back */
9935
9936 f_vty_transceive(BSCVTY, "timeslot 1");
9937 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9938 f_vty_transceive(BSCVTY, "end"); /* we're done */
9939
9940 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9941 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9942
9943 f_init(2);
9944
9945 f_TC_fh_params_handover_cmd(fhp);
9946
9947 /* Disable frequency hopping on BTS1 */
9948 f_TC_fh_params_unset(fhp, 1);
9949
9950 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9951 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9952
9953 f_vty_transceive(BSCVTY, "timeslot 0");
9954 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9955 f_vty_transceive(BSCVTY, "exit"); /* go back */
9956
9957 f_vty_transceive(BSCVTY, "timeslot 1");
9958 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9959 f_vty_transceive(BSCVTY, "end"); /* we're done */
9960
9961 f_shutdown_helper();
9962}
9963
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009964/* Verify the hopping parameters in System Information Type 4 */
9965testcase TC_fh_params_si4_cbch() runs on test_CT {
9966 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9967 var ASP_RSL_Unitdata rx_rsl_ud;
9968 timer T := 5.0;
9969
9970 f_init_vty();
9971
9972 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9973 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9974
9975 f_vty_transceive(BSCVTY, "timeslot 0");
9976 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9977 f_vty_transceive(BSCVTY, "exit"); /* go back */
9978
9979 f_vty_transceive(BSCVTY, "timeslot 1");
9980 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9981 f_vty_transceive(BSCVTY, "end"); /* we're done */
9982
9983 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9984 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9985
9986 f_init(1);
9987
9988 T.start;
9989 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009990 [] 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 +07009991 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9992 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9993
9994 /* Make sure that what we decoded is System Information Type 4 */
9995 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9996 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9997 repeat;
9998 }
9999
10000 /* Make sure that CBCH Channel Description IE is present */
10001 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
10002 setverdict(fail, "CBCH Channel Description IE is absent");
10003 break;
10004 }
10005
10006 /* Finally, check the hopping parameters (HSN, MAIO) */
10007 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
10008 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
10009
10010 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
10011 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
10012 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
10013 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
10014 break;
10015 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
10016 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
10017 si.payload.si4.cbch_mobile_alloc.v);
10018 }
10019 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010020 [] IPA_RSL[0][0].receive { repeat; }
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010021 [] T.timeout {
10022 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
10023 }
10024 }
10025
10026 /* Disable frequency hopping */
10027 f_TC_fh_params_unset(fhp);
10028
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +070010029 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010030 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
10031
10032 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +070010033 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010034 f_vty_transceive(BSCVTY, "exit"); /* go back */
10035
10036 f_vty_transceive(BSCVTY, "timeslot 1");
10037 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
10038 f_vty_transceive(BSCVTY, "end"); /* we're done */
10039
Vadim Yanitskiy21726312020-09-04 01:45:36 +070010040 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010041}
10042
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010043template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
10044 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
10045
10046private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
10047 template (present) BSSLAP_PDU expect_bsslap)
10048{
10049 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
10050 if (not match(bsslap, expect_bsslap)) {
10051 log("EXPECTING BSSLAP: ", expect_bsslap);
10052 log("GOT BSSLAP: ", bsslap);
10053 setverdict(fail, "BSSLAP is not as expected");
10054 mtc.stop;
10055 }
10056 setverdict(pass);
10057}
10058
10059/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
10060const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
10061
10062private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
10063 var PDU_BSSAP_LE rx_bsslap;
10064 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
10065 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
10066}
10067
10068/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10069 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
10070private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
10071 f_sleep(1.0);
10072
10073 f_establish_fully(omit, omit);
10074 f_bssap_le_register_imsi(g_pars.imsi, omit);
10075
10076 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10077 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10078
10079 var PDU_BSSAP_LE plr;
10080 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10081
10082 if (not do_ta_request) {
10083 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
10084 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
10085 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
10086 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
10087 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
10088 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
10089 mtc.stop;
10090 }
10091 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
10092 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
10093 if (not match(bsslap, expect_ta_layer3)) {
10094 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
10095 log("GOT BSSLAP: ", bsslap);
10096 setverdict(fail, "BSSLAP is not as expected");
10097 mtc.stop;
10098 }
10099 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
10100 * has no need to request the TA from the BSC and directly responds. */
10101 } else {
10102 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10103 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10104 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10105 }
10106
10107 /* SMLC got the TA from the BSC, now responds with geo information data. */
10108 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10109 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10110 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10111
10112 /* The LCS was using an active A-interface conn. It should still remain active after this. */
10113 f_mo_l3_transceive();
10114
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010115 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010116
10117 f_sleep(2.0);
10118 setverdict(pass);
10119}
10120
10121/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10122 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
10123private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
10124 f_lcs_loc_req_for_active_ms(false);
10125}
10126testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
10127 var MSC_ConnHdlr vc_conn;
10128 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10129
10130 f_init(1, true);
10131 f_sleep(1.0);
10132 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
10133 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010134 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010135}
10136
10137/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10138 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
10139private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
10140 f_lcs_loc_req_for_active_ms(true);
10141}
10142testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
10143 var MSC_ConnHdlr vc_conn;
10144 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10145
10146 f_init(1, true);
10147 f_sleep(1.0);
10148 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
10149 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010150 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010151}
10152
10153/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
10154 * conn without an active lchan. */
10155private function f_clear_A_conn() runs on MSC_ConnHdlr
10156{
10157 var BssmapCause cause := 0;
10158 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10159 BSSAP.receive(tr_BSSMAP_ClearComplete);
10160 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10161
10162 timer no_more_bssap := 5.0;
10163 no_more_bssap.start;
10164 alt {
10165 [] no_more_bssap.timeout { break; }
10166 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
10167 setverdict(fail, "Expected no more BSSAP after Clear Complete");
10168 mtc.stop;
10169 }
10170 }
10171 setverdict(pass);
10172}
10173
10174/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
10175 * for LCS, for cases where there is only an A conn without an active lchan. */
10176private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
10177{
10178 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
10179
10180 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
10181 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
10182 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
10183 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10184 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10185 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10186
10187 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
10188 f_clear_A_conn();
10189 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10190 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10191}
10192
10193/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10194 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
10195 */
10196private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
10197 f_sleep(1.0);
10198
10199 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10200 f_bssap_le_register_imsi(g_pars.imsi, omit);
10201
10202 /* Register to receive the Paging Command */
10203 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10204 g_chan_nr := new_chan_nr;
10205 f_rslem_register(0, g_chan_nr);
10206
10207 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10208 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10209 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10210 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10211
10212 var PDU_BSSAP_LE plr;
10213 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10214
10215 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10216 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10217
10218 /* OsmoBSC needs to Page */
10219 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
10220 f_logp(BSCVTY, "got Paging Command");
10221
10222 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
10223 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010224 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);
10225 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010226
10227 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
10228
10229 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10230
10231 /* SMLC got the TA from the BSC, now responds with geo information data. */
10232 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10233 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10234
10235 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10236
10237 /* The lchan is gone, the A-interface conn was created for the LCS only.
10238 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
10239 f_verify_active_A_conn_and_clear();
10240
10241 f_sleep(2.0);
10242 setverdict(pass);
10243}
10244testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
10245 var MSC_ConnHdlr vc_conn;
10246 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10247
10248 f_init(1, true);
10249 f_sleep(1.0);
10250
10251 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10252 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10253
10254 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
10255 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010256 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010257}
10258
10259/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
10260 */
10261private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
10262 f_sleep(1.0);
10263
10264 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10265 f_bssap_le_register_imsi(g_pars.imsi, omit);
10266
10267 /* provoke an abort by omitting both IMSI and IMEI */
10268 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10269 valueof(ts_BSSMAP_Perform_Location_Request(omit,
10270 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
10271 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10272
10273 /* BSC tells MSC about failure */
10274 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10275 locationEstimate := omit, positioningData := omit,
10276 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
10277
10278 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10279 f_verify_active_A_conn_and_clear();
10280
10281 f_sleep(2.0);
10282 setverdict(pass);
10283}
10284testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
10285 var MSC_ConnHdlr vc_conn;
10286 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10287
10288 f_init(1, true);
10289 f_sleep(1.0);
10290
10291 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10292 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10293
10294 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
10295 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010296 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010297}
10298
10299/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10300 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
10301private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
10302 f_sleep(1.0);
10303
10304 f_establish_fully(omit, omit);
10305 f_bssap_le_register_imsi(g_pars.imsi, omit);
10306
10307 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10308 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10309
10310 var PDU_BSSAP_LE plr;
10311 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10312
10313 if (do_ta) {
10314 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10315 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10316 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10317 }
10318
10319 /* SMLC fails to respond, BSC runs into timeout */
10320 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
10321 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10322
10323 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10324 locationEstimate := omit, positioningData := omit,
10325 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
10326
10327 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10328 f_verify_active_A_conn_and_clear();
10329
10330 f_sleep(2.0);
10331 setverdict(pass);
10332}
10333
10334/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10335 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
10336private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
10337 f_lcs_loc_req_for_active_ms_le_timeout(false);
10338}
10339
10340testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
10341 var MSC_ConnHdlr vc_conn;
10342 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10343
10344 f_init(1, true);
10345 f_sleep(1.0);
10346 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
10347 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010348 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010349}
10350
10351/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10352 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
10353private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
10354 f_lcs_loc_req_for_active_ms_le_timeout(true);
10355}
10356
10357testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
10358 var MSC_ConnHdlr vc_conn;
10359 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10360
10361 f_init(1, true);
10362 f_sleep(1.0);
10363 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10364 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010365 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010366}
10367
10368/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10369private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10370 f_sleep(1.0);
10371
10372 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10373 f_bssap_le_register_imsi(g_pars.imsi, omit);
10374
10375 /* Register to receive the Paging Command */
10376 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10377 g_chan_nr := new_chan_nr;
10378 f_rslem_register(0, g_chan_nr);
10379
10380 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10381 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10382 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10383 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10384
10385 var PDU_BSSAP_LE plr;
10386 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10387
10388 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10389 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10390
10391 /* OsmoBSC needs to Page */
10392 var PDU_BSSAP_LE rx_bsslap;
10393 alt {
10394 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10395 f_logp(BSCVTY, "got Paging Command");
10396 repeat;
10397 }
10398 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10399 /* MS does not respond to Paging, TA Req runs into timeout. */
10400 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10401 }
10402 }
10403
10404 /* SMLC responds with failure */
10405 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10406 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10407
10408 /* BSC tells MSC about failure */
10409 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10410 locationEstimate := omit, positioningData := omit,
10411 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10412
10413 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10414 f_verify_active_A_conn_and_clear();
10415
10416 f_sleep(2.0);
10417 setverdict(pass);
10418}
10419testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10420 var MSC_ConnHdlr vc_conn;
10421 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10422
10423 f_init(1, true);
10424 f_sleep(1.0);
10425
10426 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10427 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10428
10429 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10430 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010431 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010432}
10433
10434/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10435 * over. */
10436private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10437 f_sleep(1.0);
10438
10439 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10440 f_bssap_le_register_imsi(g_pars.imsi, omit);
10441
10442 /* Register to receive the Paging Command */
10443 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10444 g_chan_nr := new_chan_nr;
10445 f_rslem_register(0, g_chan_nr);
10446
10447 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10448 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10449 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10450 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10451
10452 var PDU_BSSAP_LE plr;
10453 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10454
10455 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10456 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010457 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 +020010458 do_clear := false, expect_bssmap_l3 := true);
10459
10460 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10461 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10462
10463 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10464 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10465
10466 /* SMLC got the TA from the BSC, now responds with geo information data. */
10467 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10468 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10469 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10470
10471 /* The lchan should still exist, it was from a CM Service Request. */
10472 f_mo_l3_transceive();
10473
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010474 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010475
10476 f_sleep(2.0);
10477 setverdict(pass);
10478}
10479testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10480 var MSC_ConnHdlr vc_conn;
10481 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10482
10483 f_init(1, true);
10484 f_sleep(1.0);
10485
10486 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10487 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10488
10489 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10490 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010491 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010492}
10493
10494/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10495 * the new lchan after handover. */
10496private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10497 f_sleep(1.0);
10498
10499 f_establish_fully(omit, omit);
10500 f_bssap_le_register_imsi(g_pars.imsi, omit);
10501
10502 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10503 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10504
10505 var PDU_BSSAP_LE plr;
10506 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10507
10508 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10509 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10510
10511 var HandoverState hs := {
10512 rr_ho_cmpl_seen := false,
10513 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010514 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010515 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010516 };
10517 /* issue hand-over command on VTY */
10518 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10519 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10520 f_rslem_suspend(RSL1_PROC);
10521
10522 /* From the MGW perspective, a handover is is characterized by
10523 * performing one MDCX operation with the MGW. So we expect to see
10524 * one more MDCX during handover. */
10525 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10526
10527 alt {
10528 [] as_handover(hs);
10529 }
10530
10531 var PDU_BSSAP_LE rx_bsslap;
10532
10533 interleave {
10534 /* Expect the BSC to inform the MSC about the handover */
10535 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10536
10537 /* Expect the BSC to inform the SMLC about the handover */
10538 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10539 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10540 }
10541 }
10542
10543 /* SMLC now responds with geo information data. */
10544 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10545 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10546 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10547
10548 /* lchan still active */
10549 f_mo_l3_transceive(RSL1);
10550
10551 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010552 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010553
10554 f_sleep(2.0);
10555 setverdict(pass);
10556}
10557testcase TC_ho_during_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(2, true);
10562 f_sleep(1.0);
10563 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10564 vc_conn.done;
Oliver Smith39f53072022-10-27 14:44:04 +020010565 f_shutdown_helper(ho := true);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010566}
10567
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010568private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10569{
10570 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10571 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10572 * another lchan. */
Pau Espin Pedrol1809bce2023-01-03 16:54:41 +010010573 g_pars.ra := f_rnd_ra_emerg();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010574 f_assignment_emerg_setup();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +010010575 f_assignment_emerg_setup_exp_bssap();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010576
10577 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10578
10579 /* Do a Location Request in-between the CC call setup */
10580 f_bssap_le_register_imsi(g_pars.imsi, omit);
10581 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10582 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10583 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10584 /* SMLC got the TA from the BSC, now responds with geo information data. */
10585 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10586 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10587 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10588
Pau Espin Pedrol14076d32023-01-03 17:07:59 +010010589 f_assignment_emerg_setup_voice();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010590
10591 setverdict(pass);
10592 f_perform_clear();
10593}
10594
10595testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10596 var MSC_ConnHdlr vc_conn;
10597 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10598
10599 f_init(1, true);
10600 f_sleep(1.0);
10601 f_vty_allow_emerg_msc(true);
10602 f_vty_allow_emerg_bts(true, 0);
10603 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10604 vc_conn.done;
10605 f_shutdown_helper();
10606}
10607
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010608private altstep no_bssmap_clear_req() runs on MSC_ConnHdlr {
10609 [] BSSAP.receive(tr_BSSMAP_ClearRequest) {
10610 setverdict(fail, "unexpected BSSMAP Clear Request");
10611 mtc.stop;
10612 }
10613}
10614
10615private type enumerated RslRel {
10616 RSLREL_REL_IND,
10617 RSLREL_CONN_FAIL
10618};
10619
10620private function f_emerg_call_and_lcs_loc_req_early_lchan_release(RslRel rsl_rel) runs on MSC_ConnHdlr
10621{
10622 g_pars.ra := f_rnd_ra_emerg();
10623 f_assignment_emerg_setup();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +010010624 f_assignment_emerg_setup_exp_bssap();
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010625
10626 /* Start a Location Request to locate the emergency */
10627 f_bssap_le_register_imsi(g_pars.imsi, omit);
10628 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10629 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10630 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10631
10632 /* 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
10633 * do a Clear Command when the Location Response arrives. */
10634 activate(no_bssmap_clear_req());
10635
10636 /* the lchan gets interrupted while the Location Request has no response */
10637 select (rsl_rel) {
10638 case (RSLREL_REL_IND) {
10639 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10640 f_expect_lchan_rel(RSL, RSL_PROC);
10641 }
10642 case (RSLREL_CONN_FAIL) {
10643 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
10644 }
10645 case else {
10646 setverdict(fail, "Unknown RslRel type");
10647 mtc.stop;
10648 }
10649 }
10650
10651 /* Still expect the Location Response to find its way to the MSC. */
10652 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10653 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10654 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10655
10656 setverdict(pass);
10657
10658 select (rsl_rel) {
10659 case (RSLREL_REL_IND) {
10660 f_perform_clear_no_lchan();
10661 }
10662 case (RSLREL_CONN_FAIL) {
10663 f_perform_clear();
10664 }
10665 }
10666}
10667
10668private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind(charstring id) runs on MSC_ConnHdlr
10669{
10670 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_REL_IND);
10671}
10672
10673testcase TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() runs on test_CT {
10674 var MSC_ConnHdlr vc_conn;
10675 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10676
10677 f_init(1, true);
10678 f_sleep(1.0);
10679 f_vty_allow_emerg_msc(true);
10680 f_vty_allow_emerg_bts(true, 0);
10681 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind), pars);
10682 vc_conn.done;
10683 f_shutdown_helper();
10684}
10685
10686private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail(charstring id) runs on MSC_ConnHdlr
10687{
10688 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_CONN_FAIL);
10689}
10690
10691testcase TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() runs on test_CT {
10692 var MSC_ConnHdlr vc_conn;
10693 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10694
10695 f_init(1, true);
10696 f_sleep(1.0);
10697 f_vty_allow_emerg_msc(true);
10698 f_vty_allow_emerg_bts(true, 0);
10699 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail), pars);
10700 vc_conn.done;
10701 f_shutdown_helper();
10702}
10703
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010704/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10705private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10706 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10707
10708 /* Also disable attach for the single connected MSC */
10709 f_vty_msc_allow_attach(BSCVTY, { false });
10710
10711 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) ));
10712 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10713
10714 /* No MSC is found, expecting a proper release on RSL */
10715 interleave {
10716 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10717 f_logp(BSCVTY, "Got RSL RR Release");
10718 }
10719 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10720 f_logp(BSCVTY, "Got RSL Deact SACCH");
10721 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010722 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010723 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10724 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010725 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010726 }
10727 }
10728 setverdict(pass);
10729}
10730testcase TC_no_msc() runs on test_CT {
10731
10732 f_init(1, true);
10733 f_sleep(1.0);
10734 var MSC_ConnHdlr vc_conn;
10735 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10736
10737 f_ctrs_bsc_init(counternames_bsc_mscpool);
10738
10739 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10740 vc_conn.done;
10741
10742 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10743 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010744 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010745}
10746
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010747/* Dyn PDCH todo:
10748 * activate OSMO as TCH/F
10749 * activate OSMO as TCH/H
10750 * does the BSC-located PCU socket get the updated INFO?
10751 * what if no PCU is connected at the time?
10752 * is the info correct on delayed PCU (re)connect?
10753 */
Harald Welte94e0c342018-04-07 11:33:23 +020010754
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010755private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +020010756 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020010757 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010758
10759 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10760 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10761 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10762 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10763 g_pars.ass_codec_list.codecElements[0];
10764 if (isvalue(g_pars.expect_mr_s0_s7)) {
10765 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10766 g_pars.expect_mr_s0_s7;
10767 }
10768 }
10769 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10770 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10771 log("expecting ASS COMPL like this: ", exp_compl);
10772
10773 f_establish_fully(ass_cmd, exp_compl);
10774
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010775 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 +000010776
10777 var RSL_Message rsl;
10778
10779 timer T := 5.0;
10780 T.start;
10781 alt {
10782 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10783 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10784 log("Rx L3 from net: ", l3);
10785 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10786 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10787 mtc.stop;
10788 }
10789 }
10790 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10791 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10792 mtc.stop;
10793 }
10794 [] T.timeout {
10795 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10796 setverdict(pass);
10797 }
10798 }
10799 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010800
10801 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010802}
10803
10804/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10805 * osmo-bsc. */
10806testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10807 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10808 var MSC_ConnHdlr vc_conn;
10809
10810 f_init(1, true);
10811 f_sleep(1.0);
10812
10813 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10814 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10815 vc_conn.done;
10816 f_shutdown_helper();
10817}
10818
10819/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10820 */
10821testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10822 f_init_vty();
10823
10824 f_init(1, false);
10825 f_sleep(1.0);
10826
10827 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10828
10829 var ASP_RSL_Unitdata rx_rsl_ud;
10830 timer T := 5.0;
10831
10832 T.start;
10833 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010834 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010835 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10836 T.stop;
10837 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10838 mtc.stop;
10839 }
10840 repeat;
10841 }
10842 [] T.timeout {
10843 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10844 setverdict(pass);
10845 }
10846 }
10847}
10848
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010849private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10850 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010851 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010852
10853 /* Trigger re-assignment to another lchan */
10854 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10855
10856 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10857 * one MDCX on MGCP. */
10858 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10859
10860 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10861 * as the old lchan used. */
10862 g_media.bts.ipa_crcx_seen := false;
10863 g_media.bts.ipa_mdcx_seen := false;
10864
10865 /* Send different BTS side RTP port number for the new lchan */
10866 g_media.bts.bts.port_nr := 4223;
10867
10868 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10869
10870 /* Trigger re-assignment. */
10871 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10872
10873 timer T := 5.0;
10874 T.start;
10875 alt {
10876 [] as_assignment(assignment_st);
10877 [] as_Media();
10878 [] T.timeout {
10879 break;
10880 }
10881 }
10882
10883 if (not assignment_st.assignment_done) {
10884 setverdict(fail, "Assignment did not complete");
10885 mtc.stop;
10886 }
10887
10888 f_check_mgcp_expectations()
10889 setverdict(pass);
10890
10891 f_sleep(2.0);
10892 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10893
10894 /* Instruct BSC to clear channel */
10895 var BssmapCause cause := 0;
10896 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10897 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010898 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10899 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010900 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010901 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010902 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010903 }
10904 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10905 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10906 }
10907 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010908 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010909
10910 f_sleep(0.5);
10911}
10912
10913testcase TC_reassignment_fr() runs on test_CT {
10914 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10915 var MSC_ConnHdlr vc_conn;
10916
10917 f_init(1, true);
10918 f_sleep(1.0);
10919
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010920 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010921
10922 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10923 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10924 vc_conn.done;
10925
10926 /* from f_establish_fully() */
10927 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10928 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10929 /* from re-assignment */
10930 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10931 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10932 f_ctrs_bsc_and_bts_verify();
10933 f_shutdown_helper();
10934}
10935
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010936const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10937const charstring REEST_CLEAR := "REEST_CLEAR";
10938const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10939
10940/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10941 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10942 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10943 * the MSC as the CM Re-Establishment is handled.
10944 *
10945 * MS bts0 bts1 bsc msc test-component
10946 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10947 * | | _1 wait a bit, to settle down
10948 * |<-x x--| | _1 "lose connection"
10949 * | | REEST_LOST_CONNECTION
10950 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10951 * | | REEST_CLEAR
10952 * | |<-0---| _1 Clear Command on first A-conn
10953 * | |--0-->| _1 Clear Complete
10954 * | |<----------------->| | _1 Release first channel
10955 * | | REEST_CLEAR_DONE
10956 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10957 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10958 *
10959 */
10960private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10961 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10962 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10963
10964 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10965 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10966
10967 f_establish_fully(ass_cmd, exp_compl);
10968
10969 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10970 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10971 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10972 f_sleep(2.0);
10973 COORD.send(REEST_LOST_CONNECTION);
10974
10975 alt {
10976 [] COORD.receive(REEST_CLEAR);
10977 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10978 setverdict(fail, "Unexpected channel release");
10979 mtc.stop;
10980 }
10981 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10982 setverdict(fail, "Unexpected channel release");
10983 mtc.stop;
10984 }
10985 }
10986 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010987 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010988 COORD.send(REEST_CLEAR_DONE);
10989}
10990
10991private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10992 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10993
10994 /* The MS lost the connection on the first channel, now establishes another one */
10995 COORD.receive(REEST_LOST_CONNECTION);
10996
10997 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10998 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10999 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
11000
11001 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011002 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 +020011003 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
11004
11005 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
11006 COORD.send(REEST_CLEAR);
11007 COORD.receive(REEST_CLEAR_DONE);
11008
11009 f_sleep(2.0);
11010
11011 /* Answer the CM Re-Establishment with an Assignment Command. */
11012 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
11013 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11014 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11015 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11016
11017 var AssignmentState st := valueof(ts_AssignmentStateInit);
11018 st.voice_call := true;
11019 st.is_assignment := true;
11020
11021 var ExpectCriteria mgcpcrit := {
11022 connid := omit,
11023 endpoint := omit,
11024 transid := omit
11025 };
11026 f_create_mgcp_expect(mgcpcrit);
11027
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011028 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011029
11030 BSSAP.send(ass_cmd);
11031
11032 var PDU_BSSAP bssap;
11033
11034 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011035 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
11036 [] as_Media_ipacc(RSL1, RSL2);
11037 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011038 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
11039 break;
11040 }
11041 }
11042
11043 f_sleep(3.0);
11044
11045 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011046 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011047}
11048
11049testcase TC_cm_reestablishment() runs on test_CT {
11050 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11051 var MSC_ConnHdlr vc_conn1;
11052
11053 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11054 var MSC_ConnHdlr vc_conn2;
11055 pars2.imsi := pars1.imsi;
11056 pars2.media_nr := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011057 pars2.expect_tsc := c_BtsParams[1].tsc;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011058
11059 f_init(2, true, guard_timeout := 40.0);
11060 f_sleep(1.0);
11061
11062 vc_conn1 := f_start_handler_create(pars1);
11063 vc_conn2 := f_start_handler_create(pars2);
11064 connect(vc_conn1:COORD, vc_conn2:COORD);
11065 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
11066 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
11067 vc_conn1.done;
11068 vc_conn2.done;
11069
11070 f_shutdown_helper();
11071}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011072
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011073function f_exp_ipa_rx_nonfatal(template (present) RSL_Message t_rx,
11074 boolean ignore_other_rx := true,
11075 BtsTrxIdx idx := {0, 0},
11076 float Tval := 2.0)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011077runs on test_CT return template (omit) RSL_Message {
11078 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011079 timer T := Tval;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011080
11081 T.start;
11082 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011083 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011084 T.stop;
11085 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011086 [ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
11087 [not ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011088 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
11089 T.stop;
11090 return omit;
11091 }
11092 [] T.timeout {
11093 return omit;
11094 }
11095 }
11096 return rx_rsl_ud.rsl;
11097}
11098
11099private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
11100 f_vty_enter_cfg_bts(pt, bts_nr);
11101 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
11102 f_vty_transceive(pt, "exit");
11103 f_vty_transceive(pt, "exit");
11104 f_vty_transceive(pt, "exit");
11105}
11106
11107private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030011108 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011109 template (present) uint12_t arfcn := ?,
11110 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011111{
11112 var RSL_IE_Body full_imm_ass_info;
11113 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
11114 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
11115 mtc.stop;
11116 }
11117
11118 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
11119 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
11120 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011121 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011122 page_mode := ?);
11123 if (not match(rr_imm_ass, expect_imm_ass)) {
11124 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
11125 setverdict(fail, "Failed to match Immediate Assignment");
11126 mtc.stop;
11127 }
11128}
11129
11130testcase TC_imm_ass_post_chan_ack() runs on test_CT {
11131 var RSL_Message chan_act;
11132 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011133 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011134
11135 f_init(1, false);
11136 f_sleep(1.0);
11137
11138 /* (should be the default anyway, just to make things clear) */
11139 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
11140
11141 /* RA containing reason=LU */
11142 var GsmFrameNumber fn := 2342;
11143 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011144 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011145
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011146 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011147
11148 /* First send the Chan Act ACK */
11149 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011150 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011151 var RSL_IE_Body chan_ident_ie;
11152 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11153 setverdict(fail, "RSL Channel Identification IE is absent");
11154 mtc.stop;
11155 }
11156
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011157 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011158
11159 /* Then expect the Immediate Assignment, after we ACKed the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011160 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011161
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011162 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11163 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011164
11165 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011166 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011167
11168 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011169 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011170 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011171 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11172
11173 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011174 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011175 f_shutdown_helper();
11176}
11177
11178testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
11179 var RSL_Message chan_act;
11180 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011181 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011182
11183 f_init(1, false);
11184 f_sleep(1.0);
11185
11186 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11187
11188 /* RA containing reason=LU */
11189 var GsmFrameNumber fn := 2342;
11190 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011191 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011192
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011193 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011194 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011195 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011196 var RSL_IE_Body chan_ident_ie;
11197 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11198 setverdict(fail, "RSL Channel Identification IE is absent");
11199 mtc.stop;
11200 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011201
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011202 /* (set bts 0 cfg back to default) */
11203 f_vty_set_imm_ass(BSCVTY);
11204
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011205 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011206 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011207 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11208 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011209
11210 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011211 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011212
11213 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011214 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011215
11216 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011217 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011218 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011219 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11220
11221 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011222 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011223 f_shutdown_helper();
11224}
11225
Neels Hofmeyr23158742021-09-07 19:08:07 +020011226testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
11227 var RSL_Message chan_act;
11228 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011229 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr23158742021-09-07 19:08:07 +020011230
11231 f_init(1, false);
11232 f_sleep(1.0);
11233
11234 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11235
11236 /* RA containing reason=LU */
11237 var GsmFrameNumber fn := 2342;
11238 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011239 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011240
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011241 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011242 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011243 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr23158742021-09-07 19:08:07 +020011244 var RSL_IE_Body chan_ident_ie;
11245 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11246 setverdict(fail, "RSL Channel Identification IE is absent");
11247 mtc.stop;
11248 }
11249
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011250 /* (set bts 0 cfg back to default) */
11251 f_vty_set_imm_ass(BSCVTY);
11252
Neels Hofmeyr23158742021-09-07 19:08:07 +020011253 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011254 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011255 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11256 chan_ident_ie.chan_ident.ch_desc.v.tsc);
11257
11258 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011259 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011260
11261 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011262 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011263
11264 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011265 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011266 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020011267 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11268
11269 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011270 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020011271 f_shutdown_helper();
11272}
11273
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011274testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
11275 /* change Timeslot 6 before f_init() starts RSL */
11276 f_init_vty();
11277 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11278 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11279
11280 f_init(1, false);
11281 f_sleep(1.0);
11282
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011283 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011284 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11285 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011286 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11287 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011288
11289 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11290 f_ts_set_chcomb(0, 0, 6, "PDCH");
11291
11292 /* block all static timeslots so that the dyn TS will be used */
11293 f_disable_all_tch_f();
11294 f_disable_all_tch_h();
11295 f_disable_all_sdcch();
11296
11297 var RSL_Message chan_act;
11298 var RSL_Message imm_ass;
11299
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011300 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11301
11302 /* RA containing reason=LU */
11303 var GsmFrameNumber fn := 2342;
11304 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011305 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011306
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011307 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011308 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
11309 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011310
11311 /* Now activation as SDCCH8 */
11312 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011313 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011314
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011315 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011316 var RSL_IE_Body chan_ident_ie;
11317 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11318 setverdict(fail, "RSL Channel Identification IE is absent");
11319 mtc.stop;
11320 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011321
11322 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011323 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011324 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11325 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011326
11327 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011328 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011329
11330 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011331 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011332
11333 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011334 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011335 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011336 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11337
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011338 /* (set bts 0 cfg back to default) */
11339 f_vty_set_imm_ass(BSCVTY);
11340
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011341 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011342 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011343 f_shutdown_helper();
11344}
11345
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011346testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
11347 /* change Timeslot 6 before f_init() starts RSL */
11348 f_init_vty();
11349 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11350 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11351
11352 f_init(1, false);
11353 f_sleep(1.0);
11354
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011355 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011356 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11357 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011358 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11359 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011360
11361 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11362 f_ts_set_chcomb(0, 0, 6, "PDCH");
11363
11364 /* block all static timeslots so that the dyn TS will be used */
11365 f_disable_all_tch_f();
11366 f_disable_all_tch_h();
11367 f_disable_all_sdcch();
11368
11369 var RSL_Message chan_act;
11370 var RSL_Message imm_ass;
11371
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011372 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11373
11374 /* RA containing reason=LU */
11375 var GsmFrameNumber fn := 2342;
11376 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011377 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011378
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011379 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011380 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011381
11382 /* And already the Immediate Assignment even before the PDCH Deact ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011383 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011384
11385 /* continue the Osmo style PDCH Deact (usual chan rel) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011386 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011387
11388 /* Now activation as SDCCH8 */
11389 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011390 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011391
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011392 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011393 var RSL_IE_Body chan_ident_ie;
11394 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11395 setverdict(fail, "RSL Channel Identification IE is absent");
11396 mtc.stop;
11397 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011398 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011399
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011400 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11401 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011402
11403 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011404 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011405
11406 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011407 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011408 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011409 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11410
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011411 /* (set bts 0 cfg back to default) */
11412 f_vty_set_imm_ass(BSCVTY);
11413
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011414 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011415 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011416 f_shutdown_helper();
11417}
11418
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011419/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11420testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11421 var MSC_ConnHdlr vc_conn;
11422
11423 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11424 f_sleep(1.0);
11425
11426 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11427 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11428 "0,0,operational,unlocked,on,rsl-up;" &
11429 "1,0,operational,unlocked,on,rsl-up;" &
11430 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011431 "2,1,operational,unlocked,on,rsl-down;" &
11432 "2,2,operational,unlocked,on,rsl-down;" &
11433 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011434 "3,0,inoperational,locked,on,rsl-down;");
11435
11436 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11437 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11438 /* give it a moment to settle the FSM status */
11439 f_sleep(1.0);
11440
11441 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11442 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11443 * of "off"? But that's for a future patch if at all. */
11444 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11445 "0,0,operational,unlocked,on,rsl-up;" &
11446 "1,0,operational,locked,on,rsl-up;" &
11447 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011448 "2,1,operational,unlocked,on,rsl-down;" &
11449 "2,2,operational,unlocked,on,rsl-down;" &
11450 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011451 "3,0,inoperational,locked,on,rsl-down;");
11452
11453 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11454 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11455 f_sleep(1.0);
11456 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11457 "0,0,operational,unlocked,on,rsl-up;" &
11458 "1,0,operational,locked,on,rsl-up;" &
11459 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011460 "2,1,operational,unlocked,on,rsl-down;" &
11461 "2,2,operational,unlocked,on,rsl-down;" &
11462 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011463 "3,0,inoperational,locked,on,rsl-down;");
11464
11465 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11466 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11467 f_sleep(1.0);
11468 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11469 "0,0,operational,unlocked,on,rsl-up;" &
11470 "1,0,operational,unlocked,on,rsl-up;" &
11471 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011472 "2,1,operational,unlocked,on,rsl-down;" &
11473 "2,2,operational,unlocked,on,rsl-down;" &
11474 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011475 "3,0,inoperational,locked,on,rsl-down;");
11476
11477 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11478 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11479 f_sleep(1.0);
11480 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11481 "0,0,operational,unlocked,on,rsl-up;" &
11482 "1,0,operational,unlocked,on,rsl-up;" &
11483 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011484 "2,1,operational,unlocked,on,rsl-down;" &
11485 "2,2,operational,unlocked,on,rsl-down;" &
11486 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011487 "3,0,inoperational,locked,on,rsl-down;");
11488
11489 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11490 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11491 f_sleep(1.0);
11492 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11493 "0,0,operational,unlocked,on,rsl-up;" &
11494 "1,0,operational,unlocked,on,rsl-up;" &
11495 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011496 "2,1,operational,unlocked,on,rsl-down;" &
11497 "2,2,operational,unlocked,on,rsl-down;" &
11498 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011499 "3,0,inoperational,locked,on,rsl-down;");
11500
11501 f_shutdown_helper();
11502}
11503
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011504const CounterNameVals counternames_cm_serv_rej := {
11505 { "cm_serv_rej", 0 },
11506 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11507 { "cm_serv_rej:illegal_ms", 0 },
11508 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11509 { "cm_serv_rej:imei_not_accepted", 0 },
11510 { "cm_serv_rej:illegal_me", 0 },
11511 { "cm_serv_rej:plmn_not_allowed", 0 },
11512 { "cm_serv_rej:loc_not_allowed", 0 },
11513 { "cm_serv_rej:roaming_not_allowed", 0 },
11514 { "cm_serv_rej:network_failure", 0 },
11515 { "cm_serv_rej:synch_failure", 0 },
11516 { "cm_serv_rej:congestion", 0 },
11517 { "cm_serv_rej:srv_opt_not_supported", 0 },
11518 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11519 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11520 { "cm_serv_rej:call_can_not_be_identified", 0 },
11521 { "cm_serv_rej:incorrect_message", 0 },
11522 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11523 { "cm_serv_rej:msg_type_not_implemented", 0 },
11524 { "cm_serv_rej:msg_type_not_compatible", 0 },
11525 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11526 { "cm_serv_rej:condtional_ie_error", 0 },
11527 { "cm_serv_rej:msg_not_compatible", 0 },
11528 { "cm_serv_rej:protocol_error", 0 },
11529 { "cm_serv_rej:retry_in_new_cell", 0 }
11530};
11531
11532private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11533{
11534 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011535 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011536 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011537 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11538 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011539 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011540}
11541testcase TC_cm_serv_rej() runs on test_CT {
11542 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11543 var MSC_ConnHdlr vc_conn;
11544
11545 f_init(1, true);
11546 f_sleep(1.0);
11547
11548 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11549
11550 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11551 vc_conn.done;
11552
11553 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11554 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11555 f_ctrs_bts_verify();
11556
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011557 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011558 f_shutdown_helper();
11559}
11560
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011561/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11562 * Activ Ack (SYS#5627). */
11563private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11564 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011565
11566 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11567 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011568
11569 var BSSMAP_FIELD_CodecType codecType;
11570 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11571
11572 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11573
11574 /* First establish a signalling lchan */
11575 f_create_chan_and_exp();
11576 f_rslem_dchan_queue_enable();
11577
11578 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011579
11580 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
Oliver Smith735b47c2023-02-15 16:03:54 +010011581 activate(as_Media_mgw());
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011582
11583 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11584 f_rslem_register(0, chan_nr);
11585
11586 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11587 BSSAP.send(ass_cmd);
11588
11589
11590 /* Wait for the Channel Activ for the TCH channel */
11591 var ASP_RSL_Unitdata rx_rsl_ud;
11592 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11593
11594 /* make the original SDCCH disappear */
11595 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11596
11597 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11598 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11599
11600 interleave {
11601 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11602 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11603 }
11604
11605 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11606 BSSAP.receive(tr_BSSMAP_ClearComplete);
11607 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11608
11609 var MgcpCommand mgcp;
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011610 var MGCP_RecvFrom mrf;
11611 var template MgcpMessage msg_dlcx := { command := tr_DLCX };
11612 alt {
11613 [g_pars.aoip] MGCP.receive(tr_DLCX) -> value mgcp {
11614 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11615 }
11616 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
11617 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
11618 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
11619 }));
11620 }
11621 }
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011622
11623 f_sleep(0.5);
11624}
11625testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11626 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11627 var MSC_ConnHdlr vc_conn;
11628
Oliver Smith735b47c2023-02-15 16:03:54 +010011629 pars.fail_on_dlcx := false;
11630
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011631 f_init(1, true);
11632 f_sleep(1.0);
11633
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011634 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11635 vc_conn.done;
11636
11637 f_shutdown_helper();
11638}
11639
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011640const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11641 { "all_allocated:sdcch", 0 },
11642 { "all_allocated:static_sdcch", 0 },
11643 { "all_allocated:tch", 0 },
11644 { "all_allocated:static_tch", 0 }
11645}
11646
11647private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11648{
11649 /* Make sure counters settle first */
11650 f_sleep(1.0);
11651
11652 /* Take a baseline of counters */
11653 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11654
11655 /* Elapse some time so that we see changes in counters, hopefully where expected */
11656 f_sleep(2.0);
11657
11658 /* Get new counters */
11659 var charstring_list all_changed := {};
11660 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11661 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11662
11663 /* Compare with expectations */
11664 var charstring_list all_expect_changed := {};
11665 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11666 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11667 }
11668 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11669}
11670
11671testcase TC_ratectr_all_available_allocated() runs on test_CT {
11672 var ASP_RSL_Unitdata rsl_ud;
11673 var integer i;
11674 var integer chreq_total, chreq_nochan;
11675
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011676 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011677 f_sleep(1.0);
11678
11679 /* Exhaust all dedicated SDCCH lchans.
11680 /* GSM 44.018 Table 9.1.8.2:
11681 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11682 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011683 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011684 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011685 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 +020011686 }
11687
11688 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11689 * level.
11690 * All SDCCH are now occupied. */
11691 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11692
11693 /* Also fill up all remaining (TCH) channels */
11694 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011695 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 +020011696 }
11697
11698 /* All TCH are now also occupied */
11699 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11700 "all_allocated:tch", "all_allocated:static_tch"});
11701
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011702 /* Clean up SDCCH lchans */
11703 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11704 f_perform_clear_test_ct(chan_cleanup[i]);
11705 }
11706
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011707 f_shutdown_helper();
11708}
11709
11710testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11711 var ASP_RSL_Unitdata rsl_ud;
11712 var integer i;
11713 var integer chreq_total, chreq_nochan;
11714
11715 f_init_vty();
11716 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11717 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11718 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11719
11720 f_init(1, guard_timeout := 60.0);
11721 f_sleep(1.0);
11722
11723 /* The dyn TS wants to activate PDCH mode, ACK that. */
11724 var RslChannelNr chan_nr;
11725 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011726 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11727 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011728
11729 /* Exhaust all dedicated SDCCH lchans.
11730 /* GSM 44.018 Table 9.1.8.2:
11731 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11732 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011733 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011734 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011735 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 +020011736 }
11737
11738 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11739 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11740 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11741
11742 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11743 * Will release them later, so remember all the DchanTuples. */
11744 var DchanTuples dyn_sddch := {};
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011745 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 +020011746
11747 /* Also occupy the seven other SDCCH of the dyn TS */
11748 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011749 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 +020011750 }
11751
11752 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11753 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11754
11755 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11756 for (i := 0; i < 5; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011757 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 +020011758 }
11759
11760 /* All TCH lchans are now also occupied, both static and dynamic */
11761 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11762 "all_allocated:tch", "all_allocated:static_tch"});
11763
11764 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11765 * incrementing. */
11766 var BssmapCause cause := 0;
11767 var DchanTuple dt := dyn_sddch[0];
11768 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011769 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011770
11771 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11772 * count as occupied, so those still both increment. */
11773 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11774 "all_allocated:tch", "all_allocated:static_tch"});
11775
11776 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11777 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11778 dt := dyn_sddch[i];
11779 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011780 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011781 }
11782
11783 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11784 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011785 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11786 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011787
11788 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11789 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11790
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011791 /* Clean up SDCCH lchans */
11792 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11793 f_perform_clear_test_ct(chan_cleanup[i]);
11794 }
11795
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011796 /* clean up config */
11797 f_ts_reset_chcomb(0);
11798
11799 f_shutdown_helper();
11800}
11801
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011802private function f_TC_chan_alloc_algo(DchanTuple dt, BtsTrxIdx idx)
11803runs on test_CT {
11804 /* MSC sends an Assignment Request */
11805 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11806 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11807 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11808 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
11809
11810 /* Expect the BSC to allocate a TCH channel on the given BTS/TRX */
11811 var RSL_Message rsl_chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
11812 /* Send CHAN ACT NACK, so that the requested TCH channel becomes BORKEN */
11813 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(rsl_chan_act.ies[0].body.chan_nr, RSL_ERR_EQUIPMENT_FAIL), idx);
11814 /* Expect to receive an Assignment Failure */
11815 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail));
11816}
11817
11818testcase TC_chan_alloc_algo_ascending() runs on test_CT {
11819 /* We need to access BTS2, which has 4 TRXs */
11820 f_init(nr_bts := 3);
11821
11822 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011823 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011824
11825 f_vty_enter_cfg_bts(BSCVTY, 2);
11826 f_vty_transceive(BSCVTY, "channel allocator ascending");
11827 f_vty_transceive(BSCVTY, "end");
11828
11829 /* Expect the BSC to allocate 4 x TCH/F channels on BTS2/TRX0 */
11830 for (var integer i := 0; i < 4; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011831 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011832 f_TC_chan_alloc_algo(dt, {2, 0});
11833 f_perform_clear_test_ct(dt);
11834 }
11835
11836 /* At this point all 4 x TCH/F channels are BORKEN, but they will be
11837 * resurrected upon the A-bis/OML link re-establishment. */
11838 f_shutdown_helper();
11839}
11840
11841testcase TC_chan_alloc_algo_descending() runs on test_CT {
11842 /* We need to access BTS2, which has 4 TRXs */
11843 f_init(nr_bts := 3);
11844
11845 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011846 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011847
11848 f_vty_enter_cfg_bts(BSCVTY, 2);
11849 f_vty_transceive(BSCVTY, "channel allocator descending");
11850 f_vty_transceive(BSCVTY, "end");
11851
11852 /* Expect the BSC to allocate 5 x TCH/F channels on BTS2/TRX3 */
11853 for (var integer i := 0; i < 5; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011854 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011855 f_TC_chan_alloc_algo(dt, {2, 3});
11856 f_perform_clear_test_ct(dt);
11857 }
11858
11859 /* At this point all 5 x TCH/F channels are BORKEN, but they will be
11860 * resurrected upon the A-bis/OML link re-establishment. */
11861 f_shutdown_helper();
11862}
11863
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011864testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
11865 const BtsTrxIdx TRX0 := {2, 0};
11866 const BtsTrxIdx TRX3 := {2, 3};
11867
11868 /* We need to access BTS2, which has 4 TRXs */
11869 f_init(nr_bts := 3);
11870
11871 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011872 vc_MGCP[0].stop;
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011873
11874 f_vty_enter_cfg_bts(BSCVTY, 2);
11875 f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
11876 f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
11877 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
11878 f_vty_transceive(BSCVTY, "end");
11879
11880 var DchanTuple dt;
11881
11882 f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011883 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011884 f_TC_chan_alloc_algo(dt, TRX0);
11885 f_perform_clear_test_ct(dt);
11886
11887 f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011888 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011889 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11890 ts_RSL_IE_UplinkMeas(30, 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_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011897 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011898 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11899 ts_RSL_IE_UplinkMeas(45, 0),
11900 ts_RSL_IE_BS_Power(0)), TRX0);
11901 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11902 ts_RSL_IE_UplinkMeas(48, 0),
11903 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011904 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011905 f_TC_chan_alloc_algo(dt, TRX0);
11906 f_perform_clear_test_ct(dt);
11907
11908 f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011909 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011910 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11911 ts_RSL_IE_UplinkMeas(50, 0),
11912 ts_RSL_IE_BS_Power(0)), TRX0);
11913 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11914 ts_RSL_IE_UplinkMeas(58, 0),
11915 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011916 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011917 f_TC_chan_alloc_algo(dt, TRX3);
11918 f_perform_clear_test_ct(dt);
11919
11920 f_vty_enter_cfg_bts(BSCVTY, 2);
11921 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
11922 f_vty_transceive(BSCVTY, "end");
11923
11924 f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011925 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011926 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11927 ts_RSL_IE_UplinkMeas(50, 0),
11928 ts_RSL_IE_BS_Power(0)), TRX0);
11929 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11930 ts_RSL_IE_UplinkMeas(58, 0),
11931 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011932 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011933 f_TC_chan_alloc_algo(dt, TRX0);
11934 f_perform_clear_test_ct(dt);
11935
11936 f_vty_enter_cfg_bts(BSCVTY, 2);
11937 f_vty_transceive(BSCVTY, "channel allocator ascending");
11938 f_vty_transceive(BSCVTY, "end");
11939
11940 /* At this point some TCH/F channels are BORKEN, but they will be
11941 * resurrected upon the A-bis/OML link re-establishment. */
11942 f_shutdown_helper();
11943}
11944
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020011945private function f_vty_mgw_enable(integer mgw_nr := 1) runs on test_CT {
11946 var rof_charstring cmds := {
11947 "remote-ip " & mp_test_ip,
11948 "remote-port " & int2str(2427 + mgw_nr)
11949 };
11950 f_vty_config3(BSCVTY, {"network", "mgw " & int2str(mgw_nr)}, cmds);
11951 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " reconnect")
11952}
11953private function f_vty_mgw_disable(integer mgw_nr := 1) runs on test_CT {
11954 f_vty_config3(BSCVTY, {"network"}, { "no mgw " &int2str(mgw_nr) });
11955}
11956private function f_vty_mgw_block(integer mgw_nr := 1, boolean blocked := true) runs on test_CT {
11957 var charstring arg;
11958 if (blocked) {
11959 arg := "block";
11960 } else {
11961 arg := "unblock";
11962 }
11963 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " " & arg);
11964}
11965private const charstring COORD_CMD_ESTABLISHED := "COORD_CMD_ESTABLISHED";
11966private function f_TC_mgwpool_call_seq_1(charstring id) runs on MSC_ConnHdlr {
11967 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11968 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11969 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11970 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11971
11972 f_establish_fully(ass_cmd, exp_compl);
11973 COORD.send(COORD_CMD_ESTABLISHED);
11974
11975 COORD.receive(COORD_CMD_ESTABLISHED);
11976 f_perform_clear()
11977 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11978}
11979private function f_TC_mgwpool_call_seq_2(charstring id) runs on MSC_ConnHdlr {
11980 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11981 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11982 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11983 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11984
11985
11986 COORD.receive(COORD_CMD_ESTABLISHED);
11987 f_establish_fully(ass_cmd, exp_compl);
11988 COORD.send(COORD_CMD_ESTABLISHED);
11989
11990 f_perform_clear()
11991 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11992}
11993/* Test load is spread around 2 available MGWs */
11994testcase TC_mgwpool_all_used() runs on test_CT {
11995 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11996 var MSC_ConnHdlr vc_conn1;
11997 pars1.mgwpool_idx := 0;
11998
11999 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12000 var MSC_ConnHdlr vc_conn2;
12001 pars2.mgwpool_idx := 1;
12002
12003 f_init(1, true, nr_mgw := 2);
12004 f_sleep(1.0);
12005
12006 f_vty_mgw_enable(1);
12007
12008 vc_conn1 := f_start_handler_create(pars1);
12009 vc_conn2 := f_start_handler_create(pars2);
12010 connect(vc_conn1:COORD, vc_conn2:COORD);
12011 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12012 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12013 vc_conn1.done;
12014 vc_conn2.done;
12015
12016 f_vty_mgw_disable(1);
12017
12018 f_shutdown_helper();
12019}
12020
12021/* Test blocked MGW in the pool are not selected */
12022testcase TC_mgwpool_blocked_not_used() runs on test_CT {
12023 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
12024 var MSC_ConnHdlr vc_conn1;
12025 pars1.mgwpool_idx := 0;
12026
12027 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12028 var MSC_ConnHdlr vc_conn2;
12029 pars2.mgwpool_idx := 0; /* expect it in the first one, since the second will be blocked */
12030 pars2.media_nr := 2;
12031
12032 f_init(1, true, nr_mgw := 2);
12033 f_sleep(1.0);
12034
12035 f_vty_mgw_enable(1);
12036 f_vty_mgw_block(1, true);
12037
12038 vc_conn1 := f_start_handler_create(pars1);
12039 vc_conn2 := f_start_handler_create(pars2);
12040 connect(vc_conn1:COORD, vc_conn2:COORD);
12041 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12042 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12043 vc_conn1.done;
12044 vc_conn2.done;
12045
12046 f_vty_mgw_disable(1);
12047
12048 f_shutdown_helper();
12049}
12050
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012051/* Test BTS pinning to an MGW is applied */
12052testcase TC_mgwpool_pin_bts() runs on test_CT {
12053 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
12054 var MSC_ConnHdlr vc_conn1;
12055 pars1.mgwpool_idx := 0;
12056
12057 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12058 var MSC_ConnHdlr vc_conn2;
12059 pars2.mgwpool_idx := 0; /* expect it in the first one, since the BTS is pinned to the first MGW */
12060 pars2.media_nr := 2;
12061
12062 f_init(1, true, nr_mgw := 2);
12063 f_sleep(1.0);
12064
12065 f_vty_mgw_enable(1);
12066 f_vty_cfg_bts(BSCVTY, 0, { "mgw pool-target 0" });
12067
12068 vc_conn1 := f_start_handler_create(pars1);
12069 vc_conn2 := f_start_handler_create(pars2);
12070 connect(vc_conn1:COORD, vc_conn2:COORD);
12071 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12072 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12073 vc_conn1.done;
12074 vc_conn2.done;
12075
12076 f_vty_cfg_bts(BSCVTY, 0, { "no mgw pool-target" } );
Vadim Yanitskiy389d7e02022-10-25 17:44:05 +070012077 f_vty_mgw_disable(1);
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012078
12079 f_shutdown_helper();
12080}
12081
Oliver Smithc9a5f532022-10-21 11:32:23 +020012082private function f_tc_ho_meas_rep_multi_band(charstring id) runs on MSC_ConnHdlr {
12083 g_pars := f_gen_test_hdlr_pars();
12084 var PDU_BSSAP ass_req := f_gen_ass_req();
12085 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
12086 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
12087 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
12088 f_establish_fully(ass_req, exp_compl);
12089
12090 /* Send a measurement report with bad rxlev except on 3rd entry. The
12091 * measurement report is divided into two sub lists, as described in
12092 * 3GPP TS 04.08 § 10.5.2.20. */
12093 var NcellReports neighbor_rep := {
12094 /* Sub list 1: same band */
Oliver Smitha6773042022-10-24 12:56:30 +020012095 { rxlev := 0, bcch_freq := 0, bsic := 12 }, /* ARFCN 800, band 1800, LAC 98 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012096 /* Sub list 2: different band */
Oliver Smitha6773042022-10-24 12:56:30 +020012097 { rxlev := 0, bcch_freq := 1, bsic := 13 }, /* ARFCN 200, band 850, LAC 97 */
12098 { rxlev := 40, bcch_freq := 2, bsic := 14 }, /* ARFCN 1000, band 900, LAC 99 */
12099 { rxlev := 0, bcch_freq := 3, bsic := 11 } /* ARFCN 0, band 900, LAC 96 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012100 };
12101 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
12102 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
12103 l3_mr, 0));
12104
12105 /* Expect a handover to the third entry. If the BSC parsed the report
Oliver Smitha6773042022-10-24 12:56:30 +020012106 * correctly, the third entry has LAC 99. */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012107 var template BSSMAP_FIELD_CellIdentificationList cid_list := {
Oliver Smitha6773042022-10-24 12:56:30 +020012108 cIl_LAC := { ts_BSSMAP_CI_LAC(99) }
Oliver Smithc9a5f532022-10-21 11:32:23 +020012109 };
12110 alt {
12111 [] BSSAP.receive(tr_BSSMAP_HandoverRequired(cid_list := cid_list)) {
12112 setverdict(pass);
12113 }
12114 [] BSSAP.receive(tr_BSSMAP_HandoverRequired()) {
12115 setverdict(fail, "Handover has unexpected LAC in Cell Identification List. The BSC probably"
12116 & " didn't parse the multi-band measurement report correctly.");
12117 }
12118 }
12119
12120 f_ho_out_of_this_bsc(skip_meas_rep := true);
12121}
12122testcase TC_ho_meas_rep_multi_band() runs on test_CT {
12123 /* Verify that the BSC parses the measurement report correctly when
12124 * neighbors in multiple bands are configured (OS#5717). See
12125 * gsm_arfcn2band_rc() in libosmocore src/gsm/gsm_utils.c for the
12126 * ARFCN -> band mapping. The MS is connected to band 1800. */
12127 var MSC_ConnHdlr vc_conn;
12128
12129 f_init_vty();
12130 f_bts_0_cfg(BSCVTY,
12131 {"neighbor-list mode automatic",
12132 "handover 1",
12133 "handover algorithm 2",
12134 "handover2 window rxlev averaging 1",
12135 "no neighbors",
12136 "neighbor lac 99 arfcn 1000 bsic any", /* band 900 */
12137 "neighbor lac 98 arfcn 800 bsic any", /* band 1800 */
12138 "neighbor lac 97 arfcn 200 bsic any", /* band 850 */
Oliver Smitha6773042022-10-24 12:56:30 +020012139 "neighbor lac 96 arfcn 0 bsic any"}); /* band 900 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012140 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
12141
12142 f_init(1, true);
12143 f_sleep(1.0);
12144
12145 f_ctrs_bsc_and_bts_handover_init();
12146
12147 vc_conn := f_start_handler(refers(f_tc_ho_meas_rep_multi_band));
12148 vc_conn.done;
12149
12150 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
12151 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
12152 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
12153 f_ctrs_bsc_and_bts_add(0, "handover:completed");
12154 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
12155 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
12156 f_ctrs_bsc_and_bts_verify();
12157 f_shutdown_helper(ho := true);
12158}
12159
Harald Welte28d943e2017-11-25 15:00:50 +010012160control {
Harald Welte898113b2018-01-31 18:32:21 +010012161 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010012162 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010012163 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020012164 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
12165 * these in the AoIP test suite. */
12166 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12167 execute( TC_stat_num_msc_connected_1() );
12168 execute( TC_stat_num_msc_connected_2() );
12169 execute( TC_stat_num_msc_connected_3() );
12170 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020012171 execute( TC_stat_num_bts_connected_1() );
12172 execute( TC_stat_num_bts_connected_2() );
12173 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010012174 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012175 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020012176 execute( TC_ctrl_location() );
12177 }
Harald Welte898113b2018-01-31 18:32:21 +010012178
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012179 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020012180 execute( TC_si2quater_2_earfcns() );
12181 execute( TC_si2quater_3_earfcns() );
12182 execute( TC_si2quater_4_earfcns() );
12183 execute( TC_si2quater_5_earfcns() );
12184 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020012185 execute( TC_si2quater_12_earfcns() );
12186 execute( TC_si2quater_23_earfcns() );
12187 execute( TC_si2quater_32_earfcns() );
12188 execute( TC_si2quater_33_earfcns() );
12189 execute( TC_si2quater_42_earfcns() );
12190 execute( TC_si2quater_48_earfcns() );
12191 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020012192 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020012193 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012194
Harald Welte898113b2018-01-31 18:32:21 +010012195 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010012196 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010012197 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010012198 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020012199 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020012200 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010012201 execute( TC_chan_act_ack_est_ind_noreply() );
12202 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010012203 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010012204 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070012205 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010012206 execute( TC_chan_rel_rll_rel_ind() );
12207 execute( TC_chan_rel_conn_fail() );
12208 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020012209 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
12210 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010012211 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010012212 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020012213 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010012214 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010012215 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020012216 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010012217
Harald Weltecfe2c962017-12-15 12:09:32 +010012218 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010012219
12220 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010012221 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010012222 execute( TC_assignment_csd() );
12223 execute( TC_assignment_ctm() );
12224 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012225 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12226 execute( TC_assignment_aoip_tla_v6() );
12227 }
Harald Welte235ebf12017-12-15 14:18:16 +010012228 execute( TC_assignment_fr_a5_0() );
12229 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012230 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020012231 execute( TC_assignment_fr_a5_1_codec_missing() );
12232 }
Harald Welte235ebf12017-12-15 14:18:16 +010012233 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020012234 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020012235 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020012236 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012237 execute( TC_ciph_mode_a5_0() );
12238 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020012239 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020012240 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012241 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020012242 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010012243
Harald Welte60aa5762018-03-21 19:33:13 +010012244 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020012245 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010012246 execute( TC_assignment_codec_hr() );
12247 execute( TC_assignment_codec_efr() );
12248 execute( TC_assignment_codec_amr_f() );
12249 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012250
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012251 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010012252 execute( TC_assignment_codec_amr_f_S1() );
12253 execute( TC_assignment_codec_amr_h_S1() );
12254 execute( TC_assignment_codec_amr_f_S124() );
12255 execute( TC_assignment_codec_amr_h_S124() );
12256 execute( TC_assignment_codec_amr_f_S0() );
12257 execute( TC_assignment_codec_amr_f_S02() );
12258 execute( TC_assignment_codec_amr_f_S024() );
12259 execute( TC_assignment_codec_amr_f_S0247() );
12260 execute( TC_assignment_codec_amr_h_S0() );
12261 execute( TC_assignment_codec_amr_h_S02() );
12262 execute( TC_assignment_codec_amr_h_S024() );
12263 execute( TC_assignment_codec_amr_h_S0247() );
12264 execute( TC_assignment_codec_amr_f_S01234567() );
12265 execute( TC_assignment_codec_amr_f_S0234567() );
12266 execute( TC_assignment_codec_amr_f_zero() );
12267 execute( TC_assignment_codec_amr_f_unsupp() );
12268 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000012269 execute( TC_assignment_codec_amr_f_start_mode_auto() );
12270 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000012271 execute( TC_assignment_codec_amr_f_start_mode_4() );
12272 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000012273 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012274 }
Harald Welte60aa5762018-03-21 19:33:13 +010012275
Philipp Maierac09bfc2019-01-08 13:41:39 +010012276 execute( TC_assignment_codec_fr_exhausted_req_hr() );
12277 execute( TC_assignment_codec_fr_exhausted_req_fr() );
12278 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
12279 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
12280 execute( TC_assignment_codec_hr_exhausted_req_fr() );
12281 execute( TC_assignment_codec_hr_exhausted_req_hr() );
12282 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
12283 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
12284 execute( TC_assignment_codec_req_hr_fr() );
12285 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020012286 execute( TC_assignment_sdcch_exhausted_req_signalling() );
12287 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
12288 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010012289
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +020012290 execute( TC_assignment_codec_hr_osmux_on() );
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020012291 execute( TC_assignment_osmux() );
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020012292 execute( TC_assignment_osmux_cn() );
12293 execute( TC_assignment_osmux_bts() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020012294
Harald Welte898113b2018-01-31 18:32:21 +010012295 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010012296 execute( TC_rll_est_ind_inact_lchan() );
12297 execute( TC_rll_est_ind_inval_sapi1() );
12298 execute( TC_rll_est_ind_inval_sapi3() );
12299 execute( TC_rll_est_ind_inval_sacch() );
12300
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070012301 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
12302 execute( TC_tch_dlci_link_id_sapi() );
12303
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012304 /* SAPI N Reject triggered by RLL establishment failures */
12305 execute( TC_rll_rel_ind_sapi_n_reject() );
12306 execute( TC_rll_err_ind_sapi_n_reject() );
12307 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070012308 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012309
Harald Welte898113b2018-01-31 18:32:21 +010012310 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010012311 execute( TC_paging_imsi_nochan() );
12312 execute( TC_paging_tmsi_nochan() );
12313 execute( TC_paging_tmsi_any() );
12314 execute( TC_paging_tmsi_sdcch() );
12315 execute( TC_paging_tmsi_tch_f() );
12316 execute( TC_paging_tmsi_tch_hf() );
12317 execute( TC_paging_imsi_nochan_cgi() );
12318 execute( TC_paging_imsi_nochan_lac_ci() );
12319 execute( TC_paging_imsi_nochan_ci() );
12320 execute( TC_paging_imsi_nochan_lai() );
12321 execute( TC_paging_imsi_nochan_lac() );
12322 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010012323 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
12324 execute( TC_paging_imsi_nochan_rnc() );
12325 execute( TC_paging_imsi_nochan_lac_rnc() );
12326 execute( TC_paging_imsi_nochan_lacs() );
12327 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010012328 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010012329 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010012330 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010012331 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010012332 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020012333 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020012334 execute( TC_paging_450req_no_paging_load_ind() );
Pau Espin Pedrol07657ae2023-01-03 12:08:05 +010012335 execute( TC_paging_imsi_nochan_ci_resp_invalid_mi() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010012336
12337 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010012338 execute( TC_rsl_unknown_unit_id() );
12339
12340 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012341
12342 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020012343 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012344 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010012345 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010012346 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010012347 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010012348 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012349
Harald Welte261af4b2018-02-12 21:20:39 +010012350 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020012351 execute( TC_ho_int_a5_0() );
12352 execute( TC_ho_int_a5_1() );
12353 execute( TC_ho_int_a5_3() );
12354 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000012355 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012356
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012357 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020012358 execute( TC_ho_out_fail_no_msc_response() );
12359 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020012360 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012361
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012362 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020012363 execute( TC_ho_into_this_bsc_a5_0() );
12364 execute( TC_ho_into_this_bsc_a5_1() );
12365 execute( TC_ho_into_this_bsc_a5_3() );
12366 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010012367 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
12368 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010012369 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012370 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12371 execute( TC_ho_into_this_bsc_tla_v6() );
12372 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020012373 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030012374 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010012375 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020012376 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020012377 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
12378 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012379 execute( TC_ho_in_fail_msc_clears() );
12380 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
12381 execute( TC_ho_in_fail_no_detect() );
12382 execute( TC_ho_in_fail_no_detect2() );
Oliver Smith7a8594a2023-02-13 14:30:49 +010012383 execute( TC_ho_in_fail_mgw_mdcx_timeout() );
Oliver Smith4eed06f2023-02-15 15:43:19 +010012384 execute( TC_ho_in_fail_ipa_crcx_timeout() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010012385 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012386
Neels Hofmeyr91401012019-07-11 00:42:35 +020012387 execute( TC_ho_neighbor_config_1() );
12388 execute( TC_ho_neighbor_config_2() );
12389 execute( TC_ho_neighbor_config_3() );
12390 execute( TC_ho_neighbor_config_4() );
12391 execute( TC_ho_neighbor_config_5() );
12392 execute( TC_ho_neighbor_config_6() );
12393 execute( TC_ho_neighbor_config_7() );
12394
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012395 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010012396 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010012397 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020012398
12399 execute( TC_dyn_pdch_ipa_act_deact() );
12400 execute( TC_dyn_pdch_ipa_act_nack() );
12401 execute( TC_dyn_pdch_osmo_act_deact() );
12402 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010012403 execute( TC_dyn_ts_sdcch8_act_deact() );
12404 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
12405 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
12406 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012407
Stefan Sperling0796a822018-10-05 13:01:39 +020012408 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020012409 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020012410
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010012411 /* Power control related */
12412 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020012413 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020012414
12415 /* MSC pooling */
12416 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
12417 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
12418 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
12419 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
12420 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12421 execute( TC_mscpool_L3Compl_on_1_msc() );
12422 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
12423 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
12424 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
12425 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
12426 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
12427 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
12428 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
12429 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
12430 execute( TC_mscpool_paging_and_response_imsi() );
12431 execute( TC_mscpool_paging_and_response_tmsi() );
12432 execute( TC_mscpool_no_allow_attach_round_robin() );
12433 execute( TC_mscpool_no_allow_attach_valid_nri() );
12434 }
12435
Harald Welte99f3ca02018-06-14 13:40:29 +020012436 execute( TC_early_conn_fail() );
12437 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020012438 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012439
Philipp Maier783681c2020-07-16 16:47:06 +020012440 /* Emergency call handling (deny / allow) */
12441 execute( TC_assignment_emerg_setup_allow() );
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +010012442 execute( TC_assignment_emerg_setup_allow_imei() );
Philipp Maier783681c2020-07-16 16:47:06 +020012443 execute( TC_assignment_emerg_setup_deny_msc() );
12444 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020012445 execute( TC_emerg_premption() );
12446
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070012447 /* Frequency hopping parameters handling */
12448 execute( TC_fh_params_chan_activ() );
12449 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070012450 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070012451 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070012452 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012453
12454 if (mp_enable_lcs_tests) {
12455 execute( TC_lcs_loc_req_for_active_ms() );
12456 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
12457 execute( TC_lcs_loc_req_for_idle_ms() );
12458 execute( TC_lcs_loc_req_no_subscriber() );
12459 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
12460 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
12461 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
12462 execute( TC_cm_service_during_lcs_loc_req() );
12463 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020012464 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020012465 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() );
12466 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012467 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000012468
12469 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000012470
12471 execute( TC_refuse_chan_act_to_vamos() );
12472 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000012473
12474 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020012475
12476 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020012477
12478 execute( TC_imm_ass_post_chan_ack() );
12479 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020012480 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020012481 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020012482 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020012483
12484 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012485
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020012486 execute( TC_ratectr_all_available_allocated() );
12487 execute( TC_ratectr_all_available_allocated_dyn() );
12488
Neels Hofmeyrb7581872021-11-07 14:02:49 +010012489 execute( TC_cm_serv_rej() );
12490
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012491 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012492
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012493 /* Channel allocator */
12494 execute( TC_chan_alloc_algo_ascending() );
12495 execute( TC_chan_alloc_algo_descending() );
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012496 execute( TC_chan_alloc_algo_ass_dynamic() );
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012497
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012498 /* MGW pool */
Pau Espin Pedrol4e431832023-02-08 12:43:47 +010012499 execute( TC_mgwpool_all_used() );
12500 execute( TC_mgwpool_blocked_not_used() );
12501 execute( TC_mgwpool_pin_bts() );
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012502
Oliver Smithc9a5f532022-10-21 11:32:23 +020012503 execute( TC_ho_meas_rep_multi_band() );
12504
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012505 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
12506 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
12507 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010012508}
12509
12510}