blob: 7773153a8d48808c2a4e514ac10fcd3c2ef07a33 [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;
Harald Welte801ed1a2023-04-30 15:07:00 +100026friend module BSC_Tests_ASCI;
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020027
Neels Hofmeyr4f118412020-06-04 15:25:10 +020028import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010029import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010030import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010031import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010032import from IPL4asp_Types all;
33
Harald Welte6f521d82017-12-11 19:52:02 +010034import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020035import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020036import from BSSAP_LE_Adapter all;
37import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020038import from BSSAP_LE_Types all;
39import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010040import from BSSAP_CodecPort all;
41import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010042import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010043import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010044import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020045import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010046import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010047import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010048import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010049import from MGCP_Templates all;
50import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020051import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010052
Harald Welte96c94412017-12-09 03:12:45 +010053import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010054import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010055import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010056
Daniel Willmannebdecc02020-08-12 15:30:17 +020057import from StatsD_Types all;
58import from StatsD_CodecPort all;
59import from StatsD_CodecPort_CtrlFunct all;
60import from StatsD_Checker all;
61
Harald Weltebc03c762018-02-12 18:09:38 +010062import from Osmocom_VTY_Functions all;
63import from TELNETasp_PortType all;
64
Harald Welte6f521d82017-12-11 19:52:02 +010065import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010066import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010067import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010068import from L3_Templates all;
69import from GSM_RR_Types all;
70
Stefan Sperlingc307e682018-06-14 15:15:46 +020071import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010072import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020073import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010074
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010075import from SCCPasp_Types all;
76
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020077import from GSM_SystemInformation all;
78import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020079import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020080
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060081const integer NUM_TRX := 4;
Harald Welte5d1a2202017-12-13 19:51:29 +010082const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020083const 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 +060084const 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 +020085const integer NUM_MSC := 3;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020086const integer NUM_MGW := 2;
Harald Welteae026692017-12-09 01:03:01 +010087const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010088
Harald Welte799c97b2017-12-14 17:50:30 +010089/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020090const integer NUM_TCHH_PER_BTS := 2;
91const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020092const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010093
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060094friend type record BtsTrxIdx {
95 uint8_t bts,
96 uint8_t trx
97}
98
99private type record BtsParams {
100 integer trx_num,
101 integer tsc
102}
103
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200104/* Default Training Sequence Code expected for bts[i]:
105 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
106 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
107 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
108 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
109 */
Harald Welte801ed1a2023-04-30 15:07:00 +1000110friend const BtsParams c_BtsParams[NUM_BTS_CFG] := {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600111 /* BTS0 */ { trx_num := 1, tsc := 2 },
112 /* BTS1 */ { trx_num := 1, tsc := 3 },
Vadim Yanitskiy7a3d2932022-05-29 20:37:46 +0600113 /* BTS2 */ { trx_num := 4, tsc := 4 },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600114 /* BTS3 */ { trx_num := 1, tsc := 4 }
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200115}
Harald Welte4003d112017-12-09 22:35:39 +0100116
Vadim Yanitskiy59494702022-09-14 15:29:04 +0700117private const RSL_IE_Body c_mr_conf_5_90 :=
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +0200118 valueof(RSL_IE_Body:{multirate_cfg := ts_RSL_MultirateCfg(true, 0, '00000100'B /* 5,90k */)});
119
Harald Welte21b46bd2017-12-17 19:46:32 +0100120/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100121type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100122 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100123 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100124}
125
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200126/* Default list of counters for an 'msc' entity. */
127const CounterNameVals counternames_msc_mscpool := {
128 { "mscpool:subscr:new", 0 },
129 { "mscpool:subscr:known", 0 },
130 { "mscpool:subscr:reattach", 0 },
131 { "mscpool:subscr:attach_lost", 0 },
132 { "mscpool:subscr:paged", 0 }
133};
134
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000135/* List of global mscpool counters, not related to a specific 'msc' entity. */
136const CounterNameVals counternames_bsc_mscpool := {
137 { "mscpool:subscr:no_msc", 0 }
138};
139
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000140/* Default list of counters for 'bsc' and 'bts' entities. */
141const CounterNameVals counternames_bsc_bts_handover := {
142 { "assignment:attempted", 0 },
143 { "assignment:completed", 0 },
144 { "assignment:stopped", 0 },
145 { "assignment:no_channel", 0 },
146 { "assignment:timeout", 0 },
147 { "assignment:failed", 0 },
148 { "assignment:error", 0 },
149
150 { "handover:attempted", 0 },
151 { "handover:completed", 0 },
152 { "handover:stopped", 0 },
153 { "handover:no_channel", 0 },
154 { "handover:timeout", 0 },
155 { "handover:failed", 0 },
156 { "handover:error", 0 },
157
158 { "intra_cell_ho:attempted", 0 },
159 { "intra_cell_ho:completed", 0 },
160 { "intra_cell_ho:stopped", 0 },
161 { "intra_cell_ho:no_channel", 0 },
162 { "intra_cell_ho:timeout", 0 },
163 { "intra_cell_ho:failed", 0 },
164 { "intra_cell_ho:error", 0 },
165
166 { "intra_bsc_ho:attempted", 0 },
167 { "intra_bsc_ho:completed", 0 },
168 { "intra_bsc_ho:stopped", 0 },
169 { "intra_bsc_ho:no_channel", 0 },
170 { "intra_bsc_ho:timeout", 0 },
171 { "intra_bsc_ho:failed", 0 },
172 { "intra_bsc_ho:error", 0 },
173
174 { "interbsc_ho_out:attempted", 0 },
175 { "interbsc_ho_out:completed", 0 },
176 { "interbsc_ho_out:stopped", 0 },
177 { "interbsc_ho_out:timeout", 0 },
178 { "interbsc_ho_out:failed", 0 },
179 { "interbsc_ho_out:error", 0 },
180
181 { "interbsc_ho_in:attempted", 0 },
182 { "interbsc_ho_in:completed", 0 },
183 { "interbsc_ho_in:stopped", 0 },
184 { "interbsc_ho_in:no_channel", 0 },
185 { "interbsc_ho_in:timeout", 0 },
186 { "interbsc_ho_in:failed", 0 },
187 { "interbsc_ho_in:error", 0 }
188};
189
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100190const CounterNameVals counternames_bts_handover := {
191 { "incoming_intra_bsc_ho:attempted", 0 },
192 { "incoming_intra_bsc_ho:completed", 0 },
193 { "incoming_intra_bsc_ho:stopped", 0 },
194 { "incoming_intra_bsc_ho:no_channel", 0 },
195 { "incoming_intra_bsc_ho:timeout", 0 },
196 { "incoming_intra_bsc_ho:failed", 0 },
197 { "incoming_intra_bsc_ho:error", 0 }
198};
199
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200200/* Set of all System Information received during one RSL port's startup.
201 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
202 * broadcast that SI type. That will be reflected as 'omit' here.
203 */
204type record SystemInformationConfig {
205 SystemInformationType1 si1 optional,
206 SystemInformationType2 si2 optional,
207 SystemInformationType2bis si2bis optional,
208 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200209 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200210 SystemInformationType3 si3 optional,
211 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100212 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200213 SystemInformationType5 si5 optional,
214 SystemInformationType5bis si5bis optional,
215 SystemInformationType5ter si5ter optional,
216 SystemInformationType6 si6 optional
217};
218
219const SystemInformationConfig SystemInformationConfig_omit := {
220 si1 := omit,
221 si2 := omit,
222 si2bis := omit,
223 si2ter := omit,
224 si2quater := omit,
225 si3 := omit,
226 si4 := omit,
227 si13 := omit,
228 si5 := omit,
229 si5bis := omit,
230 si5ter := omit,
231 si6 := omit
232};
233
234/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
235template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
236 template uint3_t meas_bw := 3)
237:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
238 meas_bw_presence := '1'B,
239 meas_bw := meas_bw);
240
241/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200242template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200243 template uint3_t prio := 3,
244 template (present) uint5_t thresh_high := 20,
245 template uint5_t thresh_low := 10,
246 template uint5_t qrxlevmin := 22)
247:= tr_EUTRAN_NeighbourCells(
248 cell_desc_list := cell_desc_list,
249 prio_presence := '1'B,
250 prio := prio,
251 thresh_high := thresh_high,
252 thresh_low_presence := '1'B,
253 thresh_low := thresh_low,
254 qrxlevmin_presence := '1'B,
255 qrxlevmin := qrxlevmin);
256
257template SystemInformationConfig SystemInformationConfig_default := {
258 si1 := {
259 cell_chan_desc := '8FB38000000000000000000000000000'O,
260 rach_control := {
261 max_retrans := RACH_MAX_RETRANS_7,
262 tx_integer := '1001'B,
263 cell_barr_access := false,
264 re_not_allowed := true,
265 acc := '0000010000000000'B
266 },
267 rest_octets := ?
268 },
269 si2 := {
270 bcch_freq_list := '00000000000000000000000000000000'O,
271 ncc_permitted := '11111111'B,
272 rach_control := {
273 max_retrans := RACH_MAX_RETRANS_7,
274 tx_integer := '1001'B,
275 cell_barr_access := false,
276 re_not_allowed := true,
277 acc := '0000010000000000'B
278 }
279 },
280 si2bis := omit,
281 si2ter := {
282 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
283 rest_octets := ?
284 },
285 si2quater := {
286 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
287 },
288 si3 := {
289 cell_id := 0,
290 lai := {
291 mcc_mnc := '001F01'H,
292 lac := 1
293 },
294 ctrl_chan_desc := {
295 msc_r99 := true,
296 att := true,
297 bs_ag_blks_res := 1,
298 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
299 si22ind := false,
300 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
301 spare := '00'B,
302 bs_pa_mfrms := 3,
303 t3212 := 30
304 },
305 cell_options := {
306 dn_ind := false,
307 pwrc := false,
308 dtx := MS_SHALL_USE_UL_DTX,
309 radio_link_tout_div4 := 7
310 },
311 cell_sel_par := {
312 cell_resel_hyst_2dB := 2,
313 ms_txpwr_max_cch := 7,
314 acs := '0'B,
315 neci := true,
316 rxlev_access_min := 0
317 },
318 rach_control := {
319 max_retrans := RACH_MAX_RETRANS_7,
320 tx_integer := '1001'B,
321 cell_barr_access := false,
322 re_not_allowed := true,
323 acc := '0000010000000000'B
324 },
325 rest_octets := {
326 sel_params := {
327 presence := '0'B,
328 params := omit
329 },
330 pwr_offset := {
331 presence := '0'B,
332 offset := omit
333 },
334 si_2ter_ind := '1'B,
335 early_cm_ind := '0'B,
336 sched_where := {
337 presence := '0'B,
338 where := omit
339 },
340 gprs_ind := {
341 presence := '1'B,
342 ind := {
343 ra_colour := 0,
344 si13_pos := '0'B
345 }
346 },
347 umts_early_cm_ind := '1'B,
348 si2_quater_ind := {
349 presence := '1'B,
350 ind := '0'B
351 },
352 iu_mode_ind := omit,
353 si21_ind := {
354 presence := '0'B,
355 pos := omit
356 }
357 }
358 },
359 si4 := {
360 lai := {
361 mcc_mnc := '001F01'H,
362 lac := 1
363 },
364 cell_sel_par := {
365 cell_resel_hyst_2dB := 2,
366 ms_txpwr_max_cch := 7,
367 acs := '0'B,
368 neci := true,
369 rxlev_access_min := 0
370 },
371 rach_control := {
372 max_retrans := RACH_MAX_RETRANS_7,
373 tx_integer := '1001'B,
374 cell_barr_access := false,
375 re_not_allowed := true,
376 acc := '0000010000000000'B
377 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200378 cbch_chan_desc := {
379 iei := '64'O,
380 v := {
381 chan_nr := {
382 u := {
383 sdcch4 := {
384 tag := '001'B,
385 sub_chan := 2
386 }
387 },
388 tn := 0
389 },
390 tsc := 2,
391 h := false,
392 arfcn := 871,
393 maio_hsn := omit
394 }
395 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200396 cbch_mobile_alloc := omit,
397 rest_octets := {
398 sel_params := {
399 presence := '0'B,
400 params := omit
401 },
402 pwr_offset := {
403 presence := '0'B,
404 offset := omit
405 },
406 gprs_ind := {
407 presence := '1'B,
408 ind := {
409 ra_colour := 0,
410 si13_pos := '0'B
411 }
412 },
413 s_presence := '0'B,
414 s := omit
415 }
416 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100417 si13 := {
418 rest_octets := {
419 presence := '1'B,
420 bcch_change_mark := ?,
421 si_change_field := '0000'B,
422 presence2 := '0'B,
423 si13_change_mark := omit,
424 gprs_ma := omit,
425 zero := '0'B, /* PBCCH not present in cell */
426 rac := 0,
427 spgc_ccch_sup := '0'B,
428 priority_access_thr := '110'B,
429 network_control_order := '00'B,
430 gprs_cell_opts := {
431 nmo := '01'B,
432 t3168 := '011'B,
433 t3192 := '010'B,
434 drx_timer_max := '011'B,
435 access_burst_type := '0'B,
436 control_ack_type := '1'B,
437 bs_cv_max := 15,
438 pan_presence := '1'B,
439 pan_dec := 1,
440 pan_inc := 1,
441 pan_max := '111'B,
442 ext_info_presence := ?,
443 ext_info_length := *,
444 ext_info := *
445 },
446 gprs_pwr_ctrl_params := {
447 alpha := 0,
448 t_avg_w := '10000'B,
449 t_avg_t := '10000'B,
450 pc_meas_chan := '0'B,
451 n_avg_i := '1000'B
452 }
453 }
454 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200455 si5 := {
456 bcch_freq_list := '10000000000000000000000000000000'O
457 },
458 si5bis := omit,
459 si5ter := {
460 extd_bcch_freq_list := '9E050020000000000000000000000000'O
461 },
462 si6 := {
463 cell_id := 0,
464 lai := {
465 mcc_mnc := '001F01'H,
466 lac := 1
467 },
468 cell_options := {
469 dtx_ext := '1'B,
470 pwrc := false,
471 dtx := '01'B,
472 radio_link_timeout := '0111'B
473 },
474 ncc_permitted := '11111111'B,
Vadim Yanitskiy348b07c2022-03-10 17:11:22 +0300475 rest_octets := {
476 pch_nch_info := ?,
477 vbs_vgcs_options := ?,
478 dtm_support := '0'B,
479 rac := omit,
480 max_lapdm := omit,
481 band_ind := '0'B /* C0 ARFCN indicates 1800 band */
482 }
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200483 }
484 };
485
486
487/* List of all the System Information received on all RSL ports */
488type record of SystemInformationConfig SystemInformationConfig_list;
489
490function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
491{
492 var RSL_IE_Body sysinfo_type_ie;
493 var RSL_IE_SysinfoType si_type;
494 var octetstring data;
495
496 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
497 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
498 mtc.stop;
499 }
500 si_type := sysinfo_type_ie.sysinfo_type;
501
502 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
503 var RSL_IE_Body bcch_ie;
504 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
505 data := bcch_ie.other.payload;
506 }
507 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
508 var RSL_IE_Body l3_ie;
509 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
510 data := l3_ie.l3_info.payload;
511 }
512 } else {
513 setverdict(fail, "Don't understand this System Information message");
514 mtc.stop;
515 }
516
517 var boolean handled := false;
518
519 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
520 handled := true;
521
522 if (si_type == RSL_SYSTEM_INFO_1) {
523 if (not isbound(data)) {
524 si.si1 := omit;
525 } else {
526 si.si1 := dec_SystemInformation(data).payload.si1;
527 }
528 } else if (si_type == RSL_SYSTEM_INFO_2) {
529 if (not isbound(data)) {
530 si.si2 := omit;
531 } else {
532 si.si2 := dec_SystemInformation(data).payload.si2;
533 }
534 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
535 if (not isbound(data)) {
536 si.si2bis := omit;
537 } else {
538 si.si2bis := dec_SystemInformation(data).payload.si2bis;
539 }
540 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
541 if (not isbound(data)) {
542 si.si2ter := omit;
543 } else {
544 si.si2ter := dec_SystemInformation(data).payload.si2ter;
545 }
546 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
547 if (not isbound(data)) {
548 si.si2quater := {};
549 } else {
550 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
551 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
552 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
553 }
554 } else if (si_type == RSL_SYSTEM_INFO_3) {
555 if (not isbound(data)) {
556 si.si3 := omit;
557 } else {
558 si.si3 := dec_SystemInformation(data).payload.si3;
559 }
560 } else if (si_type == RSL_SYSTEM_INFO_4) {
561 if (not isbound(data)) {
562 si.si4 := omit;
563 } else {
564 si.si4 := dec_SystemInformation(data).payload.si4;
565 }
566 } else if (si_type == RSL_SYSTEM_INFO_13) {
567 if (not isbound(data)) {
568 si.si13 := omit;
569 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100570 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200571 }
572 } else {
573 handled := false;
574 }
575 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
576 handled := true;
577
578 if (si_type == RSL_SYSTEM_INFO_5) {
579 if (not isbound(data)) {
580 si.si5 := omit;
581 } else {
582 si.si5 := dec_SystemInformation(data).payload.si5;
583 }
584 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
585 if (not isbound(data)) {
586 si.si5bis := omit;
587 } else {
588 si.si5bis := dec_SystemInformation(data).payload.si5bis;
589 }
590 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
591 if (not isbound(data)) {
592 si.si5ter := omit;
593 } else {
594 si.si5ter := dec_SystemInformation(data).payload.si5ter;
595 }
596 } else if (si_type == RSL_SYSTEM_INFO_6) {
597 if (not isbound(data)) {
598 si.si6 := omit;
599 } else {
600 si.si6 := dec_SystemInformation(data).payload.si6;
601 }
602 } else {
603 handled := false;
604 }
605 }
606
607 if (not handled) {
608 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
609 }
610}
611
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +0100612friend function gen_l3_valid_payload(hexstring imsi := ''H) return octetstring {
613 var octetstring l3_payload;
614 if (lengthof(imsi) == 0) {
615 imsi := f_rnd_imsi('00101'H);
616 }
617 l3_payload := enc_PDU_ML3_MS_NW(valueof(ts_LU_REQ(LU_Type_IMSI_Attach, ts_MI_LV(ts_MI_IMSI(imsi)))));
618 return l3_payload;
619}
620
Harald Weltea4ca4462018-02-09 00:17:14 +0100621type component test_CT extends CTRL_Adapter_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600622 /* Array of per-BTS/TRX state */
623 var BTS_State bts[NUM_BTS][NUM_TRX];
Harald Welte89ab1912018-02-23 18:56:29 +0100624 /* RSL common Channel Port (for RSL_Emulation) */
625 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600626 /* array of per-BTS/TRX RSL test ports */
627 port IPA_RSL_PT IPA_RSL[NUM_BTS][NUM_TRX];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100628 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200629 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
630 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200631 /* Configure/manage IPA_Emulation per-BTS/TRX port: */
632 port IPA_CFG_PT IPA_CFG_PORT[NUM_BTS][NUM_TRX];
Harald Weltea5d2ab22017-12-09 14:21:42 +0100633
Pau Espin Pedrol3c630532022-10-20 19:00:11 +0200634 var MGCP_Emulation_CT vc_MGCP[NUM_MGW];
635 var integer g_nr_mgw; /* number of vc_MGCP to initialize */
Harald Weltebc03c762018-02-12 18:09:38 +0100636 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100637
Daniel Willmannebdecc02020-08-12 15:30:17 +0200638 /* StatsD */
639 var StatsD_Checker_CT vc_STATSD;
640
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200641 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200642 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100643 /* for old legacy-tests only */
644 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200645 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100646
Harald Welte21b46bd2017-12-17 19:46:32 +0100647 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100648 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100649
Neels Hofmeyr38632aa2023-04-05 03:50:51 +0200650 var boolean g_handler_mode := false;
651
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200652 /* Osmux is enabled through VTY */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200653 var boolean g_osmux_enabled_cn := false;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +0200654 var boolean g_osmux_enabled_bts := false;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200655
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100656 /*Configure T(tias) over VTY, seconds */
657 var integer g_bsc_sccp_timer_ias := 7 * 60;
658 /*Configure T(tiar) over VTY, seconds */
659 var integer g_bsc_sccp_timer_iar := 15 * 60;
660
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200661 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100662 timer T_guard := 30.0;
663
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200664 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000665 var CounterNameValsList g_ctr_bsc;
666 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200667
668 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
669 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100670}
671
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200672type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100673modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100674 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100675 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100676 /* port number to which to establish the IPA OML connections */
677 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100678 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100679 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100680 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100681 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200682 /* port number to which to listen for STATSD metrics */
683 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100684 /* IP address at which the test binds */
685 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100686
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200687 RAN_Configurations mp_bssap_cfg := {
688 {
689 transport := BSSAP_TRANSPORT_AoIP,
690 sccp_service_type := "mtp3_itu",
691 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
692 own_pc := 185, /* 0.23.1 first MSC emulation */
693 own_ssn := 254,
694 peer_pc := 187, /* 0.23.3 osmo-bsc */
695 peer_ssn := 254,
696 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200697 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200698 },
699 {
700 transport := BSSAP_TRANSPORT_AoIP,
701 sccp_service_type := "mtp3_itu",
702 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
703 own_pc := 2, /* 0.0.2 second MSC emulation */
704 own_ssn := 254,
705 peer_pc := 187, /* 0.23.3 osmo-bsc */
706 peer_ssn := 254,
707 sio := '83'O,
708 rctx := 2
709 },
710 {
711 transport := BSSAP_TRANSPORT_AoIP,
712 sccp_service_type := "mtp3_itu",
713 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
714 own_pc := 3, /* 0.0.3 third MSC emulation */
715 own_ssn := 254,
716 peer_pc := 187, /* 0.23.3 osmo-bsc */
717 peer_ssn := 254,
718 sio := '83'O,
719 rctx := 3
720 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100721 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200722
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200723 /* Must match per BTS config in osmo-bsc.cfg */
724 phys_chan_configs phys_chan_config := {
725 "CCCH+SDCCH4+CBCH",
726 "TCH/F",
727 "TCH/F",
728 "TCH/F",
729 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600730 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200731 "PDCH",
732 "PDCH"
733 };
734
Harald Welte47cd0e32020-08-21 12:39:11 +0200735 BSSAP_LE_Configuration mp_bssap_le_cfg := {
736 sccp_service_type := "mtp3_itu",
737 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200738 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200739 own_ssn := 252, /* SMLC side SSN */
740 peer_pc := 187, /* 0.23.3 osmo-bsc */
741 peer_ssn := 250, /* BSC side SSN */
742 sio := '83'O,
743 rctx := 6
744 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200745 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200746
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100747 /* Value set in osmo-bsc.cfg "ms max power" */
748 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600749
750 /* Whether to check for memory leaks */
751 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100752}
753
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200754friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200755
756 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200757 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200758 pars.aoip := true;
759 } else {
760 pars.aoip := false;
761 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100762 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200763 pars.mscpool.bssap_idx := bssap_idx;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600764 pars.expect_tsc := c_BtsParams[0].tsc;
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300765 pars.imsi := f_rnd_imsi('00101'H);
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +0100766 pars.imei := f_rnd_imei('00101'H);
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300767
768 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200769
Philipp Maier48604732018-10-09 15:00:37 +0200770 return pars;
771}
772
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200773/* Convenience functions for rate counters using g_ctr_msc. */
774
775private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
776 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
777 log("initial msc rate counters: ", g_ctr_msc);
778}
779
780private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200781 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200782}
783
784/* f_ctrs_msc_init();
785 * f_do_thing(on_msc := 0);
786 * f_do_thing(on_msc := 0);
787 * f_do_other(on_msc := 1);
788 * f_ctrs_msc_add(0, "thing", 2);
789 * f_ctrs_msc_add(1, "other");
790 * f_ctrs_msc_verify();
791 */
792private function f_ctrs_msc_verify() runs on test_CT {
793 log("verifying msc rate counters: ", g_ctr_msc);
794 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
795}
796
797/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
798 * f_ctrs_msc_init();
799 * f_do_thing(on_msc := 0);
800 * f_do_thing(on_msc := 0);
801 * f_do_thing(on_msc := 0);
802 * f_ctrs_msc_expect(0, "thing", 3);
803 */
804private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
805 f_ctrs_msc_add(msc_nr, countername, val);
806 f_ctrs_msc_verify();
807}
808
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000809/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
810
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100811private 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 +0000812 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100813 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100814}
815
816function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
817 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000818 f_ctrs_bsc_init(counternames);
819}
820
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100821private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
822 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100823 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100824 f_ctrs_bsc_init(counternames_bsc_bts_handover);
825}
826
827private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000828 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100829}
830
831private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
832 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000833 f_ctrs_bsc_add(countername, val);
834}
835
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100836function f_ctrs_bts_verify() runs on test_CT {
837 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
838}
839
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000840/* f_ctrs_bsc_and_bts_init();
841 * f_do_thing(on_bts := 0);
842 * f_do_thing(on_bts := 0);
843 * f_do_other(on_bts := 1);
844 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
845 * f_ctrs_bsc_and_bts_add(1, "other");
846 * f_ctrs_bsc_and_bts_verify();
847 */
848private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100849 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000850 f_ctrs_bsc_verify();
851}
852
853/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
854 * f_ctrs_bsc_and_bts_init();
855 * f_do_thing(on_bts := 0);
856 * f_do_thing(on_bts := 0);
857 * f_do_thing(on_bts := 0);
858 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
859 */
860private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
861 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
862 f_ctrs_bsc_and_bts_verify();
863}
864
865
866/* Convenience functions for rate counters using g_ctr_bsc. */
867
868private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
869 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
870 log("initial bsc rate counters: ", g_ctr_bsc);
871}
872
873private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
874 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
875}
876
877/* f_ctrs_bsc_init();
878 * f_do_thing();
879 * f_do_thing();
880 * f_do_other();
881 * f_ctrs_bsc_add("thing", 2);
882 * f_ctrs_bsc_add("other");
883 * f_ctrs_bsc_verify();
884 */
885private function f_ctrs_bsc_verify() runs on test_CT {
886 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
887}
888
889/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
890 * f_ctrs_bsc_init();
891 * f_do_thing();
892 * f_ctrs_bsc_expect("thing", 1);
893 */
894private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
895 f_ctrs_bsc_add(countername, val);
896 f_ctrs_bsc_verify();
897}
898
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200899
Oliver Smith39f53072022-10-27 14:44:04 +0200900friend function f_shutdown_helper(boolean ho := false) runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100901 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600902 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100903 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
904 }
905
Oliver Smith39f53072022-10-27 14:44:04 +0200906 /* Reset handover related configuration */
907 if (ho) {
908 f_bts_0_cfg(BSCVTY,
909 {"no neighbors",
910 "neighbor-list mode manual-si5",
911 "neighbor-list add arfcn 100",
912 "neighbor-list add arfcn 200",
913 "si5 neighbor-list add arfcn 10",
914 "si5 neighbor-list add arfcn 20",
915 "handover algorithm 1"});
916 }
917
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200918 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100919 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200920 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100921}
922
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200923private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100924 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200925 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100926 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200927 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 +0200928 ts_BSSMAP_Reset(0, g_osmux_enabled_cn)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100929 T.start;
930 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200931 [] 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 +0200932 tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200933 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100934 }
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200935 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200936 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100937 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200938 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200939 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100940 repeat;
941 }
942 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200943 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200944 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200945 /* If we received a RESET after ours was sent, it
946 may be a race condition where the other peer beacame
947 available after we sent it, but we are in a desired
948 state anyway, so go forward. */
949 if (not reset_received) {
950 setverdict(fail);
951 }
952 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100953 }
Harald Welte28d943e2017-11-25 15:00:50 +0100954}
955
Harald Welteae026692017-12-09 01:03:01 +0100956type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100957 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100958 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100959 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100960 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100961 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100962 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100963 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100964 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100965}
966
Harald Welte21b46bd2017-12-17 19:46:32 +0100967/*! Start the IPA/RSL related bits for one IPA_Client.
968 * \param clnt IPA_Client for which to establish
969 * \param bsc_host IP address / hostname of the BSC
970 * \param bsc_port TCP port number of the BSC
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600971 * \param idx BTS/TRX index values
Harald Welte21b46bd2017-12-17 19:46:32 +0100972 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600973function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port,
974 BtsTrxIdx idx := {0, 0}, boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100975runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100976 timer T := 10.0;
977
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600978 clnt.id := "IPA-BTS" & int2str(idx.bts) & "-TRX" & int2str(idx.trx) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100979 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100980 clnt.ccm_pars := c_IPA_default_ccm_pars;
981 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600982 clnt.ccm_pars.unit_id := int2str(1234 + idx.bts) & "/0/" & int2str(idx.trx);
Harald Welte624f9632017-12-16 19:26:04 +0100983 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100984 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600985 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[idx.bts]);
Harald Welte624f9632017-12-16 19:26:04 +0100986 }
Harald Welteae026692017-12-09 01:03:01 +0100987
988 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200989 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100990 if (handler_mode) {
991 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
992 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600993 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100994 }
Harald Welteae026692017-12-09 01:03:01 +0100995
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600996 var integer local_port := 10000 + idx.bts * 1000 + idx.trx;
997 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", local_port, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100998 if (handler_mode) {
999 clnt.vc_RSL.start(RSL_Emulation.main());
1000 return;
1001 }
Harald Welteae026692017-12-09 01:03:01 +01001002
1003 /* wait for IPA RSL link to connect and send ID ACK */
1004 T.start;
1005 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001006 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +01001007 T.stop;
Harald Welteae026692017-12-09 01:03:01 +01001008 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001009 [] IPA_RSL[idx.bts][idx.trx].receive(ASP_IPA_Event:?) { repeat }
1010 [] IPA_RSL[idx.bts][idx.trx].receive { repeat }
Harald Welteae026692017-12-09 01:03:01 +01001011 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +01001012 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001013 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +01001014 }
1015 }
1016}
1017
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001018function f_ipa_rsl_stop(inout IPA_Client clnt, BtsTrxIdx idx := {0, 0}) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001019 var IPL4asp_Types.Result res := {
1020 errorCode := omit,
1021 connId := omit,
1022 os_error_code := omit,
1023 os_error_text := omit
1024 };
1025
Harald Welte12055472018-03-17 20:10:08 +01001026 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
1027 return;
1028 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001029
1030 /* Alive components don't finish sockets (TCP FIN) when they are
1031 * stopped. Hence, we need to manually call close() on them to make sure
1032 * the IUT knows about it. */
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001033 f_ipa_cfg_disconnect(IPA_CFG_PORT[idx.bts][idx.trx], res);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001034
Harald Welte12055472018-03-17 20:10:08 +01001035 clnt.vc_IPA.stop;
1036 if (isbound(clnt.vc_RSL)) {
1037 clnt.vc_RSL.stop;
1038 }
1039}
1040
Harald Welte21b46bd2017-12-17 19:46:32 +01001041/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +01001042function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1043 timer T := secs_max;
1044 T.start;
1045 while (true) {
1046 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1047 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001048 /* the 'degraded' state exists from OML connection time, and we have to wait
1049 * until all MO's are initialized */
1050 T.start(1.0);
1051 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001052 return;
1053 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001054 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001055 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001056 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001057 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001058 }
1059 }
1060}
1061
Harald Welte21b46bd2017-12-17 19:46:32 +01001062/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001063altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001064 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001065 [] T_guard.timeout {
1066 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001067 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001068 }
Harald Welte60e823a2017-12-10 14:10:59 +01001069 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001070 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001071 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001072 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Harald Welte69c1c262017-12-13 21:02:08 +01001073 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001074 }
Harald Welte28d943e2017-11-25 15:00:50 +01001075}
1076
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001077altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001078 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001079 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001080 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001081 }
1082}
1083
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001084function f_init_mgcp(integer mgw_nr, charstring id) runs on test_CT {
1085 id := id & "-MGCP-" & int2str(mgw_nr);
Daniel Willmann191e0d92018-01-17 12:44:35 +01001086
1087 var MGCPOps ops := {
1088 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1089 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1090 };
1091 var MGCP_conn_parameters mgcp_pars := {
1092 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001093 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001094 mgw_ip := mp_test_ip,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001095 mgw_udp_port := 2427 + mgw_nr,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001096 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
Pau Espin Pedrol36eeaf72022-10-20 16:50:31 +02001097 the one with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001098 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001099 };
1100
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001101 vc_MGCP[mgw_nr] := MGCP_Emulation_CT.create(id) alive;
1102 vc_MGCP[mgw_nr].start(MGCP_Emulation.main(ops, mgcp_pars, id));
Daniel Willmann191e0d92018-01-17 12:44:35 +01001103}
1104
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001105/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1106 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1107 * OsmuxCID IE.
1108 */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001109private function f_vty_allow_osmux_cn(boolean allow) runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001110 f_vty_enter_cfg_msc(BSCVTY, 0);
1111 if (allow) {
1112 f_vty_transceive(BSCVTY, "osmux on");
1113 } else {
1114 f_vty_transceive(BSCVTY, "osmux off");
1115 }
1116 f_vty_transceive(BSCVTY, "exit");
1117 f_vty_transceive(BSCVTY, "exit");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001118}
1119
Max2253c0b2018-11-06 19:28:05 +01001120function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001121 if (BSCVTY.checkstate("Mapped")) {
1122 /* skip initialization if already executed once */
1123 return;
1124 }
Harald Weltebc03c762018-02-12 18:09:38 +01001125 map(self:BSCVTY, system:BSCVTY);
1126 f_vty_set_prompts(BSCVTY);
1127 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001128 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1129 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001130}
1131
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001132friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001133{
1134 // log on TTCN3 log output
1135 log(log_msg);
1136 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001137 if (pt.checkstate("Mapped")) {
1138 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1139 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001140}
1141
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001142private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1143{
1144 if (rsl_idx >= lengthof(g_system_information)) {
1145 g_system_information[rsl_idx] := SystemInformationConfig_omit
1146 }
1147 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1148}
1149
1150altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1151 var ASP_RSL_Unitdata rx_rsl_ud;
1152
1153 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001154 [] 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 +02001155 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1156 repeat;
1157 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001158 [] 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 +02001159 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1160 repeat;
1161 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001162 [] 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 +02001163 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1164 repeat;
1165 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001166 [] 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 +02001167 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1168 repeat;
1169 }
1170
1171 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1172 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1173 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1174 repeat;
1175 }
1176 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1177 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1178 repeat;
1179 }
1180 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1181 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1182 repeat;
1183 }
1184 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1185 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1186 repeat;
1187 }
1188}
1189
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001190/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1191private type record of boolean my_BooleanList;
1192
1193private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1194{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001195 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1196
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001197 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001198 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1199 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1200 * stepping into that config node. */
1201 log("msc ", msc_nr, " is not configured, skipping");
1202 continue;
1203 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001204 f_vty_enter_cfg_msc(pt, msc_nr);
1205 if (allow_attach_list[msc_nr]) {
1206 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1207 f_vty_transceive(pt, "allow-attach", strict := false);
1208 } else {
1209 f_vty_transceive(pt, "no allow-attach", strict := false);
1210 }
1211 f_vty_transceive(pt, "exit");
1212 f_vty_transceive(pt, "exit");
1213 }
1214}
1215
Neels Hofmeyr38632aa2023-04-05 03:50:51 +02001216private function f_bssap_idx_init(integer bssap_idx) runs on test_CT {
1217 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1218 * MSC-side BSSAP emulation */
1219 if (g_handler_mode) {
1220 var RanOps ranops := MSC_RanOps;
1221 ranops.use_osmux := g_osmux_enabled_cn;
1222 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1223 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1224 f_ran_adapter_start(g_bssap[bssap_idx]);
1225 } else {
1226 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1227 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1228 f_ran_adapter_start(g_bssap[bssap_idx]);
1229 f_legacy_bssap_reset();
1230 }
1231}
1232
1233private function f_bssap_idx_disconnect(integer bssap_idx) runs on test_CT {
1234 f_ran_adapter_cleanup(g_bssap[bssap_idx]);
1235}
1236
Harald Welte21b46bd2017-12-17 19:46:32 +01001237/* global initialization function
1238 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001239 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1240 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1241 */
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001242function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001243 integer nr_msc := 1, integer nr_mgw := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001244 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001245
Harald Welteae026692017-12-09 01:03:01 +01001246 if (g_initialized) {
1247 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001248 }
Harald Welteae026692017-12-09 01:03:01 +01001249 g_initialized := true;
1250
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001251 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001252 activate(as_Tguard());
1253
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001254 f_init_vty("VirtMSC");
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001255 f_vty_allow_osmux_cn(g_osmux_enabled_cn);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001256
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001257 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001258 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1259
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001260 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1261 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1262 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1263 }
1264
Neels Hofmeyr38632aa2023-04-05 03:50:51 +02001265 g_handler_mode := handler_mode;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001266 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001267 allow_attach[bssap_idx] := true;
Neels Hofmeyr38632aa2023-04-05 03:50:51 +02001268 f_bssap_idx_init(bssap_idx);
Harald Welte67089ee2018-01-17 22:19:03 +01001269 }
Harald Welted5833a82018-05-27 16:52:56 +02001270
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001271 if (mp_enable_lcs_tests) {
1272 if (handler_mode) {
1273 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1274 } else {
1275 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1276 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1277 }
1278 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001279 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001280
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001281 /* start the test with exactly all enabled MSCs allowed to attach */
1282 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1283
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001284 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001285
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001286 g_nr_mgw := nr_mgw;
1287 for (var integer i := 0; i < g_nr_mgw; i := i+1) {
1288 f_init_mgcp(i, "VirtMGW");
1289 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01001290
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001291 for (var integer i := 0; i < nr_bts; i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001292 f_init_bts(i, c_BtsParams[i].trx_num, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001293 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001294
1295 /* Emit a marker to appear in the SUT's own logging output */
1296 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001297}
Harald Welte696ddb62017-12-08 14:01:43 +01001298
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001299function f_init_bts(integer bts_idx := 0,
1300 integer trx_num := NUM_TRX_CFG,
1301 boolean handler_mode := false)
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001302runs on test_CT {
1303 /* wait until osmo-bts-omldummy has respawned */
1304 f_wait_oml(bts_idx, "degraded", 5.0);
1305
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001306 /* start RSL connection(s) */
1307 for (var integer trx_idx := 0; trx_idx < trx_num; trx_idx := trx_idx + 1) {
1308 f_ipa_rsl_start(bts[bts_idx][trx_idx].rsl,
1309 mp_bsc_ip, mp_bsc_rsl_port,
1310 {bts_idx, trx_idx}, handler_mode);
1311 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001312 /* wait until BSC tells us "connected" */
1313 f_wait_oml(bts_idx, "connected", 5.0);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001314
1315 /* Set up BTS with VTY commands: */
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01001316 f_vty_enter_cfg_bts(BSCVTY, bts_idx);
1317 if (g_osmux_enabled_bts) {
1318 f_vty_transceive(BSCVTY, "osmux on");
1319 } else {
1320 f_vty_transceive(BSCVTY, "osmux off");
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001321 }
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01001322 f_vty_transceive(BSCVTY, "end");
Harald Welte28d943e2017-11-25 15:00:50 +01001323}
1324
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001325function f_init_bts_and_check_sysinfo(integer bts_idx := 0,
1326 integer trx_num := NUM_TRX_CFG,
1327 boolean handler_mode := false,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001328 template SystemInformationConfig expect_si)
1329runs on test_CT {
1330 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1331
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001332 f_init_bts(bts_idx, trx_num, handler_mode);
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001333
1334 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1335 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1336 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1337 */
1338 f_sleep(5.0);
1339 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1340
1341 deactivate(sysinfo);
1342
1343 if (match(g_system_information[bts_idx], expect_si)) {
1344 setverdict(pass);
1345 } else {
1346 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1347 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1348 setverdict(fail, "received SI does not match expectations");
1349 return;
1350 }
1351}
1352
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001353/* expect to receive a RSL message matching a specified template on a given BTS / TRX */
1354function f_exp_ipa_rx(template (present) RSL_Message t_rx,
1355 BtsTrxIdx idx := {0, 0},
1356 float Tval := 2.0)
Harald Welteae026692017-12-09 01:03:01 +01001357runs on test_CT return RSL_Message {
1358 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001359 timer T := Tval;
Harald Welteae026692017-12-09 01:03:01 +01001360
1361 T.start;
1362 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001363 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001364 T.stop;
1365 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001366 [] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001367 [] T.timeout {
1368 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001369 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001370 }
Harald Welteae026692017-12-09 01:03:01 +01001371 }
1372 return rx_rsl_ud.rsl;
1373}
1374
Harald Welte21b46bd2017-12-17 19:46:32 +01001375/* helper function to transmit RSL on a given BTS/stream */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001376function f_ipa_tx(template (value) RSL_Message t_tx,
1377 BtsTrxIdx idx := {0, 0},
1378 IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001379runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001380 IPA_RSL[idx.bts][idx.trx].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001381}
1382
1383
Harald Welte4003d112017-12-09 22:35:39 +01001384/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001385testcase TC_chan_act_noreply() runs on test_CT {
1386 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001387 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001388
Harald Welte89d42e82017-12-17 16:42:41 +01001389 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001390
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001391 f_ipa_tx(ts_RSL_CHAN_RQD('23'O, 23));
1392 rsl_unused := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001393 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001394}
1395
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001396const CounterNameVals counternames_bts_chreq := {
1397 { "chreq:total", 0 },
1398 { "chreq:attempted_emerg", 0 },
1399 { "chreq:attempted_call", 0 },
1400 { "chreq:attempted_location_upd", 0 },
1401 { "chreq:attempted_pag", 0 },
1402 { "chreq:attempted_pdch", 0 },
1403 { "chreq:attempted_other", 0 },
1404 { "chreq:attempted_unknown", 0 },
1405 { "chreq:successful", 0 },
1406 { "chreq:successful_emerg", 0 },
1407 { "chreq:successful_call", 0 },
1408 { "chreq:successful_location_upd", 0 },
1409 { "chreq:successful_pag", 0 },
1410 { "chreq:successful_pdch", 0 },
1411 { "chreq:successful_other", 0 },
1412 { "chreq:successful_unknown", 0 },
1413 { "chreq:no_channel", 0 },
1414 { "chreq:max_delay_exceeded", 0 }
1415};
1416
1417/* verify the "chreq:*" counters */
1418private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1419{
1420 var GsmFrameNumber fn := 23;
1421
1422 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1423
1424 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001425 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn));
1426 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001427 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1428
1429 f_ctrs_bts_add(0, "chreq:total");
1430 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1431 f_ctrs_bts_verify();
1432
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001433 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1434 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001435
1436 f_ctrs_bts_add(0, "chreq:successful");
1437 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1438 f_ctrs_bts_verify();
1439
1440 /* test is done, release RSL Conn Fail Ind to clean up */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001441 f_ipa_tx(ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1442 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
1443 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001444 f_sleep(1.0);
1445}
1446
Harald Welte4003d112017-12-09 22:35:39 +01001447testcase TC_chan_act_counter() runs on test_CT {
1448 var BSSAP_N_UNITDATA_ind ud_ind;
1449 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001450 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001451
Harald Welte89d42e82017-12-17 16:42:41 +01001452 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001453
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001454 f_vty_allow_emerg_bts(true, 0);
1455
1456 f_ctrs_bts_init(1, counternames_bts_chreq);
1457
1458 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1459 f_chan_act_counter('a3'O, "emerg");
1460
1461 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1462 f_chan_act_counter('43'O, "call");
1463
1464 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1465 f_chan_act_counter('03'O, "location_upd");
1466
1467 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1468 f_chan_act_counter('23'O, "pag");
1469 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1470 f_chan_act_counter('33'O, "pag");
1471
1472 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1473 /* no PCU, so PDCH not allowed. Skip this test for now. */
1474 /* f_chan_act_counter('7b'O, "pdch"); */
1475
1476 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1477 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001478
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001479 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001480}
1481
Harald Welteae026692017-12-09 01:03:01 +01001482/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001483private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001484 var RSL_Message rx_rsl;
1485
Harald Welteae026692017-12-09 01:03:01 +01001486 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001487 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001488
1489 /* expect BSC to disable the channel again if there's no RLL EST IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001490 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := T3101_MAX);
Harald Welteae026692017-12-09 01:03:01 +01001491
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001492 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001493}
1494
Philipp Maier9c60a622020-07-09 15:08:46 +02001495/* Normal variant */
1496testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001497 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001498 f_TC_chan_act_ack_noest();
1499}
1500
1501/* Emergency call variant */
1502testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1503 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001504 f_init(1);
1505 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001506 f_TC_chan_act_ack_noest(ra := 'A5'O);
1507}
1508
Philipp Maier606f07d2020-08-12 17:21:58 +02001509/* Emergency call variant, but emergency calls are not allowed */
1510testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1511 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1512
1513 var RSL_Message rx_rsl;
1514 var GsmRrMessage rr;
1515
1516 f_init(1);
1517 f_vty_allow_emerg_bts(false, 0);
1518
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001519 IPA_RSL[0][0].clear;
1520 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier606f07d2020-08-12 17:21:58 +02001521
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001522 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Philipp Maier606f07d2020-08-12 17:21:58 +02001523 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1524 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1525 setverdict(pass);
1526 } else {
1527 setverdict(fail, "immediate assignment not rejected");
1528 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001529
1530 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001531}
1532
Harald Welteae026692017-12-09 01:03:01 +01001533/* Test behavior if MSC never answers to CR */
1534testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001535 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1536 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001537 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001538 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001539 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001540
Harald Welte89d42e82017-12-17 16:42:41 +01001541 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001542
1543 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001544 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001545
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001546 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001547
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001548 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload)));
Harald Welteae026692017-12-09 01:03:01 +01001549
1550 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001551 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001552 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001553 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001554}
1555
1556/* Test behavior if MSC answers with CREF to CR */
1557testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1558 var BSSAP_N_CONNECT_ind rx_c_ind;
1559 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001560 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001561
Harald Welte89d42e82017-12-17 16:42:41 +01001562 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001563
1564 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001565 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001566
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001567 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001568
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001569 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Harald Welteae026692017-12-09 01:03:01 +01001570 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1571
1572 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001573 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001574 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001575}
1576
Harald Welte618ef642017-12-14 14:58:20 +01001577/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1578testcase TC_chan_act_nack() runs on test_CT {
1579 var RSL_Message rx_rsl;
1580 var integer chact_nack;
1581
Harald Welte89d42e82017-12-17 16:42:41 +01001582 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001583
1584 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1585
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001586 f_ipa_tx(ts_RSL_CHAN_RQD('33'O, 33));
1587 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte618ef642017-12-14 14:58:20 +01001588 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1589
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001590 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte618ef642017-12-14 14:58:20 +01001591
1592 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1593 f_sleep(0.5);
1594
1595 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1596
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001597 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001598}
1599
Harald Welte799c97b2017-12-14 17:50:30 +01001600/* Test for channel exhaustion due to RACH overload */
1601testcase TC_chan_exhaustion() runs on test_CT {
1602 var ASP_RSL_Unitdata rsl_ud;
1603 var integer i;
1604 var integer chreq_total, chreq_nochan;
1605
Harald Welte89d42e82017-12-17 16:42:41 +01001606 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001607
1608 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1609 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1610
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001611 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001612 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1613 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001614 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 +01001615 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001616 }
1617
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001618 IPA_RSL[0][0].clear;
Harald Welte799c97b2017-12-14 17:50:30 +01001619
Harald Weltedd8cbf32018-01-28 12:07:52 +01001620 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001621 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001622
1623 /* now expect additional channel activations to fail */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001624 f_ipa_tx(ts_RSL_CHAN_RQD('42'O, 42));
Harald Welte799c97b2017-12-14 17:50:30 +01001625
1626 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001627 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001628 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1629 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001630 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001631 var GsmRrMessage rr;
1632 /* match on IMM ASS REJ */
1633 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1634 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1635 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001636 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001637 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1638 chreq_nochan+1);
1639 setverdict(pass);
1640 } else {
1641 repeat;
1642 }
1643 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001644 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte799c97b2017-12-14 17:50:30 +01001645 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001646 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001647}
1648
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001649/* Test channel deactivation due to silence from MS */
1650testcase TC_chan_deact_silence() runs on test_CT {
1651 var RslChannelNr chan_nr;
1652
1653 f_init(1);
1654
1655 /* Request for a dedicated channel */
1656 chan_nr := f_chreq_act_ack('23'O);
1657
1658 /* Wait some time until the channel is released */
1659 f_sleep(2.0);
1660
1661 /* Expect CHANnel RELease */
1662 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001663 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001664 log("Received CHANnel RELease");
1665 setverdict(pass);
1666 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001667 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001668 /* See OS#3709, OsmoBSC should not send Immediate
1669 * Assignment Reject since a dedicated channel was
1670 * already allocated, and Immediate Assignment was
1671 * already sent. */
1672 setverdict(fail, "Unexpected Immediate Assignment!");
1673 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001674 [] IPA_RSL[0][0].receive {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001675 setverdict(fail, "Unexpected RSL message!");
1676 }
1677 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001678 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001679}
1680
Harald Weltecfe2c962017-12-15 12:09:32 +01001681/***********************************************************************
1682 * Assignment Testing
1683 ***********************************************************************/
1684
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001685/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1686 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001687testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001688 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001689
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001690 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1691 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001692 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001693 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001694}
1695
Harald Welte16a4adf2017-12-14 18:54:01 +01001696/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001697testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001698 var BSSAP_N_CONNECT_ind rx_c_ind;
1699 var RSL_Message rx_rsl;
1700 var DchanTuple dt;
1701
Harald Welte89d42e82017-12-17 16:42:41 +01001702 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001703
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001704 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001705 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001706 /* send assignment without AoIP IEs */
1707 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1708 } else {
Pau Espin Pedrol35609792023-01-03 16:56:59 +01001709 /* Send assignment without CIC in IPA case */
Harald Welte17b27da2018-05-25 20:33:53 +02001710 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1711 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1712 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1713 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001714 alt {
1715 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1716 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1717 }
Harald Welte235ebf12017-12-15 14:18:16 +01001718 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001719 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1720 setverdict(pass);
1721 }
1722 [] BSSAP.receive { repeat; }
1723 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001724 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001725 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001726}
1727
Harald Welteed848512018-05-24 22:27:58 +02001728/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001729function 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 +02001730 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001731 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001732 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001733 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001734 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001735 if (osmux_enabled) {
1736 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1737 } else {
1738 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1739 }
Harald Welteed848512018-05-24 22:27:58 +02001740 } else {
1741 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001742 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001743 }
1744 return ass_cmd;
1745}
1746
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001747function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001748 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001749 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1750 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001751 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001752
1753 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1754 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001755 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1756 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001757 if (ispresent(enc)) {
1758 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001759 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1760 if (ispresent(v_enc.enc_alg_chosen)) {
1761 chosenEncryptionAlgorithm := valueof(
1762 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1763 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1764 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001765 if (ispresent(v_enc.enc_kc128)) {
1766 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1767 }
1768 }
1769
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001770 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001771 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001772 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001773 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1774 cell_id_source := cell_id_source,
1775 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001776 encryptionInformation := encryptionInformation,
1777 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001778 kC128 := kc128,
1779 /* on AoIP, allow "all" codecs (until we add more concise
1780 * tests) */
1781 codecList := ts_BSSMAP_IE_CodecList(
1782 {ts_CodecAMR_F, ts_CodecAMR_H,
1783 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001784 } else {
1785 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001786 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1787 cell_id_source := cell_id_source,
1788 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001789 encryptionInformation := encryptionInformation,
1790 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1791 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001792 }
1793 return ho_req;
1794}
1795
Harald Welteed848512018-05-24 22:27:58 +02001796/* generate an assignment complete template for either AoIP or SCCPlite */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001797function f_gen_exp_compl(integer bssap_idx := 0)
1798runs on MSC_ConnHdlr return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001799 var template PDU_BSSAP exp_compl;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001800 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001801 var template BSSMAP_IE_Osmo_OsmuxCID exp_osmux_cid := omit;
1802 if (g_pars.use_osmux_cn) {
1803 var template (present) INT1 exp_cid := ?;
1804 if (isbound(g_media.mgcp_conn[0].local_osmux_cid) and isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1805 exp_cid := (g_media.mgcp_conn[0].local_osmux_cid, g_media.mgcp_conn[1].local_osmux_cid);
1806 } else if (isbound(g_media.mgcp_conn[0].local_osmux_cid)) {
1807 exp_cid := g_media.mgcp_conn[0].local_osmux_cid;
1808 } else if (isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1809 exp_cid := g_media.mgcp_conn[1].local_osmux_cid;
1810 }
1811 exp_osmux_cid := tr_OsmuxCID(exp_cid);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001812 }
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001813 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, exp_osmux_cid);
Harald Welteed848512018-05-24 22:27:58 +02001814 } else {
1815 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001816 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit, omit);
Harald Welteed848512018-05-24 22:27:58 +02001817 }
1818 return exp_compl;
1819}
1820
Harald Welte235ebf12017-12-15 14:18:16 +01001821/* Run everything required up to sending a caller-specified assignment command and expect response */
1822function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001823runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001824 var BSSAP_N_CONNECT_ind rx_c_ind;
1825 var RSL_Message rx_rsl;
1826 var DchanTuple dt;
1827
Harald Welte89d42e82017-12-17 16:42:41 +01001828 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001829
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001830 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte235ebf12017-12-15 14:18:16 +01001831 /* send assignment without AoIP IEs */
1832 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1833 alt {
1834 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1835 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1836 setverdict(pass);
1837 } else {
1838 setverdict(fail, fail_text);
1839 }
1840 }
1841 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1842 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1843 setverdict(pass);
1844 } else {
1845 setverdict(fail, fail_text);
1846 }
1847 }
1848 [] BSSAP.receive { repeat; }
1849 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001850 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001851}
Oliver Smithdd002752023-02-21 13:35:00 +01001852
Oliver Smith545492d2023-04-19 13:05:30 +02001853private function f_tc_assignment_csd(charstring data_rate_str, OCT1 data_rate, boolean transp := true) runs on MSC_ConnHdlr {
Oliver Smithdd002752023-02-21 13:35:00 +01001854 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Harald Welteed848512018-05-24 22:27:58 +02001855 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Oliver Smithbc392a82023-04-17 14:06:42 +02001856 var SDP_FIELD_PayloadType pt_csd := PT_CSD;
Oliver Smithdd002752023-02-21 13:35:00 +01001857
Harald Welte235ebf12017-12-15 14:18:16 +01001858 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
Oliver Smithdd002752023-02-21 13:35:00 +01001859 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecCSData}));
1860
Oliver Smith545492d2023-04-19 13:05:30 +02001861 /* Non-transparent service (3GPP TS 48.008 § 3.2.2.11, oct 5, bit 7) */
1862 if (not transp) {
1863 data_rate := data_rate or4b '40'O;
1864 }
1865
Oliver Smithcb617912023-04-18 11:29:10 +02001866 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := data_rate;
1867
1868 log("-----------------------------------------------");
1869 log("Assignment req with data rate: " & data_rate_str);
1870 log("-----------------------------------------------");
Oliver Smithdd002752023-02-21 13:35:00 +01001871
1872 f_establish_fully(ass_cmd, exp_compl);
Oliver Smithbc392a82023-04-17 14:06:42 +02001873
1874 if (g_media.bts.rtp_pt != enum2int(pt_csd)) {
1875 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("unexpected RTP payload type: ", g_media.bts.rtp_pt));
1876 }
1877
Oliver Smithdd002752023-02-21 13:35:00 +01001878 f_perform_clear();
Oliver Smithace447a2023-05-08 14:07:21 +02001879 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Oliver Smithdd002752023-02-21 13:35:00 +01001880}
Oliver Smithcb617912023-04-18 11:29:10 +02001881private function f_tc_assignment_csd_all(charstring id) runs on MSC_ConnHdlr {
1882 /* Data rates that require multi-slot HSCSD assignment are not tested
Oliver Smith545492d2023-04-19 13:05:30 +02001883 * on purpose (not supported): T_32k0, T_28k8, NT_43k5, NT_29k0 */
Oliver Smithcb617912023-04-18 11:29:10 +02001884 f_tc_assignment_csd("T_14k4", GSM0808_DATA_RATE_TRANSP_14k4);
1885 f_tc_assignment_csd("T_9k6", GSM0808_DATA_RATE_TRANSP_9k6);
1886 f_tc_assignment_csd("T_4k8", GSM0808_DATA_RATE_TRANSP_4k8);
1887 f_tc_assignment_csd("T_2k4", GSM0808_DATA_RATE_TRANSP_2k4);
1888 f_tc_assignment_csd("T_1k2", GSM0808_DATA_RATE_TRANSP_1k2);
1889 f_tc_assignment_csd("T_600", GSM0808_DATA_RATE_TRANSP_600);
1890 f_tc_assignment_csd("T_1200_75", GSM0808_DATA_RATE_TRANSP_1200_75);
Oliver Smith545492d2023-04-19 13:05:30 +02001891
1892 f_tc_assignment_csd("NT_12000_6000", GSM0808_DATA_RATE_NON_TRANSP_12000_6000, false);
1893 f_tc_assignment_csd("NT_14k5", GSM0808_DATA_RATE_NON_TRANSP_14k5, false);
1894 f_tc_assignment_csd("NT_12k0", GSM0808_DATA_RATE_NON_TRANSP_12k0, false);
1895 f_tc_assignment_csd("NT_6k0", GSM0808_DATA_RATE_NON_TRANSP_6k0, false);
Oliver Smithcb617912023-04-18 11:29:10 +02001896}
Oliver Smithdd002752023-02-21 13:35:00 +01001897testcase TC_assignment_csd() runs on test_CT {
Vadim Yanitskiy02c086f2023-09-22 15:32:41 +07001898 var MSC_ConnHdlr vc_conn;
1899 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Oliver Smithdd002752023-02-21 13:35:00 +01001900
Vadim Yanitskiy02c086f2023-09-22 15:32:41 +07001901 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
1902
1903 f_init(1, true, guard_timeout := 120.0);
1904 f_sleep(1.0);
1905 vc_conn := f_start_handler(refers(f_tc_assignment_csd_all), pars);
1906 vc_conn.done;
1907
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001908 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001909}
1910
1911testcase TC_assignment_ctm() runs on test_CT {
1912 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001913 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001914 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1915 //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 +01001916 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1917 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001918 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001919}
1920
Harald Welte4003d112017-12-09 22:35:39 +01001921type record DchanTuple {
1922 integer sccp_conn_id,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001923 RslChannelNr rsl_chan_nr,
1924 BtsTrxIdx idx
Harald Weltea5d2ab22017-12-09 14:21:42 +01001925}
1926
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001927type record of DchanTuple DchanTuples;
1928
Harald Welted6939652017-12-13 21:02:46 +01001929/* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001930private function f_chreq_act_ack(OCT1 ra := '23'O,
1931 GsmFrameNumber fn := 23,
1932 BtsTrxIdx idx := {0, 0})
Harald Welted6939652017-12-13 21:02:46 +01001933runs on test_CT return RslChannelNr {
1934 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001935 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
1936 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Harald Welted6939652017-12-13 21:02:46 +01001937 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001938 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10), idx);
1939 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Harald Welted6939652017-12-13 21:02:46 +01001940 return chan_nr;
1941}
1942
Harald Welte4003d112017-12-09 22:35:39 +01001943/* helper function to establish a dedicated channel via BTS and MSC */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001944function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1945 BtsTrxIdx idx := {0, 0})
Harald Welte4003d112017-12-09 22:35:39 +01001946runs on test_CT return DchanTuple {
1947 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001948 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001949
Harald Welte4003d112017-12-09 22:35:39 +01001950 /* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001951 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn, idx);
Harald Welte4003d112017-12-09 22:35:39 +01001952
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001953 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 +01001954
1955 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1956 dt.sccp_conn_id := rx_c_ind.connectionId;
1957 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1958
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001959 dt.idx := idx;
Harald Welte4003d112017-12-09 22:35:39 +01001960 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001961}
1962
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001963/* 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 +06001964function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1965 BtsTrxIdx idx := {0, 0})
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001966runs on test_CT return DchanTuple {
1967 var BSSAP_N_CONNECT_ind rx_c_ind;
1968 var DchanTuple dt;
1969
1970 /* Send CHAN RQD */
1971 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001972 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001973
1974 /* The dyn TS first deactivates PDCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001975 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 +02001976 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001977 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001978
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001979 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001980 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1981
1982 /* Now activates the signalling channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001983 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10), idx);
1984 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001985
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001986 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 +02001987
1988 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1989 dt.sccp_conn_id := rx_c_ind.connectionId;
1990 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1991
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001992 dt.idx := idx;
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001993 return dt;
1994}
1995
Harald Welte641fcbe2018-06-14 10:58:35 +02001996/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001997private function f_exp_chan_rel_and_clear(DchanTuple dt)
1998runs on test_CT {
Harald Welte641fcbe2018-06-14 10:58:35 +02001999 var RSL_Message rx_rsl;
2000 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002001 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 +02002002 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002003 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), dt.idx);
Harald Welte641fcbe2018-06-14 10:58:35 +02002004
2005 /* expect Clear Complete from BSC */
2006 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2007
2008 /* MSC disconnects as instructed. */
2009 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2010}
2011
Harald Welte4003d112017-12-09 22:35:39 +01002012/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
2013testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01002014 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002015 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01002016
Harald Welte89d42e82017-12-17 16:42:41 +01002017 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01002018
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002019 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01002020
2021 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002022 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Harald Welte4003d112017-12-09 22:35:39 +01002023
Neels Hofmeyr27f64362018-03-12 01:44:00 +01002024 /* expect Clear Request on MSC side */
2025 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
2026
2027 /* Instruct BSC to clear channel */
2028 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
2029 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2030
Harald Welte4003d112017-12-09 22:35:39 +01002031 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002032 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01002033
2034 /* wait for SCCP emulation to do its job */
2035 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01002036
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002037 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002038}
2039
2040/* Test behavior of channel release after CONN FAIL IND from BTS */
2041testcase TC_chan_rel_conn_fail() runs on test_CT {
2042 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002043 var DchanTuple dt;
2044
Harald Welte89d42e82017-12-17 16:42:41 +01002045 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002046
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002047 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01002048
Vadim Yanitskiy01d0a902022-12-14 22:41:42 +07002049 /* Sending CONN FAIL IND immediately may trigger a race condition.
2050 * Give the BSC some time to process a new SCCP connection (OS#5823). */
2051 f_sleep(0.2);
2052
Harald Welte4003d112017-12-09 22:35:39 +01002053 /* simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002054 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01002055 /* TODO: different cause values? */
2056
Harald Welte4003d112017-12-09 22:35:39 +01002057 /* expect Clear Request from BSC */
2058 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
2059
2060 /* Instruct BSC to clear channel */
2061 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
2062 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2063
Harald Welte6ff76ea2018-01-28 13:08:01 +01002064 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002065 f_exp_chan_rel_and_clear(dt);
Harald Welte4003d112017-12-09 22:35:39 +01002066
2067 /* wait for SCCP emulation to do its job */
2068 f_sleep(1.0);
2069
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002070 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002071}
2072
Harald Welte99f3ca02018-06-14 13:40:29 +02002073/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
2074/* See also https://www.osmocom.org/issues/3182 */
2075testcase TC_early_conn_fail() runs on test_CT {
2076 var RSL_Message rx_rsl;
2077 var DchanTuple dt;
2078
2079 f_init(1);
2080
2081 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02002082 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02002083
2084 /* BTS->BSC: simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002085 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002086
2087 /* BTS->BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002088 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002089
2090 /* BTS<-BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002091 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002092
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002093 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002094}
2095
2096/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
2097/* See also https://www.osmocom.org/issues/3182 */
2098testcase TC_late_conn_fail() runs on test_CT {
2099 var RSL_Message rx_rsl;
2100 var DchanTuple dt;
2101
2102 f_init(1);
2103
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002104 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99f3ca02018-06-14 13:40:29 +02002105
2106 /* BSC<-MSC: Instruct BSC to clear connection */
2107 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
2108
2109 /* BTS->BSC: expect BSC to deactivate SACCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002110 rx_rsl := f_exp_ipa_rx(tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002111
2112 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002113 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002114
2115 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002116 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002117 /* BTS->BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002118 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002119
2120 /* BSC->MSC: expect Clear Complete from BSC */
2121 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2122
2123 /* BSC<-MSC: MSC disconnects as requested. */
2124 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2125
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002126 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002127}
2128
Oliver Smithaf03bef2021-08-24 15:34:51 +02002129private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
2130 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
2131 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2132
2133 f_statsd_reset();
2134
Oliver Smith15890b42023-03-08 14:12:28 +01002135 /* Establish SDCCH (invalid DataIndicator for exp_fail) */
Oliver Smithaf03bef2021-08-24 15:34:51 +02002136 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
Oliver Smith15890b42023-03-08 14:12:28 +01002137 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := 'ff'O;
Oliver Smithaf03bef2021-08-24 15:34:51 +02002138 f_establish_fully(ass_cmd, exp_fail);
2139
2140 /* Expect stats to be 0 */
2141 var StatsDExpects expect := {
2142 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
2143 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
2144 };
2145 f_statsd_expect(expect);
2146
2147 /* Simulate CONN FAIL IND on SDCCH */
2148 RSL.send(ts_ASP_RSL_UD(
2149 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2150 IPAC_PROTO_RSL_TRX0));
2151
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002152 f_sleep(1.0);
2153
Oliver Smithaf03bef2021-08-24 15:34:51 +02002154 /* Expect stats to be 1 */
2155 expect := {
2156 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2157 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2158 };
2159 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002160 BSSAP.receive(tr_BSSMAP_ClearRequest);
2161 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002162}
2163testcase TC_stats_conn_fail() runs on test_CT {
2164 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2165 var MSC_ConnHdlr vc_conn;
2166
2167 f_init(1, true);
2168 f_sleep(1.0);
2169
2170 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2171 vc_conn.done;
2172
2173 f_shutdown_helper();
2174}
2175
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002176function f_expect_chan_rel(RslChannelNr rsl_chan_nr,
2177 BtsTrxIdx idx := {0, 0},
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002178 boolean expect_deact_sacch := true,
2179 boolean expect_rr_chan_rel := true,
2180 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002181 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002182 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002183 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002184 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002185
2186 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002187 var boolean got_deact_sacch := false;
2188 var boolean got_rr_chan_rel := false;
2189 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002190 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002191 var RSL_IE_Body l3_ie;
2192 var PDU_ML3_NW_MS l3;
2193 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002194 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2195 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002196 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002197 [] 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 +01002198 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002199 repeat;
2200 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002201 [] 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 +01002202 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002203
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002204 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2205 setverdict(fail, "cannot find L3");
2206 mtc.stop;
2207 }
2208 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2209
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002210 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002211 var CellSelIndValue cells := dec_CellSelIndValue(
2212 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2213
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002214 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2215 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002216 setverdict(pass);
2217 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002218 log("EXPECTED CELLS: ", expect_cells);
2219 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002220 }
2221 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002222
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002223 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2224 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2225 if (match(got_cause, expect_rr_cause)) {
2226 setverdict(pass);
2227 } else {
2228 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2229 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002230 }
Harald Welte99787102019-02-04 10:41:36 +01002231 repeat;
2232 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002233 [] 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 +01002234 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002235 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002236 if (handle_rll_rel) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002237 f_ipa_tx(ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002238 }
Harald Welte91d54a52018-01-28 15:35:07 +01002239 repeat;
2240 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002241 [] 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 +01002242 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002243 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
Harald Welte91d54a52018-01-28 15:35:07 +01002244 }
2245 /* ignore any user data */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002246 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002247 repeat;
2248 }
2249 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002250
2251 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2252 " got_rll_rel_req=", got_rll_rel_req);
2253
2254 if (expect_deact_sacch != got_deact_sacch) {
2255 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2256 }
2257 if (expect_rr_chan_rel != got_rr_chan_rel) {
2258 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2259 }
2260 if (expect_rll_rel_req != got_rll_rel_req) {
2261 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2262 }
Harald Welte91d54a52018-01-28 15:35:07 +01002263}
2264
Harald Welte4003d112017-12-09 22:35:39 +01002265/* Test behavior of channel release after hard Clear Command from MSC */
2266testcase TC_chan_rel_hard_clear() runs on test_CT {
2267 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002268 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002269
Harald Welte89d42e82017-12-17 16:42:41 +01002270 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002271
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002272 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01002273
2274 /* Instruct BSC to clear channel */
2275 var BssmapCause cause := 0;
2276 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2277
2278 /* expect Clear Complete from BSC on A */
2279 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2280 /* release the SCCP connection */
2281 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2282 }
2283
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002284 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002285 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002286}
2287
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002288function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2289 var BSSAP_N_DATA_ind rx_di;
2290 var DchanTuple dt;
2291
2292 f_init(1);
2293
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002294 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002295 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2296 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2297 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2298
2299 /* Instruct BSC to clear channel */
2300 var BssmapCause cause := 0;
2301 if (tx_csfb_ind) {
2302 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2303 } else {
2304 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2305 }
2306
2307 /* expect Clear Complete from BSC on A */
2308 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2309 /* release the SCCP connection */
2310 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2311 }
2312
2313 /* 1 neighbor is added by default in osmo-bts.cfg and
2314 SystemInformationConfig_default, use that: */
2315 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2316
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002317 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 +02002318 f_shutdown_helper();
2319}
2320
2321/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2322 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2323 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2324 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2325 Indicator or not shouldn't matter at all. */
2326testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2327 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2328}
2329
2330/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2331 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2332 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2333 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2334testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2335 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2336}
2337
2338/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2339 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2340 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2341 CSFB Indicator should not be used anymore, and hence, there should be no
2342 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2343 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002344testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2345 var BSSAP_N_DATA_ind rx_di;
2346 var DchanTuple dt;
2347
2348 f_init(1);
2349
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002350 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99787102019-02-04 10:41:36 +01002351
2352 /* Instruct BSC to clear channel */
2353 var BssmapCause cause := 0;
2354 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2355
2356 /* expect Clear Complete from BSC on A */
2357 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2358 /* release the SCCP connection */
2359 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2360 }
2361
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002362 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002363 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002364}
2365
Harald Welted8c36cd2017-12-09 23:05:31 +01002366/* Test behavior of channel release after hard RLSD from MSC */
2367testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002368 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002369
Harald Welte89d42e82017-12-17 16:42:41 +01002370 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002371
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002372 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welted8c36cd2017-12-09 23:05:31 +01002373
2374 /* release the SCCP connection */
2375 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2376
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002377 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002378 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002379}
2380
Harald Welte550daf92018-06-11 19:22:13 +02002381/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2382testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2383 var DchanTuple dt;
2384
2385 f_init(1);
2386
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002387 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte550daf92018-06-11 19:22:13 +02002388
2389 /* release the SCCP connection */
2390 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2391
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002392 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002393 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002394}
2395
Harald Welte85804d42017-12-10 14:11:58 +01002396/* Test behavior of channel release after BSSMAP RESET from MSC */
2397testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002398 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002399
Harald Welte89d42e82017-12-17 16:42:41 +01002400 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002401
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002402 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte85804d42017-12-10 14:11:58 +01002403
2404 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002405 IPA_RSL[0][0].clear;
Harald Welte85804d42017-12-10 14:11:58 +01002406
2407 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002408 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 +01002409 interleave {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002410 [] 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 +01002411 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2412 }
2413
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002414 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002415 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002416}
2417
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002418/* Verify T(iar) triggers and releases the channel */
2419testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2420 var DchanTuple dt;
2421
2422 /* Set T(iar) in BSC low enough that it will trigger before other side
2423 has time to keep alive with a T(ias). Keep recommended ratio of
2424 T(iar) >= T(ias)*2 */
2425 g_bsc_sccp_timer_ias := 2;
2426 g_bsc_sccp_timer_iar := 5;
2427
2428 f_init(1);
2429
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002430 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002431 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002432 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002433}
2434
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002435private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2436 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002437runs on test_CT
2438{
2439 var DchanTuple dt;
2440
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002441 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002442 var BssmapCause cause := 0;
2443 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2444 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2445 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2446 }
2447
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002448 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 +02002449}
2450
2451/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2452testcase TC_chan_rel_rr_cause() runs on test_CT {
2453 f_init(1);
2454
2455 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2456 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2457 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2458 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2459 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2460 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002461
2462 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002463}
2464
Harald Welte5cd20ed2017-12-13 21:03:20 +01002465/* Test behavior if RSL EST IND for non-active channel */
2466testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2467 timer T := 2.0;
2468
Harald Welte89d42e82017-12-17 16:42:41 +01002469 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002470
Harald Welte5cd20ed2017-12-13 21:03:20 +01002471 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002472 var octetstring l3_payload := gen_l3_valid_payload();
2473 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002474
2475 T.start;
2476 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002477 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002478 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2479 }
2480 [] BSSAP.receive {}
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002481 [] IPA_RSL[0][0].receive {}
Harald Welte5cd20ed2017-12-13 21:03:20 +01002482 [] T.timeout {}
2483 }
2484
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002485 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002486}
2487
2488/* Test behavior if RSL EST IND for invalid SAPI */
2489testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2490 var RslChannelNr chan_nr;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002491 var octetstring l3_payload;
Harald Welte5cd20ed2017-12-13 21:03:20 +01002492
Harald Welte89d42e82017-12-17 16:42:41 +01002493 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002494
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002495 chan_nr := f_chreq_act_ack();
2496 l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002497
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002498 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002499
2500 timer T := 2.0;
2501 T.start;
2502 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002503 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002504 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2505 }
2506 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002507 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002508 [] T.timeout {}
2509 }
2510
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002511 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002512}
2513
2514/* Test behavior if RSL EST IND for invalid SAPI */
2515testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2516 timer T := 2.0;
2517
Harald Welte89d42e82017-12-17 16:42:41 +01002518 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002519
2520 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002521 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002522
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002523 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002524
2525 T.start;
2526 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002527 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002528 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2529 }
2530 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002531 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002532 [] T.timeout {}
2533 }
2534
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002535 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002536}
2537
2538/* Test behavior if RSL EST IND for invalid SACCH */
2539testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2540 timer T := 2.0;
2541
Harald Welte89d42e82017-12-17 16:42:41 +01002542 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002543
2544 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002545 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002546
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002547 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002548
2549 T.start;
2550 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002551 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002552 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2553 }
2554 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002555 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002556 [] T.timeout {}
2557 }
2558
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002559 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002560}
2561
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002562/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2563private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2564 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2565 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2566
2567 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2568 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2569
2570 f_establish_fully(ass_cmd, exp_compl);
2571
2572 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2573 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2574 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2575 BSSAP.receive(PDU_BSSAP:{
2576 discriminator := '1'B,
2577 spare := '0000000'B,
2578 dlci := 'C3'O,
2579 lengthIndicator := ?,
2580 pdu := { dtap := '0904'O }
2581 });
2582
2583 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2584 for (var integer i := 0; i < 32; i := i + 1) {
2585 var octetstring l3 := '09'O & f_rnd_octstring(14);
2586 var template (value) RslLinkId link_id;
2587 var template (value) OCT1 dlci;
2588
2589 if (i mod 2 == 0) {
2590 /* SAPI0 on FACCH or SDCCH */
2591 link_id := ts_RslLinkID_DCCH(0);
2592 dlci := '80'O;
2593 } else {
2594 /* SAPI3 on SACCH */
2595 link_id := ts_RslLinkID_SACCH(3);
2596 dlci := 'C3'O;
2597 }
2598
2599 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002600 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002601 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002602 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002603 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002604 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002605}
2606testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2607 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2608 var MSC_ConnHdlr vc_conn;
2609
2610 f_init(1, true);
2611 f_sleep(1.0);
2612
2613 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2614 vc_conn.done;
2615
2616 f_shutdown_helper();
2617}
2618
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002619private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002620 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002621 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002622 float T_val := 2.0)
2623runs on test_CT {
2624 var BSSAP_N_DATA_ind rx_di;
2625 timer T;
2626
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002627 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2628 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002629
2630 T.start(T_val);
2631 alt {
2632 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2633 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2634 if (not match(rx_cause, tr_cause)) {
2635 setverdict(fail, "Rx unexpected Cause IE: ",
2636 rx_cause, " vs expected ", tr_cause);
2637 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002638
2639 /* Who ever on the earth decided to define this field as two separate bits?!? */
2640 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2641 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2642 if (not match(rx_cc, cc)) {
2643 setverdict(fail, "Rx unexpected Control Channel type: ",
2644 rx_cc, " vs expected ", cc);
2645 }
2646
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002647 setverdict(pass);
2648 }
2649 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2650 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2651 }
2652 [] T.timeout {
2653 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2654 }
2655 }
2656}
2657
2658/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2659testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002660 var RSL_Message rx_rsl;
2661 var DchanTuple dt;
2662
2663 f_init(1);
2664
2665 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002666 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002667
2668 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002669 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 +07002670 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002671 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 +07002672
2673 /* MS sends unexpected RELease INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002674 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002675 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2676 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2677
2678 /* Clean up the connection */
2679 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002680 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002681
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002682 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002683}
2684
2685/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2686testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002687 var RSL_Message rx_rsl;
2688 var DchanTuple dt;
2689
2690 f_init(1);
2691
2692 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002693 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002694
2695 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002696 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 +07002697 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002698 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 +07002699
2700 /* BTS sends unexpected ERROR INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002701 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002702 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2703 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2704
2705 /* Clean up the connection */
2706 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002707 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002708
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002709 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002710}
2711
2712/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2713testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002714 var RSL_Message rx_rsl;
2715 var DchanTuple dt;
2716
2717 f_init(1);
2718
2719 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002720 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002721
2722 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002723 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 +07002724 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002725 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 +07002726
2727 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2728 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2729
2730 /* Clean up the connection */
2731 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002732 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002733
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002734 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002735}
2736
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002737/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2738testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002739 var RSL_Message rx_rsl;
2740 var DchanTuple dt;
2741
2742 f_init(1);
2743
2744 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002745 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002746
2747 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002748 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 +07002749 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002750 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 +07002751
2752 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002753 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002754 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002755
2756 /* Clean up the connection */
2757 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002758 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002759
2760 f_shutdown_helper();
2761}
2762
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002763testcase TC_si_default() runs on test_CT {
2764 f_init(0);
2765 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002766 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002767}
Harald Welte4003d112017-12-09 22:35:39 +01002768
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002769/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2770 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2771private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2772{
2773 select (earfcn_index) {
2774 case (0) {
2775 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2776 return 111;
2777 }
2778 case (1) {
2779 return 1;
2780 }
2781 case (2) {
2782 return 0;
2783 }
2784 case (3) {
2785 return 65535;
2786 }
2787 case else {
2788 return 23 * (earfcn_index - 3);
2789 }
2790 }
2791}
2792
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002793function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2794 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002795
2796 f_init(0);
2797
2798 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2799 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002800 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2801 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002802 }
2803
2804 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2805
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002806 if (not istemplatekind(expect_cells, "omit")) {
2807 /* Also check that RR Channel Release contains these EARFCNs.
2808 * (copied code from TC_chan_rel_hard_clear_csfb) */
2809 var BSSAP_N_DATA_ind rx_di;
2810 var DchanTuple dt;
2811
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002812 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002813 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2814 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2815 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002816
2817 /* Instruct BSC to clear channel */
2818 var BssmapCause cause := 0;
2819 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2820
2821 /* expect Clear Complete from BSC on A */
2822 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2823 /* release the SCCP connection */
2824 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2825 }
2826
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002827 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002828 }
2829
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002830 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002831 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 +02002832 }
2833}
2834
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002835private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2836{
2837 var template SI2quaterRestOctetsList si2quater := {};
2838 var integer si2quater_count := (count + 2) / 3;
2839
2840 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002841 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002842 var integer index := i / 3;
2843 var integer earfcn_index := i mod 3;
2844 if (index >= lengthof(si2quater)) {
2845 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2846 }
2847 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);
2848 }
2849
2850 return si2quater;
2851}
2852
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002853private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2854{
2855 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2856
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002857 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002858 for (var integer i := 0; i < count; i := i + 1) {
2859 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002860 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002861 }
2862
2863 return tr_CellSelIndValue_EUTRAN(cells);
2864}
2865
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002866private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2867{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002868 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002869 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002870 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2871 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002872}
2873
2874testcase TC_si2quater_2_earfcns() runs on test_CT {
2875 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002876 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002877}
2878
2879testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002880 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002881 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002882}
2883
2884testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002885 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002886 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002887}
2888
2889testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002890 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002891 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002892}
2893
2894testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002895 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002896 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002897}
2898
2899testcase TC_si2quater_12_earfcns() runs on test_CT {
2900 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002901 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002902}
2903
2904testcase TC_si2quater_23_earfcns() runs on test_CT {
2905 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002906 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002907}
2908
2909testcase TC_si2quater_32_earfcns() runs on test_CT {
2910 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002911 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002912}
2913
2914testcase TC_si2quater_33_earfcns() runs on test_CT {
2915 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002916 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002917}
2918
2919testcase TC_si2quater_42_earfcns() runs on test_CT {
2920 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002921 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002922}
2923
2924testcase TC_si2quater_48_earfcns() runs on test_CT {
2925 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002926 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002927}
2928
2929/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2930 * 48 EARFCNs. */
2931testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002932 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002933 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2934 f_init(0);
2935
2936 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002937 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2938 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002939 }
2940
2941 /* The 49th EARFCN no longer fits, expect VTY error */
2942 f_vty_enter_cfg_bts(BSCVTY, 0);
2943 var charstring vty_error;
2944 vty_error := f_vty_transceive_ret(BSCVTY,
2945 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2946 f_vty_transceive(BSCVTY, "end");
2947
2948 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2949 log("Got expected VTY error: ", vty_error);
2950 setverdict(pass);
2951 } else {
2952 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2953 }
2954
2955 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2956
2957 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002958 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 +02002959 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002960 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002961}
2962
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002963private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2964{
2965 var uint8_t count := 0;
2966 for (var integer i := 5; i < 16; i := i + 1) {
2967 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2968 count := count + 1;
2969 }
2970 }
2971 return count;
2972}
2973
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002974private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2975{
2976 var ASP_RSL_Unitdata rx_rsl_ud;
2977 var SystemInformationType1 last_si1;
2978
2979 timer T := 30.0;
2980 T.start;
2981 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002982 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2983 tr_RSL_BCCH_INFO,
2984 tr_RSL_NO_SACCH_FILL,
2985 tr_RSL_SACCH_FILL))) -> value rx_rsl_ud {
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002986 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2987 if (g_system_information[rsl_idx].si1 == omit) {
2988 repeat;
2989 }
2990 last_si1 := g_system_information[rsl_idx].si1;
2991 g_system_information[rsl_idx].si1 := omit;
2992 T.stop;
2993 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002994 [] IPA_RSL[rsl_idx][0].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002995 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2996 }
2997 return last_si1;
2998}
2999
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02003000/* verify ACC rotate feature */
3001testcase TC_si_acc_rotate() runs on test_CT {
3002 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003003 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02003004 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02003005 var uint8_t count;
3006 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3007
3008 f_init(0, guard_timeout := 60.0);
3009
3010 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
3011 "access-control-class-rotate 3",
3012 "access-control-class-rotate-quantum 1"});
3013
3014 /* Init and get first sysinfo */
3015 f_init_bts_and_check_sysinfo(0, expect_si := ?);
3016
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003017 for (var integer i:= 0; i < 20; i := i + 1) {
3018 last_si1 := f_recv_next_si1(0);
3019 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02003020 count := f_acc09_count_allowed(acc);
3021 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
3022
3023 if (count != 3) {
3024 log("RSL: EXPECTED SI ACC len=3");
3025 setverdict(fail, "received SI does not match expectations");
3026 break;
3027 }
3028
3029 for (var integer j := 0; j < 10; j := j + 1) {
3030 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
3031 times_allowed[j] := times_allowed[j] + 1;
3032 }
3033 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02003034 }
3035
3036 for (var integer j := 0; j < 10; j := j + 1) {
3037 log("ACC", j, " allowed ", times_allowed[j], " times" );
3038 if (j != 5 and times_allowed[j] < 3) {
3039 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
3040 } else if (j == 5 and times_allowed[j] > 0) {
3041 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
3042 }
3043 }
3044
3045 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
3046 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003047 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02003048}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02003049
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003050/* verify ACC startup ramp+rotate feature */
3051testcase TC_si_acc_ramp_rotate() runs on test_CT {
3052 var template SystemInformationConfig sic := SystemInformationConfig_default;
3053 var SystemInformationType1 last_si1;
3054 var AccessControlClass acc;
3055 var ASP_RSL_Unitdata rx_rsl_ud;
3056 var uint8_t count;
3057 var uint8_t prev_count;
3058 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3059
3060 f_init(0, guard_timeout := 80.0);
3061
3062 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
3063 "access-control-class-rotate 0",
3064 "access-control-class-rotate-quantum 1",
3065 "access-control-class-ramping",
3066 "access-control-class-ramping-step-interval 5",
3067 "access-control-class-ramping-step-size 5"});
3068
3069 /* Init and get first sysinfo */
3070 f_init_bts_and_check_sysinfo(0, expect_si := ?);
3071 last_si1 := g_system_information[0].si1;
3072 acc := last_si1.rach_control.acc;
3073 count := f_acc09_count_allowed(acc);
3074 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
3075 while (count > 0) {
3076 last_si1 := f_recv_next_si1(0);
3077 acc := last_si1.rach_control.acc;
3078 count := f_acc09_count_allowed(acc);
3079 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
3080 }
3081
3082 /* Increase adm subset size, we should see ramping start up */
3083 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
3084 prev_count := 0;
3085 while (true) {
3086 last_si1 := f_recv_next_si1(0);
3087 acc := last_si1.rach_control.acc;
3088 count := f_acc09_count_allowed(acc);
3089 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
3090
3091 if (prev_count > count) {
3092 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
3093 break;
3094 }
3095
3096 if (count == 9) {
3097 break; /* Maximum reached (10 - 1 perm barred), done here */
3098 }
3099
3100 prev_count := count;
3101 }
3102
3103 setverdict(pass);
3104
3105 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
3106 "rach access-control-class 4 allowed",
3107 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003108 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003109}
3110
Harald Welte4003d112017-12-09 22:35:39 +01003111testcase TC_ctrl_msc_connection_status() runs on test_CT {
3112 var charstring ctrl_resp;
3113
Harald Welte89d42e82017-12-17 16:42:41 +01003114 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003115
3116 /* See https://osmocom.org/issues/2729 */
3117 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003118 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01003119}
3120
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003121testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3122 var charstring ctrl_resp;
3123
3124 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003125
3126 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003127 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003128}
3129
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003130/* Verify correct stats on the number of configured and connected MSCs */
3131private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3132 g_pars := f_gen_test_hdlr_pars();
3133 var StatsDExpects expect := {
3134 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3135 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3136 };
3137 f_statsd_expect(expect);
3138}
3139
3140private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3141{
3142 var MSC_ConnHdlr vc_conn;
3143
3144 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3145 f_sleep(1.0);
3146 vc_conn := f_start_handler(tc_fn);
3147 vc_conn.done;
3148
3149 /* Also verify stat exposed on CTRL interface */
3150 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3151 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3152
3153 f_shutdown_helper();
3154}
3155
3156/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3157private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3158 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3159}
3160testcase TC_stat_num_msc_connected_1() runs on test_CT {
3161 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3162}
3163
3164/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3165private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3166 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3167}
3168testcase TC_stat_num_msc_connected_2() runs on test_CT {
3169 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3170}
3171
3172/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3173private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3174 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3175}
3176testcase TC_stat_num_msc_connected_3() runs on test_CT {
3177 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3178}
3179
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003180/* Verify correct stats on the number of configured and connected MSCs */
3181private 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 +06003182 var integer num_trx_connected := 0;
3183 var integer num_trx_total := 0;
3184
3185 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3186 var integer trx_num := c_BtsParams[i].trx_num;
3187 num_trx_total := num_trx_total + trx_num;
3188 if (i < expect_num_bts_connected) {
3189 num_trx_connected := num_trx_connected + trx_num;
3190 }
3191 }
3192
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003193 var StatsDExpects expect := {
3194 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3195 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3196 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003197 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := num_trx_connected, max := num_trx_connected },
3198 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := num_trx_total, max := num_trx_total }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003199 };
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003200
3201 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003202 f_statsd_expect(expect);
3203}
3204
3205private 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 +06003206 var integer num_trx_connected := 0;
3207 var integer num_trx_total := 0;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003208 var MSC_ConnHdlr vc_conn;
3209
3210 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3211 f_sleep(1.0);
3212 vc_conn := f_start_handler(tc_fn);
3213 vc_conn.done;
3214
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003215 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3216 var integer trx_num := c_BtsParams[i].trx_num;
3217 num_trx_total := num_trx_total + trx_num;
3218 if (i < nr_bts) {
3219 num_trx_connected := num_trx_connected + trx_num;
3220 }
3221 }
3222
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003223 /* Also verify stat exposed on CTRL interface */
3224 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3225 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 +06003226 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(num_trx_connected));
3227 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 +02003228
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003229 /* Verify rf_states exposed on CTRL interface */
3230 var charstring expect_net_rf_states := "";
3231 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003232 var charstring expect_bts_rf_states := "";
3233
3234 for (var integer j := 0; j < c_BtsParams[i].trx_num; j := j + 1) {
3235 expect_bts_rf_states := expect_bts_rf_states &
3236 int2str(i) & "," & int2str(j) & ",";
3237 if (i < NUM_BTS) {
3238 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3239 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3240 } else {
3241 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3242 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3243 }
3244 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3245 expect_bts_rf_states := expect_bts_rf_states & "on,";
3246 if (i < nr_bts) {
3247 /* For BTS where RSL is connected, the RSL state will be "up" */
3248 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3249 } else {
3250 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3251 }
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003252 }
3253
3254 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3255 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3256 }
3257 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3258
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003259 f_shutdown_helper();
3260}
3261
3262/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3263private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3264 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3265}
3266testcase TC_stat_num_bts_connected_1() runs on test_CT {
3267 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3268}
3269
3270/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3271private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3272 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3273}
3274testcase TC_stat_num_bts_connected_2() runs on test_CT {
3275 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3276}
3277
3278/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3279private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3280 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3281}
3282testcase TC_stat_num_bts_connected_3() runs on test_CT {
3283 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3284}
3285
Harald Welte4003d112017-12-09 22:35:39 +01003286testcase TC_ctrl() runs on test_CT {
3287 var charstring ctrl_resp;
3288
Harald Welte89d42e82017-12-17 16:42:41 +01003289 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003290
3291 /* all below values must match the osmo-bsc.cfg config file used */
3292
Harald Welte6a129692018-03-17 17:30:14 +01003293 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3294 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003295 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003296
3297 var integer bts_nr := 0;
3298 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3299 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3300 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3301 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3302 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3303 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3304 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3305
3306 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3307 f_sleep(2.0);
3308 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3309 setverdict(fail, "oml-uptime not incrementing as expected");
3310 }
3311 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3312
3313 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3314
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003315 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003316}
3317
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003318/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3319 "location-state" over the SCCPlite IPA conn */
3320testcase TC_ctrl_location() runs on test_CT {
3321 var MSC_ConnHdlr vc_conn;
3322 var integer bts_nr := 0;
3323
3324 f_init(1, true);
3325 f_sleep(1.0);
3326
3327 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3328 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3329 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3330
3331 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3332 f_sleep(2.0);
3333
3334 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3335 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3336 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3337
3338 /* should match the one from config */
3339 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3340
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003341 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003342}
3343
Harald Welte6f521d82017-12-11 19:52:02 +01003344
3345/***********************************************************************
3346 * Paging Testing
3347 ***********************************************************************/
3348
3349type record Cell_Identity {
3350 GsmMcc mcc,
3351 GsmMnc mnc,
3352 GsmLac lac,
3353 GsmCellId ci
3354};
Harald Welte24135bd2018-03-17 19:27:53 +01003355private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003356private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003357
Harald Welte5d1a2202017-12-13 19:51:29 +01003358type set of integer BtsIdList;
3359
3360private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3361 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3362 if (bts_id == bts_ids[j]) {
3363 return true;
3364 }
3365 }
3366 return false;
3367}
Harald Welte6f521d82017-12-11 19:52:02 +01003368
3369/* core paging test helper function; used by most paging test cases */
3370private function f_pageing_helper(hexstring imsi,
3371 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003372 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003373 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003374 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003375{
3376 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003377 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003378 var RSL_Message rx_rsl;
3379 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003380 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003381
3382 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003383
3384 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003385 for (i := 0; i < NUM_BTS; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003386 IPA_RSL[i][0].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003387 }
Harald Welte6f521d82017-12-11 19:52:02 +01003388
3389 if (isvalue(rsl_chneed)) {
3390 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3391 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3392 } else {
3393 bssmap_chneed := omit;
3394 }
3395
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003396 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3397 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003398
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003399 if (not istemplatekind(tmsi, "omit")) {
3400 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003401 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003402 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003403 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003404
Harald Welte5d1a2202017-12-13 19:51:29 +01003405 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003406 rx_rsl := f_exp_ipa_rx(tr_RSL_PAGING_CMD(mi), idx := {bts_ids[i], 0});
Harald Welte5d1a2202017-12-13 19:51:29 +01003407 /* check channel type, paging group */
3408 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3409 setverdict(fail, "Paging for wrong paging group");
3410 }
3411 if (ispresent(rsl_chneed) and
3412 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3413 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3414 }
Harald Welte6f521d82017-12-11 19:52:02 +01003415 }
Harald Welte2fccd982018-01-31 15:48:19 +01003416 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003417 /* do a quick check on all not-included BTSs if they received paging */
3418 for (i := 0; i < NUM_BTS; i := i + 1) {
3419 timer T := 0.1;
3420 if (f_bts_in_list(i, bts_ids)) {
3421 continue;
3422 }
3423 T.start;
3424 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003425 [] IPA_RSL[i][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003426 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3427 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003428 [] IPA_RSL[i][0].receive { repeat; }
Harald Welte5d1a2202017-12-13 19:51:29 +01003429 [] T.timeout { }
3430 }
Harald Welte6f521d82017-12-11 19:52:02 +01003431 }
3432
3433 setverdict(pass);
3434}
3435
Harald Welte5d1a2202017-12-13 19:51:29 +01003436const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003437const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003438const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3439const BtsIdList c_BtsId_LAC2 := { 2 };
3440
Harald Welte6f521d82017-12-11 19:52:02 +01003441/* PAGING by IMSI + TMSI */
3442testcase TC_paging_imsi_nochan() runs on test_CT {
3443 var BSSMAP_FIELD_CellIdentificationList cid_list;
3444 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003445 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003446 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003447}
3448
3449/* PAGING by IMSI + TMSI */
3450testcase TC_paging_tmsi_nochan() runs on test_CT {
3451 var BSSMAP_FIELD_CellIdentificationList cid_list;
3452 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003453 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003454 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003455}
3456
3457/* Paging with different "channel needed' values */
3458testcase TC_paging_tmsi_any() runs on test_CT {
3459 var BSSMAP_FIELD_CellIdentificationList cid_list;
3460 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003461 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003462 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003463}
3464testcase TC_paging_tmsi_sdcch() runs on test_CT {
3465 var BSSMAP_FIELD_CellIdentificationList cid_list;
3466 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003467 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003468 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003469}
3470testcase TC_paging_tmsi_tch_f() runs on test_CT {
3471 var BSSMAP_FIELD_CellIdentificationList cid_list;
3472 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003473 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003474 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003475}
3476testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3477 var BSSMAP_FIELD_CellIdentificationList cid_list;
3478 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003479 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003480 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003481}
3482
3483/* Paging by CGI */
3484testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3485 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3486 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003487 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003488 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003489}
3490
3491/* Paging by LAC+CI */
3492testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3493 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3494 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003495 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003496 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003497}
3498
3499/* Paging by CI */
3500testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3501 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3502 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003503 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003504 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003505}
3506
3507/* Paging by LAI */
3508testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3509 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3510 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003511 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003512 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003513}
3514
3515/* Paging by LAC */
3516testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3517 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3518 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003519 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003520 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003521}
3522
3523/* Paging by "all in BSS" */
3524testcase TC_paging_imsi_nochan_all() runs on test_CT {
3525 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3526 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003527 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003528 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003529}
3530
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003531/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003532testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3533 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3534 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 +01003535 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003536 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003537}
Harald Welte6f521d82017-12-11 19:52:02 +01003538
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003539/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003540testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3541 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3542 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003543 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003544 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003545}
3546
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003547/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003548testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3549 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3550 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003551 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003552 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003553}
3554
Harald Welte6f521d82017-12-11 19:52:02 +01003555/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003556testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3557 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3558 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3559 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003560 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003561}
3562
3563/* Paging on empty list: Verify none of them page */
3564testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3565 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3566 cid_list := { cIl_LAC := { } };
3567 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003568 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003569}
3570
Stefan Sperling049a86e2018-03-20 15:51:00 +01003571/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3572testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3573 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3574 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3575 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3576 f_shutdown_helper();
3577}
3578
Pau Espin Pedrol07657ae2023-01-03 12:08:05 +01003579/* Send paging response containing invalid (wrongly formatted) MobileIdentity IE. */
3580testcase TC_paging_imsi_nochan_ci_resp_invalid_mi() runs on test_CT {
3581 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3582 var BSSAP_N_CONNECT_ind rx_c_ind;
3583 var DchanTuple dt;
3584 var octetstring rr_pag_resp := '06270003535992617965720000'O;
3585 /* { 06 27 } is { GSM48_PDISC_RR, GSM48_MT_RR_PAG_RESP }
3586 * see 3GPP TS 44.018, table 9.1.25.1
3587 * { 00 } or { 01 } is CKSN + Spare Half Octet, not important
3588 * { 03 53 59 92 } is Mobile Station Classmark
3589 * { 61 79 65 72 00 00 } is the invalid Mobile Identity IE (3GPP TS 24.008, 10.5.1.4),
3590 * Length is 0x61 (97 in decimal).
3591 */
3592
3593 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
3594 f_pageing_helper('001010000000008'H, cid_list, { 0 });
3595
3596 /* Send CHAN RQD and wait for allocation; acknowledge it */
3597 dt.rsl_chan_nr := f_chreq_act_ack();
3598 dt.idx := {0, 0};
3599
3600 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3601 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), rr_pag_resp));
3602
3603 /* Expevct a CR with a matching Paging response on the A-Interface */
3604 timer T := 5.0;
3605 T.start;
3606 alt {
3607 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
3608 setverdict(pass);
3609 dt.sccp_conn_id := rx_c_ind.connectionId;
3610 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
3611 }
3612 [] BSSAP.receive {
3613 setverdict(fail, "Received unexpected message on A-Interface!");
3614 }
3615 [] T.timeout {
3616 setverdict(fail, "Received nothing on A-Interface!");
3617 }
3618 }
3619
3620 f_perform_clear_test_ct(dt);
3621 f_shutdown_helper();
3622}
3623
Harald Welte6f521d82017-12-11 19:52:02 +01003624/* Verify paging retransmission interval + count */
3625/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003626/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003627
Harald Weltee65d40e2017-12-13 00:09:06 +01003628/* Verify PCH load */
3629testcase TC_paging_imsi_load() runs on test_CT {
3630 var BSSMAP_FIELD_CellIdentificationList cid_list;
3631 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003632 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003633 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003634 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003635
3636 /* tell BSC there is no paging space anymore */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003637 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003638 f_sleep(0.2);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003639 IPA_RSL[0][0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003640
3641 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3642 * there would be 8 retransmissions during 4 seconds */
3643 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003644 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003645 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003646 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003647 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003648 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003649 }
Harald Welte2caa1062018-03-17 18:19:05 +01003650 [] T_retrans.timeout {
3651 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003652 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte2caa1062018-03-17 18:19:05 +01003653 T_retrans.start;
3654 repeat;
3655 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003656 [] T.timeout {
3657 setverdict(pass);
3658 }
3659 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003660
3661 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003662}
3663
Harald Welte235ebf12017-12-15 14:18:16 +01003664/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003665testcase TC_paging_counter() runs on test_CT {
3666 var BSSMAP_FIELD_CellIdentificationList cid_list;
3667 timer T := 4.0;
3668 var integer i;
3669 var integer paging_attempted_bsc;
3670 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003671 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003672 var integer paging_expired_bts[NUM_BTS];
3673 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3674
3675 f_init();
3676
3677 /* read counters before paging */
3678 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01003679 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
Harald Welte1ff69992017-12-14 12:31:17 +01003680 for (i := 0; i < NUM_BTS; i := i+1) {
3681 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3682 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3683 }
3684
3685 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3686
3687 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3688 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3689 for (i := 0; i < NUM_BTS; i := i+1) {
3690 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3691 paging_attempted_bts[i]+1);
3692 }
3693
3694 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3695 f_sleep(12.0);
Pau Espin Pedrol4e431832023-02-08 12:43:47 +01003696 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
Harald Welte1ff69992017-12-14 12:31:17 +01003697 for (i := 0; i < NUM_BTS; i := i+1) {
3698 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3699 paging_expired_bts[i]+1);
3700 }
Harald Welte1ff69992017-12-14 12:31:17 +01003701
Philipp Maier282ca4b2018-02-27 17:17:00 +01003702 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003703}
3704
3705
Harald Welte10985002017-12-12 09:29:15 +01003706/* Verify paging stops after A-RESET */
3707testcase TC_paging_imsi_a_reset() runs on test_CT {
3708 var BSSMAP_FIELD_CellIdentificationList cid_list;
3709 timer T := 3.0;
3710 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003711 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003712
3713 /* Perform a BSSMAP Reset and wait for ACK */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003714 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 +01003715 alt {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003716 [] 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 +01003717 [] BSSAP.receive { repeat; }
3718 }
3719
Daniel Willmanncbef3982018-07-30 09:22:40 +02003720 /* Wait to avoid a possible race condition if a paging message is
3721 * received right before the reset ACK. */
3722 f_sleep(0.2);
3723
Harald Welte10985002017-12-12 09:29:15 +01003724 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003725 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003726 IPA_RSL[i][0].clear;
Philipp Maier1e6b4422018-02-23 14:02:13 +01003727 }
Harald Welte10985002017-12-12 09:29:15 +01003728
3729 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3730 T.start;
3731 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003732 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003733 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003734 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003735 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003736 [] IPA_RSL[1][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003737 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003738 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003739 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003740 [] IPA_RSL[2][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003741 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003742 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003743 }
Harald Welte10985002017-12-12 09:29:15 +01003744 [] T.timeout {
3745 setverdict(pass);
3746 }
3747 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003748
3749 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003750}
Harald Welteae026692017-12-09 01:03:01 +01003751
Philipp Maierf45824a2019-08-14 14:44:10 +02003752/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3753 * paging response we can not know which MSC is in charge, so we will blindly
3754 * pick the first configured MSC. This behavior is required in order to make
3755 * MT-CSFB calls working because in those cases the BSC can not know that the
3756 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3757 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003758 */
3759testcase TC_paging_resp_unsol() runs on test_CT {
3760
3761 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003762 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003763
3764 var BSSAP_N_CONNECT_ind rx_c_ind;
3765 var DchanTuple dt;
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02003766 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(ts_MI_IMSI_LV('001010008880018'H)));
Philipp Maierf45824a2019-08-14 14:44:10 +02003767 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003768
3769 /* Send CHAN RQD and wait for allocation; acknowledge it */
3770 dt.rsl_chan_nr := f_chreq_act_ack();
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003771 dt.idx := {0, 0};
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003772
3773 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
Pau Espin Pedrole8a51012023-01-03 11:59:59 +01003774 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 +01003775
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003776
Philipp Maierf45824a2019-08-14 14:44:10 +02003777 /* Expevct a CR with a matching Paging response on the A-Interface */
3778 T.start;
3779 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003780 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003781 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003782 dt.sccp_conn_id := rx_c_ind.connectionId;
3783 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003784 }
3785 [] BSSAP.receive {
3786 setverdict(fail, "Received unexpected message on A-Interface!");
3787 }
3788 [] T.timeout {
3789 setverdict(fail, "Received nothing on A-Interface!");
3790 }
3791 }
3792
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003793 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003794 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003795}
3796
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003797/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3798function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003799 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003800 var Hexstrings imsis := {};
3801 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003802 var integer rx_paging_num := 0;
3803 var integer i;
3804 timer T_rx := 60.0;
3805 timer T_load_ind := 1.0;
3806
3807 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003808 imsis := imsis & {f_gen_imsi(i)};
3809 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003810 }
3811
3812 f_init(1, guard_timeout := 100.0);
3813
3814 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003815 IPA_RSL[0][0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003816 if (send_pag_load_ind) {
3817 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003818 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(65535));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003819 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003820
3821 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003822 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003823 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 +02003824 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3825 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003826 }
3827
3828 T_rx.start;
3829 T_load_ind.start;
3830 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003831 [] 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 +02003832 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3833 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3834 var charstring imsi_str := hex2str(imsi_suffix);
3835 var integer imsi_idx := str2int(imsi_str);
3836 if (rx_paging_done[imsi_idx] == false) {
3837 rx_paging_done[imsi_idx] := true;
3838 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003839 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003840 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 +02003841 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003842 }
3843 if (rx_paging_num < num_subscribers) {
3844 repeat;
3845 }
3846 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003847 [] IPA_RSL[0][0].receive { repeat; }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003848 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003849 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3850 if (send_pag_load_ind) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003851 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(40));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003852 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003853 T_load_ind.start;
3854 repeat;
3855 }
3856 [] T_rx.timeout {
3857 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3858 mtc.stop;
3859 }
3860 }
3861
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003862 /* Drop OML connection to have all paging requests flushed: */
3863 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3864
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003865 f_shutdown_helper();
3866}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003867/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3868testcase TC_paging_500req() runs on test_CT {
3869 f_TC_paging_Nreq(500, true);
3870}
3871/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3872 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3873 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3874 * for current config yields ~8req/sec, so 480req/min maximum. */
3875testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3876 f_TC_paging_Nreq(450, false);
3877}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003878
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003879/* Test RSL link drop causes counter increment */
3880testcase TC_rsl_drop_counter() runs on test_CT {
3881 var integer rsl_fail;
3882
Harald Welte89d42e82017-12-17 16:42:41 +01003883 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003884
3885 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3886
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003887 f_ipa_rsl_stop(bts[0][0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003888
3889 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3890
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003891 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003892}
3893
3894/* TODO: Test OML link drop causes counter increment */
3895
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003896/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3897function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003898 var IPA_Client client;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003899 timer T := 10.0;
3900
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003901 client.id := "IPA-BTS0-TRX0-RSL";
3902 client.vc_IPA := IPA_Emulation_CT.create(client.id & "-IPA") alive;
3903 client.ccm_pars := c_IPA_default_ccm_pars;
3904 client.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
3905 client.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003906
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003907 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003908
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003909 f_init_mgcp(0, "VirtMGW");
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003910
3911 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003912 map(client.vc_IPA:IPA_PORT, system:IPA);
3913 connect(client.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0][0]);
3914 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 +01003915
3916 /* wait for IPA OML link to connect and then disconnect */
3917 T.start;
3918 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003919 [] IPA_RSL[0][0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003920 T.stop;
3921 return true;
3922 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003923 [] IPA_RSL[0][0].receive { repeat }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003924 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003925 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003926 }
3927 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003928 return false;
3929}
3930
3931/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3932testcase TC_rsl_unknown_unit_id() runs on test_CT {
3933 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3934 setverdict(pass);
3935 } else {
3936 setverdict(fail, "Timeout RSL waiting for connection to close");
3937 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003938 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003939}
3940
3941
3942/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3943testcase TC_oml_unknown_unit_id() runs on test_CT {
3944 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3945 setverdict(pass);
3946 } else {
3947 setverdict(fail, "Timeout OML waiting for connection to close");
3948 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003949 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003950}
3951
3952
Harald Weltec1a2fff2017-12-17 11:06:19 +01003953/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003954 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003955 ***********************************************************************/
3956
Harald Welte6811d102019-04-14 22:23:14 +02003957import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003958import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003959import from RSL_Emulation all;
3960import from MSC_ConnectionHandler all;
3961
3962type function void_fn(charstring id) runs on MSC_ConnHdlr;
3963
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003964/* helper function to create and connect a MSC_ConnHdlr component
3965 * TODO: allow connecting to TRX1..N, not only TRX0 */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003966private 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 +02003967 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003968 connect(vc_conn:RSL, bts[0][0].rsl.vc_RSL:CLIENT_PT);
3969 connect(vc_conn:RSL_PROC, bts[0][0].rsl.vc_RSL:RSL_PROC);
3970 if (isvalue(bts[1][0])) {
3971 connect(vc_conn:RSL1, bts[1][0].rsl.vc_RSL:CLIENT_PT);
3972 connect(vc_conn:RSL1_PROC, bts[1][0].rsl.vc_RSL:RSL_PROC);
Philipp Maier956a92f2018-02-16 10:58:07 +01003973 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003974 if (isvalue(bts[2][0])) {
3975 connect(vc_conn:RSL2, bts[2][0].rsl.vc_RSL:CLIENT_PT);
3976 connect(vc_conn:RSL2_PROC, bts[2][0].rsl.vc_RSL:RSL_PROC);
Neels Hofmeyr91401012019-07-11 00:42:35 +02003977 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003978 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003979 if (mp_enable_lcs_tests) {
3980 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3981 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3982 }
Daniel Willmannebdecc02020-08-12 15:30:17 +02003983 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003984 connect(vc_conn:MGCP_PROC, vc_MGCP[mgwpool_idx]:MGCP_PROC);
3985 connect(vc_conn:MGCP, vc_MGCP[mgwpool_idx]:MGCP_CLIENT);
3986 connect(vc_conn:MGCP_MULTI, vc_MGCP[mgwpool_idx]:MGCP_CLIENT_MULTI);
Harald Welte336820c2018-05-31 20:34:52 +02003987}
3988
Neels Hofmeyrda436782021-07-20 22:09:06 +02003989function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003990runs on test_CT return MSC_ConnHdlr {
3991 var charstring id := testcasename();
3992 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003993 var integer bssap_idx := 0;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003994 var integer mgwpool_idx := 0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003995 if (isvalue(pars)) {
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003996 var TestHdlrParams pars_val := valueof(pars);
3997 bssap_idx := pars_val.mscpool.bssap_idx;
3998 mgwpool_idx := pars_val.mgwpool_idx;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003999 }
Harald Welte336820c2018-05-31 20:34:52 +02004000 vc_conn := MSC_ConnHdlr.create(id);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02004001 f_connect_handler(vc_conn, bssap_idx, mgwpool_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02004002 return vc_conn;
4003}
4004
4005function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
4006runs on test_CT return MSC_ConnHdlr {
4007 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01004008 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004009 return vc_conn;
4010}
4011
Neels Hofmeyrda436782021-07-20 22:09:06 +02004012function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
4013runs on test_CT return MSC_ConnHdlr {
4014 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
4015}
4016
Harald Weltea0630032018-03-20 21:09:55 +01004017/* first function inside ConnHdlr component; sets g_pars + starts function */
4018private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
4019runs on MSC_ConnHdlr {
4020 if (isvalue(pars)) {
4021 g_pars := valueof(pars);
4022 }
4023 fn.apply(id);
4024}
4025
Oliver Smith26a3db72021-07-09 13:51:29 +02004026private function f_vty_encryption_a5(charstring options) runs on test_CT {
4027 f_vty_transceive(BSCVTY, "configure terminal");
4028 f_vty_transceive(BSCVTY, "network");
4029 f_vty_transceive(BSCVTY, "encryption a5 " & options);
4030 f_vty_transceive(BSCVTY, "exit");
4031 f_vty_transceive(BSCVTY, "exit");
4032}
4033
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01004034const charstring VTY_A5_DEFAULT := "0 1 3";
4035
Oliver Smith26a3db72021-07-09 13:51:29 +02004036private function f_vty_encryption_a5_reset() runs on test_CT {
4037 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01004038 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02004039}
4040
Harald Welte3c86ea02018-05-10 22:28:05 +02004041/* Establish signalling channel (non-assignment case) followed by cipher mode */
4042private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004043 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4044 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02004045 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02004046 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
4047 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
4048 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
4049 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02004050
Philipp Maier23000732018-05-18 11:25:37 +02004051 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004052 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02004053}
4054testcase TC_ciph_mode_a5_0() runs on test_CT {
4055 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004056 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004057 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
4058
4059 f_init(1, true);
4060 f_sleep(1.0);
4061 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4062 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004063 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004064}
4065testcase TC_ciph_mode_a5_1() runs on test_CT {
4066 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004067 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004068 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
4069
4070 f_init(1, true);
4071 f_sleep(1.0);
4072 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4073 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004074 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004075}
Oliver Smith50b98122021-07-09 15:00:28 +02004076/* OS#4975: verify that A5/2 is preferred over A5/0 */
4077testcase TC_ciph_mode_a5_2_0() runs on test_CT {
4078 var MSC_ConnHdlr vc_conn;
4079 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4080
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01004081 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02004082
4083 f_init(1, true);
4084 f_vty_encryption_a5("0 1 2 3");
4085 f_sleep(1.0);
4086 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4087 vc_conn.done;
4088 f_vty_encryption_a5_reset();
4089 f_shutdown_helper();
4090}
Oliver Smith1dff88d2021-07-09 08:45:51 +02004091/* OS#4975: verify that A5/1 is preferred over A5/2 */
4092testcase TC_ciph_mode_a5_2_1() runs on test_CT {
4093 var MSC_ConnHdlr vc_conn;
4094 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4095
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01004096 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02004097
4098 f_init(1, true);
4099 f_vty_encryption_a5("1 2");
4100 f_sleep(1.0);
4101 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4102 vc_conn.done;
4103 f_vty_encryption_a5_reset();
4104 f_shutdown_helper();
4105}
Harald Welte3c86ea02018-05-10 22:28:05 +02004106testcase TC_ciph_mode_a5_3() runs on test_CT {
4107 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004108 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004109 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
4110
4111 f_init(1, true);
4112 f_sleep(1.0);
4113 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4114 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004115 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004116}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004117/* Establish a Signalling channel with A5/4 encryption. */
4118testcase TC_ciph_mode_a5_4() runs on test_CT {
4119 var MSC_ConnHdlr vc_conn;
4120 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4121 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02004122
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004123 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02004124 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004125 f_sleep(1.0);
4126 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4127 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02004128 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004129 f_shutdown_helper();
4130}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004131/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
4132private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
4133 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4134 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
4135 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4136 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4137
4138 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004139 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004140}
4141testcase TC_assignment_aoip_tla_v6() runs on test_CT {
4142 var MSC_ConnHdlr vc_conn;
4143 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4144
4145 f_init(1, true);
4146 f_sleep(1.0);
4147 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
4148 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004149 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004150}
4151
Harald Welte3c86ea02018-05-10 22:28:05 +02004152
4153/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02004154private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004155 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4156 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004157
Harald Welte552620d2017-12-16 23:21:36 +01004158 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4159 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01004160
Harald Weltea0630032018-03-20 21:09:55 +01004161 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004162 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004163}
Harald Welte552620d2017-12-16 23:21:36 +01004164testcase TC_assignment_fr_a5_0() runs on test_CT {
4165 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004166 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004167 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01004168
Harald Welte89d42e82017-12-17 16:42:41 +01004169 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004170 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004171 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004172 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004173 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004174}
Harald Welte552620d2017-12-16 23:21:36 +01004175testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01004176 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004177 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004178 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004179
Harald Welte89d42e82017-12-17 16:42:41 +01004180 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004181 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004182 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4183 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004184 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02004185}
4186testcase TC_assignment_fr_a5_3() runs on test_CT {
4187 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004188 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004189 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004190
Harald Welte651fcdc2018-05-10 20:23:16 +02004191 f_init(1, true);
4192 f_sleep(1.0);
4193 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004194 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004195 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004196}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004197/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
4198testcase TC_assignment_fr_a5_4() runs on test_CT {
4199 var MSC_ConnHdlr vc_conn;
4200 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4201 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
4202
4203 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004204 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004205 f_sleep(1.0);
4206 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4207 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02004208 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004209 f_shutdown_helper();
4210}
Harald Weltec1a2fff2017-12-17 11:06:19 +01004211
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02004212/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
4213testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
4214 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4215 var MSC_ConnHdlr vc_conn;
4216
4217 f_init(1, true);
4218 f_sleep(1.0);
4219
4220 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4221 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4222 vc_conn.done;
4223 f_shutdown_helper();
4224}
4225
Harald Welte552620d2017-12-16 23:21:36 +01004226/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4227private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004228 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004229 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004230 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004231
4232 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004233 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4234
Harald Weltea0630032018-03-20 21:09:55 +01004235 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004236 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004237}
Harald Welte552620d2017-12-16 23:21:36 +01004238testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4239 var MSC_ConnHdlr vc_conn;
4240
Harald Welte89d42e82017-12-17 16:42:41 +01004241 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004242 f_sleep(1.0);
4243
Harald Welte8863fa12018-05-10 20:15:27 +02004244 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004245 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004246 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004247}
4248
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004249private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4250 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4251 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004252
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004253 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4254 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4255
4256 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4257
4258 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004259
4260 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4261 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4262
4263 f_create_chan_and_exp();
4264 /* we should now have a COMPL_L3 at the MSC */
4265
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004266 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004267 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004268 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004269}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004270testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4271 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004272 var MSC_ConnHdlr vc_conn;
4273
Harald Welte89d42e82017-12-17 16:42:41 +01004274 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004275 f_sleep(1.0);
4276
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004277 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004278 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004279 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004280 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004281}
4282
4283
Harald Welte4532e0a2017-12-23 02:05:44 +01004284private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004285 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004286 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004287 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004288 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004289
4290 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004291 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004292
4293 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004294 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4295 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004296 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4297 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4298 };
4299 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004300 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004301}
4302
4303testcase TC_assignment_sign() runs on test_CT {
4304 var MSC_ConnHdlr vc_conn;
4305
4306 f_init(1, true);
4307 f_sleep(1.0);
4308
Harald Welte8863fa12018-05-10 20:15:27 +02004309 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004310 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004311 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004312}
4313
Harald Welte60aa5762018-03-21 19:33:13 +01004314/***********************************************************************
4315 * Codec (list) testing
4316 ***********************************************************************/
4317
4318/* check if the given rsl_mode is compatible with the a_elem */
4319private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4320return boolean {
4321 select (a_elem.codecType) {
4322 case (GSM_FR) {
4323 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4324 return true;
4325 }
4326 }
4327 case (GSM_HR) {
4328 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4329 return true;
4330 }
4331 }
4332 case (GSM_EFR) {
4333 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4334 return true;
4335 }
4336 }
4337 case (FR_AMR) {
4338 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4339 return true;
4340 }
4341 }
4342 case (HR_AMR) {
4343 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4344 return true;
4345 }
4346 }
4347 case else { }
4348 }
4349 return false;
4350}
4351
4352/* check if the given rsl_mode is compatible with the a_list */
4353private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4354return boolean {
4355 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4356 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4357 return true;
4358 }
4359 }
4360 return false;
4361}
4362
4363/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004364function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004365return BSSMAP_IE_ChannelType {
4366 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4367 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4368 select (a_elem.codecType) {
4369 case (GSM_FR) {
4370 ret.channelRateAndType := ChRate_TCHF;
4371 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4372 }
4373 case (GSM_HR) {
4374 ret.channelRateAndType := ChRate_TCHH;
4375 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4376 }
4377 case (GSM_EFR) {
4378 ret.channelRateAndType := ChRate_TCHF;
4379 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4380 }
4381 case (FR_AMR) {
4382 ret.channelRateAndType := ChRate_TCHF;
4383 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4384 }
4385 case (HR_AMR) {
4386 ret.channelRateAndType := ChRate_TCHH;
4387 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4388 }
4389 case else {
4390 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004391 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004392 }
4393 }
4394 return ret;
4395}
4396
Harald Weltea63b9102018-03-22 20:36:16 +01004397private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4398return template RSL_IE_Body {
4399 var template RSL_IE_Body mode_ie := {
4400 chan_mode := {
4401 len := ?,
4402 reserved := ?,
4403 dtx_d := ?,
4404 dtx_u := ?,
4405 spd_ind := RSL_SPDI_SPEECH,
4406 ch_rate_type := -,
Oliver Smith0033b122023-02-28 13:30:53 +01004407 u := { speech := - }
Harald Weltea63b9102018-03-22 20:36:16 +01004408 }
4409 }
4410
4411 select (a_elem.codecType) {
4412 case (GSM_FR) {
4413 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
Oliver Smith0033b122023-02-28 13:30:53 +01004414 mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM1;
Harald Weltea63b9102018-03-22 20:36:16 +01004415 }
4416 case (GSM_HR) {
4417 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
Oliver Smith0033b122023-02-28 13:30:53 +01004418 mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM1;
Harald Weltea63b9102018-03-22 20:36:16 +01004419 }
4420 case (GSM_EFR) {
4421 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
Oliver Smith0033b122023-02-28 13:30:53 +01004422 mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM2;
Harald Weltea63b9102018-03-22 20:36:16 +01004423 }
4424 case (FR_AMR) {
4425 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
Oliver Smith0033b122023-02-28 13:30:53 +01004426 mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM3;
Harald Weltea63b9102018-03-22 20:36:16 +01004427 }
4428 case (HR_AMR) {
4429 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
Oliver Smith0033b122023-02-28 13:30:53 +01004430 mode_ie.chan_mode.u.speech := RSL_CMOD_SP_GSM3;
Harald Weltea63b9102018-03-22 20:36:16 +01004431 }
4432 }
4433 return mode_ie;
4434}
4435
Harald Welte60aa5762018-03-21 19:33:13 +01004436type record CodecListTest {
4437 BSSMAP_IE_SpeechCodecList codec_list,
4438 charstring id
4439}
4440type record of CodecListTest CodecListTests
4441
4442private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004443 f_assignment_codec(id);
4444}
4445
4446private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02004447 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02004448 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Harald Welte60aa5762018-03-21 19:33:13 +01004449
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) {
Harald Welte79f3f542018-05-25 20:02:37 +02004452 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4453 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4454 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004455 if (isvalue(g_pars.expect_mr_s0_s7)) {
4456 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4457 g_pars.expect_mr_s0_s7;
4458 }
Harald Welte79f3f542018-05-25 20:02:37 +02004459 }
Harald Welte60aa5762018-03-21 19:33:13 +01004460 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4461 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004462 log("expecting ASS COMPL like this: ", exp_compl);
4463
4464 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004465
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004466 if (not g_pars.expect_channel_mode_modify) {
4467 /* Verify that the RSL-side activation actually matches our expectations */
4468 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004469
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004470 var RSL_IE_Body mode_ie;
4471 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4472 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004473 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004474 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004475 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4476 if (not match(mode_ie, t_mode_ie)) {
4477 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4478 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004479 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004480
4481 var RSL_IE_Body mr_conf;
4482 if (g_pars.expect_mr_conf_ie != omit) {
4483 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4484 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4485 mtc.stop;
4486 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004487 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004488
4489 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
Vadim Yanitskiy8b189372022-09-14 17:31:17 +07004490 setverdict(fail, "RSL MR CONFIG IE does not match expectation. ",
4491 "Expected: ", g_pars.expect_mr_conf_ie, ", got: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004492 }
4493 } else {
4494 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4495 log("found RSL MR CONFIG IE: ", mr_conf);
4496 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4497 mtc.stop;
4498 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004499 }
4500 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004501
4502 if (do_perform_clear) {
4503 f_perform_clear();
4504 }
Harald Welte60aa5762018-03-21 19:33:13 +01004505}
4506
Philipp Maierd0e64b02019-03-13 14:15:23 +01004507private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4508
4509 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4510 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4511
4512 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004513 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004514 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4515 }
4516 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4517 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4518 log("expecting ASS FAIL like this: ", exp_fail);
4519
4520 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004521 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004522}
4523
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004524const CounterNameVals counternames_bsc_bts_assignment := {
4525 { "assignment:attempted", 0 },
4526 { "assignment:completed", 0 },
4527 { "assignment:stopped", 0 },
4528 { "assignment:no_channel", 0 },
4529 { "assignment:timeout", 0 },
4530 { "assignment:failed", 0 },
4531 { "assignment:error", 0 }
4532};
4533
4534const CounterNameVals counternames_bts_assignment := {
4535 { "assignment:attempted_sign", 0 },
4536 { "assignment:attempted_speech", 0 },
4537 { "assignment:completed_sign", 0 },
4538 { "assignment:completed_speech", 0 },
4539 { "assignment:stopped_sign", 0 },
4540 { "assignment:stopped_speech", 0 },
4541 { "assignment:no_channel_sign", 0 },
4542 { "assignment:no_channel_speech", 0 },
4543 { "assignment:timeout_sign", 0 },
4544 { "assignment:timeout_speech", 0 },
4545 { "assignment:failed_sign", 0 },
4546 { "assignment:failed_speech", 0 },
4547 { "assignment:error_sign", 0 },
4548 { "assignment:error_speech", 0 }
4549};
4550
4551function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4552 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4553 f_ctrs_bts_init(bts_count, bts_names);
4554 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4555}
4556
Harald Welte60aa5762018-03-21 19:33:13 +01004557testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004558 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004559 var MSC_ConnHdlr vc_conn;
4560
4561 f_init(1, true);
4562 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004563 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004564
4565 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004566 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004567 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004568
4569 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4570 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4571 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4572 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4573 f_ctrs_bts_verify();
4574
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004575 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004576}
4577
4578testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004579 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004580 var MSC_ConnHdlr vc_conn;
4581
4582 f_init(1, true);
4583 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004584 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004585
4586 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004587 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004588 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004589
4590 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4591 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4592 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4593 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4594 f_ctrs_bts_verify();
4595
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004596 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004597}
4598
4599testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004600 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004601 var MSC_ConnHdlr vc_conn;
4602
4603 f_init(1, true);
4604 f_sleep(1.0);
4605
4606 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004607 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004608 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004609 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004610}
4611
Philipp Maierd0e64b02019-03-13 14:15:23 +01004612/* Allow 5,90k only (current default config) */
4613private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004614 f_vty_cfg_msc(BSCVTY, 0, {
4615 "amr-config 12_2k forbidden",
4616 "amr-config 10_2k forbidden",
4617 "amr-config 7_95k forbidden",
4618 "amr-config 7_40k forbidden",
4619 "amr-config 6_70k forbidden",
4620 "amr-config 5_90k allowed",
4621 "amr-config 5_15k forbidden",
4622 "amr-config 4_75k forbidden"
4623 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004624}
4625
4626/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4627 * ("Config-NB-Code = 1") */
4628private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004629 f_vty_cfg_msc(BSCVTY, 0, {
4630 "amr-config 12_2k allowed",
4631 "amr-config 10_2k forbidden",
4632 "amr-config 7_95k forbidden",
4633 "amr-config 7_40k allowed",
4634 "amr-config 6_70k forbidden",
4635 "amr-config 5_90k allowed",
4636 "amr-config 5_15k forbidden",
4637 "amr-config 4_75k allowed"
4638 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004639}
4640
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004641private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4642 var charstring tch;
4643 if (fr) {
4644 tch := "tch-f";
4645 } else {
4646 tch := "tch-h";
4647 }
4648 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4649}
4650
4651/* Set the AMR start-mode for this TCH back to the default configuration. */
4652private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4653 f_vty_amr_start_mode_set(fr, "auto");
4654}
4655
Harald Welte60aa5762018-03-21 19:33:13 +01004656testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004657 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004658 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004659
4660 /* Note: This setups the codec configuration. The parameter payload in
4661 * mr_conf must be consistant with the parameter codecElements in pars
4662 * and also must match the amr-config in osmo-bsc.cfg! */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004663 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004664 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004665 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004666 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004667
Harald Welte60aa5762018-03-21 19:33:13 +01004668 f_init(1, true);
4669 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004670 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004671 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004672
Harald Welte8863fa12018-05-10 20:15:27 +02004673 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004674 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004675
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004676 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4677 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4678 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4679 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4680 f_ctrs_bts_verify();
4681
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004682 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004683 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004684}
4685
4686testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004687 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004688 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004689
4690 /* See note above */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004691 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004692 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004693 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004694 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004695
Harald Welte60aa5762018-03-21 19:33:13 +01004696 f_init(1, true);
4697 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004698 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004699 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004700
Harald Welte8863fa12018-05-10 20:15:27 +02004701 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004702 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004703
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004704 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4705 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4706 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4707 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4708 f_ctrs_bts_verify();
4709
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004710 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004711 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004712}
4713
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004714/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4715testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4716 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4717 var MSC_ConnHdlr vc_conn;
4718
4719 f_init(1, true);
4720 f_sleep(1.0);
4721
4722 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4723 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4724 * expecting a Channel Mode Modify if the channel type is compatible. */
4725 f_disable_all_sdcch();
4726 f_disable_all_tch_h();
4727
4728 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4729 pars.expect_channel_mode_modify := true;
4730 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4731 vc_conn.done;
4732
4733 f_enable_all_sdcch();
4734 f_enable_all_tch();
4735 f_shutdown_helper();
4736}
4737
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004738/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4739testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4740 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4741 var MSC_ConnHdlr vc_conn;
4742
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004743 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4744 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4745 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy36fe9582022-09-14 15:25:04 +07004746 pars.expect_mr_conf_ie := c_mr_conf_5_90;
4747 pars.expect_mr_conf_ie.multirate_cfg.icmi := false; /* expect ICMI=0, smod=00: */
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004748
4749 f_init(1, true);
4750 f_sleep(1.0);
4751
4752 /* First set nonzero start mode bits */
4753 f_vty_amr_start_mode_set(true, "4");
4754 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4755 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4756 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4757 f_vty_amr_start_mode_set(true, "auto");
4758
4759 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4760 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004761
4762 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4763 f_vty_amr_start_mode_set(true, "1");
4764 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004765 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004766}
4767
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004768function f_TC_assignment_codec_amr(boolean fr, RSL_IE_MultirateCfg mr_cfg,
4769 bitstring s8_s0, bitstring exp_s8_s0,
4770 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004771runs on test_CT {
4772
4773 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4774 var MSC_ConnHdlr vc_conn;
4775
Philipp Maierd0e64b02019-03-13 14:15:23 +01004776 if (fr) {
4777 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4778 } else {
4779 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4780 }
4781 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4782 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004783 pars.expect_mr_conf_ie := { multirate_cfg := mr_cfg };
Philipp Maierd0e64b02019-03-13 14:15:23 +01004784 pars.expect_mr_s0_s7 := exp_s8_s0;
4785
4786 f_init(1, true);
4787 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004788 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004789 f_sleep(1.0);
4790
4791 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4792 vc_conn.done;
4793 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004794 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004795}
4796
4797function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4798runs on test_CT {
4799
4800 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4801 var MSC_ConnHdlr vc_conn;
4802
4803 if (fr) {
4804 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4805 } else {
4806 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4807 }
4808 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4809 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4810
4811 f_init(1, true);
4812 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004813 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004814 f_sleep(1.0);
4815
4816 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4817 vc_conn.done;
4818 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004819 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004820}
4821
Philipp Maierd0e64b02019-03-13 14:15:23 +01004822/* Set S1, we expect an AMR multirate configuration IE with all four rates
4823 * set. */
4824testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004825 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4826 params := '20882208'O));
4827 f_TC_assignment_codec_amr(true, mr_cfg, '00000011'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004828 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004829}
4830
4831/* Set S1, we expect an AMR multirate configuration IE with the lower three
4832 * rates set. */
4833testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004834 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4835 params := '208820'O));
4836 f_TC_assignment_codec_amr(false, mr_cfg, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004837 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004838}
4839
4840/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4841 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4842testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004843 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4844 params := '20882208'O));
4845 f_TC_assignment_codec_amr(true, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004846 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004847}
4848
4849/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4850 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4851testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004852 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4853 params := '208820'O));
4854 f_TC_assignment_codec_amr(false, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004855 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004856}
4857
4858/* The following block of tests selects more and more rates until all four
4859 * possible rates are in the active set (full rate) */
4860testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004861 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4862 f_TC_assignment_codec_amr(true, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004863 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004864}
4865
4866testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004867 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4868 params := '2080'O));
4869 f_TC_assignment_codec_amr(true, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004870 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004871}
4872
4873testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004874 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4875 params := '208820'O));
4876 f_TC_assignment_codec_amr(true, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004877 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004878}
4879
4880testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004881 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4882 params := '20882208'O));
4883 f_TC_assignment_codec_amr(true, mr_cfg, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004884 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004885}
4886
4887/* The following block of tests selects more and more rates until all three
4888 * possible rates are in the active set (half rate) */
4889testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004890 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4891 f_TC_assignment_codec_amr(false, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004892 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004893}
4894
4895testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004896 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4897 params := '2080'O));
4898 f_TC_assignment_codec_amr(false, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004899 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004900}
4901
4902testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004903 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4904 params := '208820'O));
4905 f_TC_assignment_codec_amr(false, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004906 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004907}
4908
4909/* The following block tests what happens when the MSC does offer rate
4910 * configurations that are not supported by the BSC. Normally such situations
4911 * should not happen because the MSC gets informed by the BSC in advance via
4912 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4913 * to offer rates that are not applicable anyway. */
4914
4915testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004916 /* Try to include 12,2k in into the active set even though the channel
4917 * is half rate only. The BSC is expected to remove the 12,0k */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004918 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4919 params := '208820'O));
4920 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004921 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004922}
4923
4924testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004925 /* See what happens when all rates are selected at once. Since then
4926 * Also S1 is selected, this setting will be prefered and we should
4927 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004928 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4929 params := '20882208'O));
4930 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004931 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004932}
4933
4934testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004935 /* Same as above, but with S1 missing, the MSC is then expected to
4936 * select the currently supported rates, which are also 12.2k, 7,40k,
4937 * 5,90k, and 4,75k, into the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004938 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4939 params := '20882208'O));
4940 f_TC_assignment_codec_amr(true, mr_cfg, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004941 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004942}
4943
4944testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004945 /* Try to select no rates at all */
4946 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004947 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004948}
4949
4950testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004951 /* Try to select only unsupported rates */
4952 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004953 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004954}
4955
4956testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004957 /* Try to select 12,2k for half rate */
4958 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004959 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004960}
4961
Neels Hofmeyr21863562020-11-26 00:34:33 +00004962testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004963 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4964 codec_modes := '10010101'B,
4965 params := '20882208'O));
4966 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004967 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004968}
4969
4970testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004971 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4972 codec_modes := '00010101'B,
4973 params := '208820'O));
4974 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B,
Neels Hofmeyr21863562020-11-26 00:34:33 +00004975 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004976 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004977}
4978
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004979testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004980 /* "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 +07004981 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 3,
4982 codec_modes := '10010101'B,
4983 params := '20882208'O));
4984 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004985 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004986}
4987
4988testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004989 /* "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 +07004990 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 2,
4991 codec_modes := '00010101'B,
4992 params := '208820'O));
4993 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004994 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004995}
4996
Philipp Maierac09bfc2019-01-08 13:41:39 +01004997private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004998 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4999 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
5000 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
5001 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01005002}
5003
5004private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01005005 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
5006 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01005007}
5008
5009private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01005010 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
5011 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
5012 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
5013 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
5014 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
5015 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01005016}
5017
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02005018private function f_disable_all_sdcch() runs on test_CT {
5019 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
5020 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
5021 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
5022 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
5023}
5024
5025private function f_enable_all_sdcch() runs on test_CT {
5026 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
5027 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
5028 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
5029 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
5030}
5031
Philipp Maierac09bfc2019-01-08 13:41:39 +01005032/* Allow HR only */
5033private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
5034 g_pars := f_gen_test_hdlr_pars();
5035 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5036 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5037 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5038 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
5039 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
5040 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5041 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005042 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005043}
5044
5045/* Allow FR only */
5046private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
5047 g_pars := f_gen_test_hdlr_pars();
5048 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5049 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5050 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5051 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
5052 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
5053 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5054 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005055 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005056}
5057
5058/* Allow HR only (expect assignment failure) */
5059private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
5060 g_pars := f_gen_test_hdlr_pars();
5061 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5062 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
5063 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5064 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
5065 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
5066 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5067 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005068 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005069}
5070
5071/* Allow FR only (expect assignment failure) */
5072private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
5073 g_pars := f_gen_test_hdlr_pars();
5074 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5075 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
5076 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5077 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
5078 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
5079 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5080 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005081 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005082}
5083
5084/* Allow FR and HR, but prefer FR */
5085private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5086 g_pars := f_gen_test_hdlr_pars();
5087 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5088 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5089 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5090 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5091 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5092 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5093 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5094 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005095 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005096}
5097
5098/* Allow FR and HR, but prefer HR */
5099private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5100 g_pars := f_gen_test_hdlr_pars();
5101 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5102 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5103 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5104 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5105 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5106 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5107 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5108 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005109 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005110}
5111
5112/* Allow FR and HR, but prefer FR */
5113private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5114 g_pars := f_gen_test_hdlr_pars();
5115 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5116 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5117 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5118 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5119 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5120 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5121 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5122 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005123 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005124}
5125
5126/* Allow FR and HR, but prefer HR */
5127private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5128 g_pars := f_gen_test_hdlr_pars();
5129 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5130 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5131 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5132 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5133 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5134 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5135 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5136 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005137 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005138}
5139
5140/* Request a HR channel while all FR channels are exhausted, this is expected
5141 * to work without conflicts */
5142testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
5143 var MSC_ConnHdlr vc_conn;
5144 f_init(1, true);
5145 f_sleep(1.0);
5146 f_enable_all_tch();
5147 f_disable_all_tch_f();
5148 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
5149 vc_conn.done;
5150 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005151 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005152}
5153
5154/* Request a FR channel while all FR channels are exhausted, this is expected
5155 * to fail. */
5156testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
5157 var MSC_ConnHdlr vc_conn;
5158 f_init(1, true);
5159 f_sleep(1.0);
5160 f_enable_all_tch();
5161 f_disable_all_tch_f();
5162 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
5163 vc_conn.done;
5164 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005165 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005166}
5167
5168/* Request a FR (prefered) or alternatively a HR channel while all FR channels
5169 * are exhausted, this is expected to be resolved by selecting a HR channel. */
5170testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
5171 var MSC_ConnHdlr vc_conn;
5172 f_init(1, true);
5173 f_sleep(1.0);
5174 f_enable_all_tch();
5175 f_disable_all_tch_f();
5176 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
5177 vc_conn.done;
5178 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005179 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005180}
5181
5182/* Request a HR (prefered) or alternatively a FR channel while all FR channels
5183 * are exhausted, this is expected to work without conflicts. */
5184testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
5185 var MSC_ConnHdlr vc_conn;
5186 f_init(1, true);
5187 f_sleep(1.0);
5188 f_enable_all_tch();
5189 f_disable_all_tch_f();
5190 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
5191 vc_conn.done;
5192 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005193 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005194}
5195
5196/* Request a FR channel while all HR channels are exhausted, this is expected
5197 * to work without conflicts */
5198testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
5199 var MSC_ConnHdlr vc_conn;
5200 f_init(1, true);
5201 f_sleep(1.0);
5202 f_enable_all_tch();
5203 f_disable_all_tch_h();
5204 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
5205 vc_conn.done;
5206 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005207 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005208}
5209
5210/* Request a HR channel while all HR channels are exhausted, this is expected
5211 * to fail. */
5212testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
5213 var MSC_ConnHdlr vc_conn;
5214 f_init(1, true);
5215 f_sleep(1.0);
5216 f_enable_all_tch();
5217 f_disable_all_tch_h();
5218 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
5219 vc_conn.done;
5220 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005221 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005222}
5223
5224/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5225 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5226testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5227 var MSC_ConnHdlr vc_conn;
5228 f_init(1, true);
5229 f_sleep(1.0);
5230 f_enable_all_tch();
5231 f_disable_all_tch_h();
5232 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5233 vc_conn.done;
5234 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005235 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005236}
5237
5238/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5239 * are exhausted, this is expected to work without conflicts. */
5240testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5241 var MSC_ConnHdlr vc_conn;
5242 f_init(1, true);
5243 f_sleep(1.0);
5244 f_enable_all_tch();
5245 f_disable_all_tch_h();
5246 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5247 vc_conn.done;
5248 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005249 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005250}
5251
5252/* Allow FR and HR, but prefer HR */
5253private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5254 g_pars := f_gen_test_hdlr_pars();
5255 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5256 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5257 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5258 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5259 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5260 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5261 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5262 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005263 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005264}
5265
5266/* Allow FR and HR, but prefer FR */
5267private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5268 g_pars := f_gen_test_hdlr_pars();
5269 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5270 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5271 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5272 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5273 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5274 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5275 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5276 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005277 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005278}
5279
5280/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5281 * HR, which is the prefered type, is selected. */
5282testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5283 var MSC_ConnHdlr vc_conn;
5284 f_init(1, true);
5285 f_sleep(1.0);
5286 f_enable_all_tch();
5287 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5288 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005289 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005290}
5291
5292/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5293 * FR, which is the prefered type, is selected. */
5294testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5295 var MSC_ConnHdlr vc_conn;
5296 f_init(1, true);
5297 f_sleep(1.0);
5298 f_enable_all_tch();
5299 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5300 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005301 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005302}
5303
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005304/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5305private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5306 g_pars := f_gen_test_hdlr_pars();
5307 g_pars.ra := '02'O; /* RA containing reason=LU */
5308
5309 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5310 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5311 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5312 var template uint3_t tsc := ?;
5313
5314 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5315 f_create_bssmap_exp(l3_enc);
5316 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5317 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5318
5319 /* we should now have a COMPL_L3 at the MSC */
5320 timer T := 10.0;
5321 T.start;
5322 alt {
5323 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5324 [] T.timeout {
5325 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5326 }
5327 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005328
5329 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005330}
5331testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5332 var MSC_ConnHdlr vc_conn;
5333 f_init(1, true);
5334 f_sleep(1.0);
5335 f_disable_all_sdcch();
5336 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5337 vc_conn.done;
5338 f_enable_all_sdcch();
5339 f_shutdown_helper();
5340}
5341
5342/* Request a signalling channel with all SDCCH exhausted, it is
5343 expected that no TCH will be selected for signalling and assigment will fail
5344 because it's dictated by VTY config */
5345testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5346 var RSL_Message rsl_unused, rsl_msg;
5347 var GsmRrMessage rr;
5348 f_init(1, false);
5349 f_sleep(1.0);
5350 f_vty_allow_tch_for_signalling(false, 0);
5351 f_disable_all_sdcch();
5352
5353 /* RA containing reason=LU */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005354 f_ipa_tx(ts_RSL_CHAN_RQD('02'O, 2342));
5355 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005356 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5357 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5358 setverdict(fail, "Expected reject");
5359 }
5360
5361 f_vty_allow_tch_for_signalling(true, 0);
5362 f_enable_all_sdcch();
5363 f_shutdown_helper();
5364}
5365
5366/* Request a voice channel with all SDCCH exhausted, it is
5367 * expected that TCH channel will be allocated since the VTY option is only
5368 * aimed at signalling requests */
5369private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5370 g_pars := f_gen_test_hdlr_pars();
5371 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5372
5373 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5374 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5375 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5376 var template uint3_t tsc := ?;
5377
5378 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5379 f_create_bssmap_exp(l3_enc);
5380 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5381 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5382
5383 /* we should now have a COMPL_L3 at the MSC */
5384 timer T := 10.0;
5385 T.start;
5386 alt {
5387 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5388 [] T.timeout {
5389 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5390 }
5391 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005392 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005393}
5394testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5395 var MSC_ConnHdlr vc_conn;
5396 f_init(1, true);
5397 f_sleep(1.0);
5398 f_vty_allow_tch_for_signalling(false, 0);
5399 f_disable_all_sdcch();
5400
5401 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5402 vc_conn.done;
5403
5404 f_vty_allow_tch_for_signalling(true, 0);
5405 f_enable_all_sdcch();
5406 f_shutdown_helper();
5407}
5408
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005409/* Test Osmux setup BSC<->MSC */
5410testcase TC_assignment_osmux_cn() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005411 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5412 var MSC_ConnHdlr vc_conn;
5413
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005414 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5415 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5416 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiyb9bf00f2022-09-14 15:35:37 +07005417 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02005418 pars.use_osmux_cn := true;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005419
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02005420 g_osmux_enabled_cn := true;
5421 f_init(1, true);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005422 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005423 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005424
5425 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5426 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005427
5428 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005429 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005430}
5431
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005432/* Test Osmux setup BTS<->BSC */
5433testcase TC_assignment_osmux_bts() runs on test_CT {
5434 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5435 var MSC_ConnHdlr vc_conn;
5436
5437 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5438 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5439 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005440 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005441 pars.use_osmux_bts := true;
5442
5443 g_osmux_enabled_bts := true;
5444 f_init(1, true);
5445 f_sleep(1.0);
5446 f_vty_amr_start_mode_set(false, "1");
5447
5448 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5449 vc_conn.done;
5450
5451 f_vty_amr_start_mode_restore(false);
5452 f_shutdown_helper();
5453}
5454
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +02005455/* Test non-AMR codecs still work fine as RTP when Osmux is enabled BTS<->BSC<->MSC */
5456testcase TC_assignment_codec_hr_osmux_on() runs on test_CT {
5457 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5458 var MSC_ConnHdlr vc_conn;
5459
5460 g_osmux_enabled_cn := true;
5461 g_osmux_enabled_bts := true;
5462 f_init(1, true);
5463 f_sleep(1.0);
5464 f_ctrs_bsc_and_bts_assignment_init(1);
5465
5466 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5467 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5468 vc_conn.done;
5469
5470 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
5471 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
5472 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
5473 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
5474 f_ctrs_bts_verify();
5475
5476 f_shutdown_helper();
5477}
5478
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005479/* Test Osmux setup BTS<->BSC<->MSC */
5480testcase TC_assignment_osmux() runs on test_CT {
5481 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5482 var MSC_ConnHdlr vc_conn;
5483
5484 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5485 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5486 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005487 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005488 pars.use_osmux_cn := true;
5489 pars.use_osmux_bts := true;
5490
5491 g_osmux_enabled_cn := true;
5492 g_osmux_enabled_bts := true;
5493 f_init(1, true);
5494 f_sleep(1.0);
5495 f_vty_amr_start_mode_set(false, "1");
5496
5497 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5498 vc_conn.done;
5499
5500 f_vty_amr_start_mode_restore(false);
5501 f_shutdown_helper();
5502}
5503
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005504/* test the procedure of the MSC requesting a Classmark Update:
5505 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5506 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005507private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005508 g_pars := f_gen_test_hdlr_pars();
5509
Harald Weltea0630032018-03-20 21:09:55 +01005510 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005511 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005512
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005513 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5514 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5515
Harald Welte898113b2018-01-31 18:32:21 +01005516 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5517 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5518 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005519
5520 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005521}
5522testcase TC_classmark() runs on test_CT {
5523 var MSC_ConnHdlr vc_conn;
5524 f_init(1, true);
5525 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005526 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005527 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005528 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005529}
5530
Harald Welteeddf0e92020-06-21 19:42:15 +02005531/* Send a CommonID from the simulated MSC and verify that the information is used to
5532 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5533private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5534 g_pars := f_gen_test_hdlr_pars();
5535 f_MscConnHdlr_init_vty();
5536
5537 f_create_chan_and_exp();
5538 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005539
5540 /* Send CommonID */
5541 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5542
5543 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5544 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5545 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5546
5547 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005548
5549 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005550}
5551testcase TC_common_id() runs on test_CT {
5552 var MSC_ConnHdlr vc_conn;
5553 f_init(1, true);
5554 f_sleep(1.0);
5555 vc_conn := f_start_handler(refers(f_tc_common_id));
5556 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005557 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005558}
5559
Harald Weltee3bd6582018-01-31 22:51:25 +01005560private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005561 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005562 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005563 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005564
Harald Weltee3bd6582018-01-31 22:51:25 +01005565 /* send the single message we want to send */
5566 f_rsl_send_l3(l3);
5567}
5568
5569private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5570 timer T := sec;
5571 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005572 T.start;
5573 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005574 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5575 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005576 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005577 }
5578 [] T.timeout {
5579 setverdict(pass);
5580 }
5581 }
5582}
5583
Harald Weltee3bd6582018-01-31 22:51:25 +01005584/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5585private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5586 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5587 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005588 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005589}
Harald Welte898113b2018-01-31 18:32:21 +01005590testcase TC_unsol_ass_fail() runs on test_CT {
5591 var MSC_ConnHdlr vc_conn;
5592 f_init(1, true);
5593 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005594 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005595 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005596 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005597}
Harald Welte552620d2017-12-16 23:21:36 +01005598
Harald Welteea99a002018-01-31 20:46:43 +01005599
5600/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5601private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005602 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5603 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005604 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005605}
5606testcase TC_unsol_ass_compl() runs on test_CT {
5607 var MSC_ConnHdlr vc_conn;
5608 f_init(1, true);
5609 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005610 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005611 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005612 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005613}
5614
5615
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005616/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5617private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005618 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5619 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005620 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005621}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005622testcase TC_unsol_ho_fail() runs on test_CT {
5623 var MSC_ConnHdlr vc_conn;
5624 f_init(1, true);
5625 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005626 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005627 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005628 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005629}
5630
5631
Harald Weltee3bd6582018-01-31 22:51:25 +01005632/* short message from MS should be ignored */
5633private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005634 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005635 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005636 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005637
5638 /* send short message */
5639 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5640 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005641 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005642}
5643testcase TC_err_82_short_msg() runs on test_CT {
5644 var MSC_ConnHdlr vc_conn;
5645 f_init(1, true);
5646 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005647 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005648 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005649 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005650}
5651
Harald Weltee9e02e42018-01-31 23:36:25 +01005652/* 24.008 8.4 Unknown message must trigger RR STATUS */
5653private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
Andreas Eversberg9ff96e62023-07-25 12:37:42 +02005654 f_est_single_l3(ts_RRM_DTM_ASS_FAIL('00'O));
Harald Weltee9e02e42018-01-31 23:36:25 +01005655 timer T := 3.0
5656 alt {
5657 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5658 setverdict(pass);
5659 }
5660 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005661 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005662 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005663 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005664}
5665testcase TC_err_84_unknown_msg() runs on test_CT {
5666 var MSC_ConnHdlr vc_conn;
5667 f_init(1, true);
5668 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005669 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005670 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005671 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005672}
5673
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005674/***********************************************************************
5675 * Handover
5676 ***********************************************************************/
5677
Harald Welte94e0c342018-04-07 11:33:23 +02005678/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5679private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5680runs on test_CT {
5681 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5682 " timeslot "&int2str(ts_nr)&" ";
5683 f_vty_transceive(BSCVTY, cmd & suffix);
5684}
5685
Harald Welte261af4b2018-02-12 21:20:39 +01005686/* 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 +07005687private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5688 uint8_t bts_nr, uint8_t trx_nr,
5689 in RslChannelNr chan_nr)
5690{
Harald Welte261af4b2018-02-12 21:20:39 +01005691 /* FIXME: resolve those from component-global state */
5692 var integer ts_nr := chan_nr.tn;
5693 var integer ss_nr;
5694 if (ischosen(chan_nr.u.ch0)) {
5695 ss_nr := 0;
5696 } else if (ischosen(chan_nr.u.lm)) {
5697 ss_nr := chan_nr.u.lm.sub_chan;
5698 } else if (ischosen(chan_nr.u.sdcch4)) {
5699 ss_nr := chan_nr.u.sdcch4.sub_chan;
5700 } else if (ischosen(chan_nr.u.sdcch8)) {
5701 ss_nr := chan_nr.u.sdcch8.sub_chan;
5702 } else {
5703 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005704 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005705 }
5706
5707 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5708 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005709 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005710}
5711
Neels Hofmeyr91401012019-07-11 00:42:35 +02005712/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5713 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5714 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5715 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5716 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005717private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5718 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5719{
5720 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005721}
5722
5723/* intra-BSC hand-over between BTS0 and BTS1 */
5724private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005725 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5726 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005727
5728 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5729 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5730
Harald Weltea0630032018-03-20 21:09:55 +01005731 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005732 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005733
5734 var HandoverState hs := {
5735 rr_ho_cmpl_seen := false,
5736 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005737 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005738 expect_target_tsc := c_BtsParams[1].tsc
Harald Welte261af4b2018-02-12 21:20:39 +01005739 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005740 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005741 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005742 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5743 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005744
5745 /* From the MGW perspective, a handover is is characterized by
5746 * performing one MDCX operation with the MGW. So we expect to see
5747 * one more MDCX during handover. */
5748 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5749
Harald Welte261af4b2018-02-12 21:20:39 +01005750 alt {
5751 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005752 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005753
Philipp Maier4dae0652018-11-12 12:03:26 +01005754 /* Since this is an internal handover we expect the BSC to inform the
5755 * MSC about the event */
5756 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5757
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005758 /* Check the amount of MGCP transactions is still consistant with the
5759 * test expectation */
5760 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005761
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005762 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5763
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005764 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5765 * 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 +02005766 f_verify_encr_info(chan_act);
5767
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005768 f_chan_act_verify_tsc(chan_act, c_BtsParams[1].tsc);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005769
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005770 f_perform_clear(RSL1, RSL1_PROC);
5771
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005772 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005773}
5774
5775testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005776 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005777 var MSC_ConnHdlr vc_conn;
5778 f_init(2, true);
5779 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005780
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005781 pars.expect_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005782
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005783 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005784
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005785 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005786 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005787
5788 /* from f_establish_fully() */
5789 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5790 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5791 /* from handover */
5792 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5793 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5794 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5795 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005796 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5797 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005798 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005799 f_shutdown_helper(ho := true);
Harald Welte261af4b2018-02-12 21:20:39 +01005800}
Harald Weltee9e02e42018-01-31 23:36:25 +01005801
Oliver Smith7eabd312021-07-12 14:18:56 +02005802function 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 +02005803 var MSC_ConnHdlr vc_conn;
5804 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5805 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5806
5807 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005808 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005809 f_sleep(1.0);
5810
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005811 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005812
5813 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5814 vc_conn.done;
5815
5816 /* from f_establish_fully() */
5817 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5818 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5819 /* from handover */
5820 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5821 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5822 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5823 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005824 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5825 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005826 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005827 f_vty_encryption_a5_reset();
Oliver Smith39f53072022-10-27 14:44:04 +02005828 f_shutdown_helper(ho := true);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005829}
5830
5831testcase TC_ho_int_a5_0() runs on test_CT {
5832 f_tc_ho_int_a5('01'O);
5833}
5834
5835testcase TC_ho_int_a5_1() runs on test_CT {
5836 f_tc_ho_int_a5('02'O);
5837}
5838
5839testcase TC_ho_int_a5_3() runs on test_CT {
5840 f_tc_ho_int_a5('08'O);
5841}
5842
5843testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005844 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005845}
5846
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005847/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5848private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5849 g_pars := f_gen_test_hdlr_pars();
5850 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5851 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005852
5853 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5854 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5855
5856 f_establish_fully(ass_cmd, exp_compl);
5857 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5858
5859 var HandoverState hs := {
5860 rr_ho_cmpl_seen := false,
5861 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005862 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005863 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005864 };
5865 /* issue hand-over command on VTY */
5866 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5867 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5868 f_rslem_suspend(RSL1_PROC);
5869
5870 /* From the MGW perspective, a handover is is characterized by
5871 * performing one MDCX operation with the MGW. So we expect to see
5872 * one more MDCX during handover. */
5873 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5874
5875 var RSL_Message rsl;
5876 var PDU_ML3_NW_MS l3;
5877 var RslChannelNr new_chan_nr;
5878 var GsmArfcn arfcn;
5879 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5880 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5881 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5882 setverdict(fail, "Expected handoverCommand");
5883 mtc.stop;
5884 }
5885 }
5886 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5887 new_chan_nr, arfcn);
5888
5889 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5890
5891 /* resume processing of RSL DChan messages, which was temporarily suspended
5892 * before performing a hand-over */
5893 f_rslem_resume(RSL1_PROC);
5894 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5895
5896 f_sleep(1.0);
5897
5898 /* Handover fails because no HANDO DET appears on the new lchan,
5899 * and the old lchan reports a Radio Link Failure. */
5900 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5901
5902 var PDU_BSSAP rx_clear_request;
5903 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5904 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5905 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5906
5907 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5908
5909 var MgcpCommand mgcp;
5910 interleave {
5911 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5912 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005913 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005914 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005915 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005916 }
5917 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005918 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005919 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005920 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005921 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005922 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5923 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5924 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005925 }
5926
5927 f_sleep(0.5);
5928 setverdict(pass);
5929}
5930testcase TC_ho_int_radio_link_failure() runs on test_CT {
5931 var MSC_ConnHdlr vc_conn;
5932 f_init(2, true);
5933 f_sleep(1.0);
5934
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005935 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005936
5937 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5938 vc_conn.done;
5939
5940 /* from f_establish_fully() */
5941 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5942 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5943 /* from handover */
5944 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5945 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5946 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5947 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005948 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5949 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005950 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005951 f_shutdown_helper(ho := true);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005952}
5953
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005954/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005955private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005956 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005957 var template MgcpResponse mgcp_resp;
5958 var MGCP_RecvFrom mrf;
5959 var template MgcpMessage msg_resp;
5960 var template MgcpMessage msg_dlcx := {
5961 command := tr_DLCX()
5962 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005963
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005964 if (g_pars.aoip) {
5965 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005966 log("Got first DLCX: ", mgcp);
5967 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005968 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005969
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005970 MGCP.receive(tr_DLCX()) -> value mgcp {
5971 log("Got second DLCX: ", mgcp);
5972 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5973 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005974 } else {
5975 /* For SCCPLite, BSC doesn't handle the MSC-side */
5976 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5977 log("Got first DLCX: ", mrf.msg.command);
5978 msg_resp := {
5979 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5980 }
5981 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5982 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005983 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005984}
5985
Oliver Smithc9a5f532022-10-21 11:32:23 +02005986private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit,
5987 boolean skip_meas_rep := false) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005988
Oliver Smithc9a5f532022-10-21 11:32:23 +02005989 if (not skip_meas_rep) {
5990 var NcellReports neighbor_rep := {
5991 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5992 };
5993 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5994 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5995 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005996
Oliver Smithc9a5f532022-10-21 11:32:23 +02005997 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
5998 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005999
6000 f_sleep(0.5);
6001 /* The MSC negotiates Handover Request and Handover Request Ack with
6002 * the other BSS and comes back with a BSSMAP Handover Command
6003 * containing an RR Handover Command coming from the target BSS... */
6004
6005 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6006 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6007 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6008 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6009 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6010
6011 /* expect the Handover Command to go out on RR */
6012 var RSL_Message rsl_ho_cmd
6013 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6014 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6015 var RSL_IE_Body rsl_ho_cmd_l3;
6016 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6017 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6018 setverdict(fail);
6019 } else {
6020 log("Found L3 Info: ", rsl_ho_cmd_l3);
6021 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6022 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6023 setverdict(fail);
6024 } else {
6025 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6026 setverdict(pass);
6027 }
6028 }
6029
6030 /* When the other BSS has reported a completed handover, this side is
6031 * torn down. */
6032
6033 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
6034 var BssmapCause cause := enum2int(cause_val);
6035 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6036
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006037 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02006038
6039 interleave {
6040 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
6041 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
6042 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006043 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
6044 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
6045 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02006046 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006047 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006048}
6049
6050private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
6051 g_pars := f_gen_test_hdlr_pars();
6052 var PDU_BSSAP ass_req := f_gen_ass_req();
6053 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6054 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6055 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6056 f_establish_fully(ass_req, exp_compl);
6057
6058 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006059}
6060testcase TC_ho_out_of_this_bsc() runs on test_CT {
6061 var MSC_ConnHdlr vc_conn;
6062
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01006063 f_init_vty();
6064 f_bts_0_cfg(BSCVTY,
6065 {"neighbor-list mode automatic",
6066 "handover 1",
6067 "handover algorithm 2",
6068 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006069 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01006070 "neighbor lac 99 arfcn 123 bsic any"});
6071 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6072
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006073 f_init(1, true);
6074 f_sleep(1.0);
6075
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006076 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006077
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006078 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
6079 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006080
6081 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6082 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6083 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6084 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6085 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6086 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
6087 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006088 f_shutdown_helper(ho := true);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006089}
6090
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006091private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6092 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07006093 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07006094 octetstring l3 := '0123456789'O)
6095runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02006096 /* The old lchan and conn should still be active. See that arbitrary L3
6097 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006098 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02006099 var template PDU_BSSAP exp_data := {
6100 discriminator := '1'B,
6101 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07006102 dlci := dlci,
6103 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02006104 pdu := {
6105 dtap := l3
6106 }
6107 };
6108 BSSAP.receive(exp_data);
6109 setverdict(pass);
6110}
6111
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006112private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6113 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006114 template (value) OCT1 dlci := '00'O,
6115 octetstring l3 := '0123456789'O)
6116runs on MSC_ConnHdlr {
6117 BSSAP.send(PDU_BSSAP:{
6118 discriminator := '1'B,
6119 spare := '0000000'B,
6120 dlci := dlci,
6121 lengthIndicator := lengthof(l3),
6122 pdu := {
6123 dtap := l3
6124 }
6125 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006126 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006127 setverdict(pass);
6128}
6129
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006130/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
6131 * simply never sends a BSSMAP Handover Command. */
6132private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006133 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006134
6135 var PDU_BSSAP ass_req := f_gen_ass_req();
6136 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6137 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6138 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6139 f_establish_fully(ass_req, exp_compl);
6140
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006141 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006142 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6143
6144 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6145
6146 /* osmo-bsc should time out 10 seconds after the handover started.
6147 * Let's give it a bit extra. */
6148 f_sleep(15.0);
6149
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006150 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006151 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006152 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006153}
6154testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
6155 var MSC_ConnHdlr vc_conn;
6156
6157 f_init(1, true);
6158 f_sleep(1.0);
6159
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006160 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006161
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006162 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
6163 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006164
6165 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6166 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6167 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6168 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6169 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6170 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6171 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006172 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006173}
6174
6175/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
6176 * RR Handover Failure. */
6177private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006178 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006179
6180 var PDU_BSSAP ass_req := f_gen_ass_req();
6181 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6182 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6183 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6184 f_establish_fully(ass_req, exp_compl);
6185
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006186 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006187 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6188
6189 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6190
6191 f_sleep(0.5);
6192 /* The MSC negotiates Handover Request and Handover Request Ack with
6193 * the other BSS and comes back with a BSSMAP Handover Command
6194 * containing an RR Handover Command coming from the target BSS... */
6195
6196 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6197 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6198 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6199 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6200 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6201
6202 /* expect the Handover Command to go out on RR */
6203 var RSL_Message rsl_ho_cmd
6204 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6205 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6206 var RSL_IE_Body rsl_ho_cmd_l3;
6207 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6208 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6209 setverdict(fail);
6210 } else {
6211 log("Found L3 Info: ", rsl_ho_cmd_l3);
6212 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6213 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6214 setverdict(fail);
6215 } else {
6216 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6217 setverdict(pass);
6218 }
6219 }
6220
6221 f_sleep(0.2);
6222 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6223
6224 /* Should tell the MSC about the failure */
6225 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6226
6227 f_sleep(1.0);
6228
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006229 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006230 f_sleep(1.0);
6231
6232 setverdict(pass);
6233 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006234 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006235}
6236testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
6237 var MSC_ConnHdlr vc_conn;
6238
6239 f_init(1, true);
6240 f_sleep(1.0);
6241
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006242 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006243
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006244 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
6245 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006246
6247 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6248 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6249 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6250 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6251 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6252 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
6253 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006254 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006255}
6256
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006257/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
6258 * (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 +02006259 * and the lchan is released. */
6260private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006261 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006262
6263 var PDU_BSSAP ass_req := f_gen_ass_req();
6264 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6265 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6266 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6267 f_establish_fully(ass_req, exp_compl);
6268
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006269 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006270 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6271
6272 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6273
6274 f_sleep(0.5);
6275 /* The MSC negotiates Handover Request and Handover Request Ack with
6276 * the other BSS and comes back with a BSSMAP Handover Command
6277 * containing an RR Handover Command coming from the target BSS... */
6278
6279 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6280 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6281 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6282 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6283 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6284
6285 /* expect the Handover Command to go out on RR */
6286 var RSL_Message rsl_ho_cmd
6287 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6288 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6289 var RSL_IE_Body rsl_ho_cmd_l3;
6290 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6291 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6292 setverdict(fail);
6293 } else {
6294 log("Found L3 Info: ", rsl_ho_cmd_l3);
6295 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6296 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6297 setverdict(fail);
6298 } else {
6299 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6300 setverdict(pass);
6301 }
6302 }
6303
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006304 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6305 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6306 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006307
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006308 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006309 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6310 log("Got BSSMAP Clear Request");
6311 /* Instruct BSC to clear channel */
6312 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6313 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6314
6315 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006316 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006317 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6318 log("Got Deact SACCH");
6319 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006320 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006321 log("Got RR Release");
6322 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006323 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006324 log("Got RF Chan Rel");
6325 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006326 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006327 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006328 }
6329
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006330 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006331 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006332 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006333
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006334 setverdict(pass);
6335 f_sleep(1.0);
6336}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006337testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006338 var MSC_ConnHdlr vc_conn;
6339
6340 f_init(1, true);
6341 f_sleep(1.0);
6342
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006343 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006344
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006345 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006346 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006347
6348 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6349 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6350 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6351 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6352 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6353 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6354 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006355 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006356}
6357
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006358private 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 +01006359 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006360 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6361 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6362 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6363 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6364 * before we get started. */
6365 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6366 f_rslem_register(0, new_chan_nr);
6367 g_chan_nr := new_chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06006368 var uint3_t expect_target_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006369 f_sleep(1.0);
6370
6371 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6372 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006373 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006374
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006375 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6376 cell_id_source := g_pars.cell_id_source,
6377 oldToNewBSSIEs := oldToNewBSSIEs,
6378 enc := g_pars.encr);
6379 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6380 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6381 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6382 } else {
6383 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6384 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6385 BSSAP.send(ho_req);
6386 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006387
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006388 alt {
6389 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6390 if (g_pars.expect_ho_fail) {
6391 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6392 "Expected Handover Request to fail, but got Handover Request Ack")
6393 }
6394 }
6395 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6396 if (not g_pars.expect_ho_fail) {
6397 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6398 "Expected Handover Request to succeed, but got Handover Failure")
6399 }
6400 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6401 // For now just accept any cause.
6402 BSSAP.receive(tr_BSSMAP_ClearRequest);
6403 setverdict(pass);
6404 return;
6405 }
6406 }
6407
Oliver Smith7a8594a2023-02-13 14:30:49 +01006408 if (g_pars.expect_ho_fail_lchan_est) {
6409 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6410 setverdict(pass);
Oliver Smitha1cbec52023-02-21 12:44:12 +01006411
6412 /* When we let MGCP MDCX run into a timeout, it's still in the
6413 * queue and additionally after BSSAP HandoverFailure, two DLCX
Oliver Smith30eb8822023-03-06 12:31:53 +01006414 * get sent (for AoIP, for SCCPlite one DLCX). */
Oliver Smitha1cbec52023-02-21 12:44:12 +01006415 if (g_pars.ignore_mgw_mdcx) {
Oliver Smith30eb8822023-03-06 12:31:53 +01006416 if (g_pars.aoip) {
6417 MGCP.receive(tr_MDCX);
6418 MGCP.receive(tr_DLCX);
6419 MGCP.receive(tr_DLCX);
6420 } else {
6421 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any({command := tr_MDCX}));
6422 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any({command := tr_DLCX}));
6423 }
Oliver Smitha1cbec52023-02-21 12:44:12 +01006424 }
Oliver Smith7a8594a2023-02-13 14:30:49 +01006425 return;
6426 }
6427
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006428 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6429
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006430 /* we're sure that the channel activation is done now, verify the parameters in it */
6431 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6432 f_verify_encr_info(chan_act);
6433 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006434
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006435 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6436 if (not g_pars.aoip) {
6437 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6438 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6439 }
6440 /* TODO: check actual codecs? */
6441 } else {
6442 if (g_pars.aoip) {
6443 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6444 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6445 }
6446 }
6447
6448 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6449 if (not g_pars.aoip) {
6450 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6451 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6452 }
6453 /* TODO: check actual codec? */
6454 } else {
6455 if (g_pars.aoip) {
6456 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6457 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6458 }
6459 }
6460
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006461 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006462 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6463 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6464 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6465 log("L3 Info in HO Request Ack is ", ho_command);
6466
6467 var GsmArfcn arfcn;
6468 var RslChannelNr actual_new_chan_nr;
6469 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6470 actual_new_chan_nr, arfcn);
6471
6472 if (actual_new_chan_nr != new_chan_nr) {
6473 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6474 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6475 setverdict(fail);
6476 return;
6477 }
6478 log("Handover Command chan_nr is", actual_new_chan_nr);
6479
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006480 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6481 if (not match(got_tsc, expect_target_tsc)) {
6482 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6483 expect_target_tsc, " got ", got_tsc);
6484 mtc.stop;
6485 } else {
6486 log("handoverCommand: verified TSC = ", got_tsc);
6487 }
6488
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006489 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6490 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6491 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6492 var template (present) CipherModeSetting_TV tr_cms := {
6493 sC := '0'B, /* no ciphering by default */
6494 algorithmIdentifier := '000'B,
6495 elementIdentifier := ?
6496 };
6497 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6498 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6499 tr_cms.sC := '1'B;
6500 }
6501 if (not match(cms, tr_cms)) {
6502 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6503 cms, ", expected: ", tr_cms);
6504 }
6505 } else {
6506 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6507 }
6508
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006509 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6510 * tells the MS to handover to the new lchan. Here comes the new MS on
6511 * the new lchan with a Handover RACH: */
6512
6513 /* send handover detect */
6514
6515 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6516
6517 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6518
6519 /* send handover complete over the new channel */
6520
6521 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6522 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6523 enc_PDU_ML3_MS_NW(l3_tx)));
6524
6525 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006526 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006527 setverdict(pass);
6528}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006529
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006530private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006531 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006532 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6533 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6534 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006535 }
6536 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006537 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006538 } else {
6539 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006540 }
6541 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006542 if (g_pars.expect_ho_fail) {
6543 f_perform_clear_no_lchan();
Oliver Smith7a8594a2023-02-13 14:30:49 +01006544 } else if (g_pars.expect_ho_fail_lchan_est) {
6545 BSSAP.receive(tr_BSSMAP_ClearRequest);
6546 f_perform_clear_no_lchan();
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006547 } else {
6548 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6549 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006550 setverdict(pass);
6551}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006552function 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 +01006553 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006554
6555 f_init(1, true);
6556 f_sleep(1.0);
6557
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006558 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006559 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006560
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006561 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6562 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006563
6564 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6565 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006566
6567 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006568 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006569 if (pars.expect_ho_fail) {
6570 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6571 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
Oliver Smith7a8594a2023-02-13 14:30:49 +01006572 } else if (pars.expect_ho_fail_lchan_est) {
6573 f_ctrs_bsc_and_bts_add(0, "handover:error");
6574 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006575 } else {
6576 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6577 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6578 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006579 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006580
6581 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006582}
6583
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006584testcase TC_ho_into_this_bsc() runs on test_CT {
6585 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6586 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006587 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006588}
6589
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006590function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6591 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006592 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006593 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006594 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006595 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Oliver Smith39f53072022-10-27 14:44:04 +02006596 f_shutdown_helper(ho := true);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006597}
6598
6599testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006600 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006601}
6602
6603testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006604 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006605}
6606
6607testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006608 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006609}
6610
6611testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006612 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006613}
6614
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006615/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6616 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6617 *
6618 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6619 * omitted.
6620 *
6621 * Related: SYS#5839
6622 */
6623testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6624 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6625}
6626
6627testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6628 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6629}
6630
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006631/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6632testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6633 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6634 expect_fail := true); // 0x18 = A5/3 and A5/4
6635}
6636
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006637testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6638 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6639 pars.host_aoip_tla := "::6";
6640 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006641 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006642}
6643
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006644/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006645 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006646 channel is later released (RR CHannel Release), should trigger inclusion of
6647 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6648 neighbors. */
6649testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6650 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6651 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006652 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006653 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006654
6655 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6656 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6657 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006658 f_shutdown_helper(ho := true);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006659}
6660
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006661/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6662testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6663 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6664 pars.encr := f_encr_params('08'O); /* only A5/3 */
6665 pars.last_used_eutran_plmn := '323454'O;
6666 pars.exp_fast_return := true;
6667 f_tc_ho_into_this_bsc_main(pars);
6668
6669 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6670 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6671 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006672 f_shutdown_helper(ho := true);
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006673}
6674
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006675/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6676 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6677 list when the channel is released. */
6678testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6679 f_init_vty();
6680 f_vty_allow_srvcc_fast_return(true, 0)
6681
6682 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6683 pars.last_used_eutran_plmn := '323454'O;
6684 pars.exp_fast_return := false;
6685 f_tc_ho_into_this_bsc_main(pars);
6686 f_vty_allow_srvcc_fast_return(false, 0);
6687 f_shutdown_helper();
6688}
6689
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006690/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6691testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6692 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6693 pars.last_used_eutran_plmn := '323454'O;
6694 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6695 f_tc_ho_into_this_bsc_main(pars);
6696
6697 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6698 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6699 f_ctrs_bsc_and_bts_verify();
6700 f_shutdown_helper();
6701}
6702
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006703private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6704 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6705 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6706 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6707 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6708 setverdict(pass);
6709}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006710
6711private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6712 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006713 var MSC_ConnHdlr vc_conn;
6714 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6715
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006716 f_init_vty();
6717 f_bts_0_cfg(BSCVTY,
6718 {"neighbor-list mode automatic",
6719 "handover 1",
6720 "handover algorithm 2",
6721 "handover2 window rxlev averaging 1",
6722 "no neighbors",
6723 "neighbor lac 99 arfcn 123 bsic any"});
6724 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6725
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006726 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006727 if (disable_fast_return) {
6728 f_vty_allow_srvcc_fast_return(true, 0);
6729 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006730 f_sleep(1.0);
6731
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006732 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006733
6734 pars.last_used_eutran_plmn := '323454'O;
6735 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6736 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6737
6738 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6739 vc_conn.done;
6740
6741 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6742 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6743 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6744 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6745 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6746 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006747
6748 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6749 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006750 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006751
6752 if (disable_fast_return) {
6753 f_vty_allow_srvcc_fast_return(false, 0);
6754 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006755 f_shutdown_helper();
6756}
6757
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006758/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6759 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6760 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6761 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6762testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6763 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6764}
6765/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6766 * independently of fast-reture allowed/forbidden in local BTS */
6767testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6768 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6769}
6770
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006771private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6772 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6773 f_rslem_register(0, new_chan_nr);
6774 g_chan_nr := new_chan_nr;
6775 f_sleep(1.0);
6776
6777 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6778 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6779 activate(as_Media());
6780
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006781 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006782 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006783 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006784
6785 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6786
6787 var PDU_BSSAP rx_bssap;
6788 var octetstring ho_command_str;
6789
6790 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6791
6792 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6793 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6794 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6795 log("L3 Info in HO Request Ack is ", ho_command);
6796
6797 var GsmArfcn arfcn;
6798 var RslChannelNr actual_new_chan_nr;
6799 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6800 actual_new_chan_nr, arfcn);
6801
6802 if (actual_new_chan_nr != new_chan_nr) {
6803 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6804 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6805 setverdict(fail);
6806 return;
6807 }
6808 log("Handover Command chan_nr is", actual_new_chan_nr);
6809
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006810 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6811 f_sleep(1.0);
6812
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006813 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6814 * tells the MS to handover to the new lchan. In this case, the MS
6815 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6816 * Handover Failure to the MSC. The procedure according to 3GPP TS
6817 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6818 * BSSMAP Clear Command: */
6819
6820 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6821 var BssmapCause cause := enum2int(cause_val);
6822 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6823
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006824 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006825 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006826 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006827
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006828 setverdict(pass);
6829 f_sleep(1.0);
6830
6831 setverdict(pass);
6832}
6833testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6834 var MSC_ConnHdlr vc_conn;
6835 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6836
6837 f_init(1, true);
6838 f_sleep(1.0);
6839
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006840 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006841
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006842 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6843 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006844
6845 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6846 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006847
6848 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6849 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6850 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6851 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6852 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006853 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006854}
6855
6856private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6857 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6858 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6859 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6860 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6861 * before we get started. */
6862 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6863 f_rslem_register(0, new_chan_nr);
6864 g_chan_nr := new_chan_nr;
6865 f_sleep(1.0);
6866
6867 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6868 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6869 activate(as_Media());
6870
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006871 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006872 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006873 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006874
6875 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6876
6877 var PDU_BSSAP rx_bssap;
6878 var octetstring ho_command_str;
6879
6880 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6881
6882 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6883 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6884 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6885 log("L3 Info in HO Request Ack is ", ho_command);
6886
6887 var GsmArfcn arfcn;
6888 var RslChannelNr actual_new_chan_nr;
6889 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6890 actual_new_chan_nr, arfcn);
6891
6892 if (actual_new_chan_nr != new_chan_nr) {
6893 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6894 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6895 setverdict(fail);
6896 return;
6897 }
6898 log("Handover Command chan_nr is", actual_new_chan_nr);
6899
6900 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6901 * tells the MS to handover to the new lchan. Here comes the new MS on
6902 * the new lchan with a Handover RACH: */
6903
6904 /* send handover detect */
6905
6906 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6907
6908 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6909
6910 /* The MSC chooses to clear the connection now, maybe we got the
6911 * Handover RACH on the new cell but the MS still signaled Handover
6912 * Failure to the old BSS? */
6913
6914 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6915 var BssmapCause cause := enum2int(cause_val);
6916 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6917
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006918 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006919 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006920 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006921
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006922 f_sleep(1.0);
6923}
6924testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6925 var MSC_ConnHdlr vc_conn;
6926 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6927
6928 f_init(1, true);
6929 f_sleep(1.0);
6930
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006931 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006932
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006933 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6934 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006935
6936 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6937 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006938
6939 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6940 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6941 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6942 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6943 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006944 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006945}
6946
6947/* The new BSS's lchan times out before the MSC decides that handover failed. */
6948private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6949 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6950 f_rslem_register(0, new_chan_nr);
6951 g_chan_nr := new_chan_nr;
6952 f_sleep(1.0);
6953
6954 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6955 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Oliver Smith735b47c2023-02-15 16:03:54 +01006956 activate(as_Media());
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006957
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006958 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006959 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006960 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006961
6962 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6963
6964 var PDU_BSSAP rx_bssap;
6965 var octetstring ho_command_str;
6966
6967 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6968
6969 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6970 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6971 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6972 log("L3 Info in HO Request Ack is ", ho_command);
6973
6974 var GsmArfcn arfcn;
6975 var RslChannelNr actual_new_chan_nr;
6976 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6977 actual_new_chan_nr, arfcn);
6978
6979 if (actual_new_chan_nr != new_chan_nr) {
6980 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6981 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6982 setverdict(fail);
6983 return;
6984 }
6985 log("Handover Command chan_nr is", actual_new_chan_nr);
6986
6987 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6988 * tells the MS to handover to the new lchan. But the MS never shows up
6989 * on the new lchan. */
6990
6991 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6992
6993 /* Did osmo-bsc also send a Clear Request? */
6994 timer T := 0.5;
6995 T.start;
6996 alt {
6997 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6998 [] T.timeout { }
6999 }
7000
7001 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
7002 * asked for it, this is a Handover Failure after all). */
7003
7004 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
7005 var BssmapCause cause := enum2int(cause_val);
7006 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
7007
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02007008 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007009 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007010 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007011
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007012 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007013}
7014testcase TC_ho_in_fail_no_detect() runs on test_CT {
7015 var MSC_ConnHdlr vc_conn;
7016 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7017
Oliver Smithd49f46d2023-03-08 12:23:13 +01007018 pars.fail_on_dlcx := false;
7019
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007020 f_init(1, true);
7021 f_sleep(1.0);
7022
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007023 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007024
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007025 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
7026 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007027
7028 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
7029 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007030
7031 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7032 f_ctrs_bsc_and_bts_add(0, "handover:error");
7033 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
7034 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
7035 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007036 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007037}
7038
7039/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
7040private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
7041 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
7042 f_rslem_register(0, new_chan_nr);
7043 g_chan_nr := new_chan_nr;
7044 f_sleep(1.0);
7045
7046 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
7047 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Oliver Smith735b47c2023-02-15 16:03:54 +01007048 activate(as_Media());
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007049
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007050 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007051 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02007052 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007053
7054 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
7055
7056 var PDU_BSSAP rx_bssap;
7057 var octetstring ho_command_str;
7058
7059 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
7060
7061 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
7062 log("Received L3 Info in HO Request Ack: ", ho_command_str);
7063 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
7064 log("L3 Info in HO Request Ack is ", ho_command);
7065
7066 var GsmArfcn arfcn;
7067 var RslChannelNr actual_new_chan_nr;
7068 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
7069 actual_new_chan_nr, arfcn);
7070
7071 if (actual_new_chan_nr != new_chan_nr) {
7072 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
7073 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
7074 setverdict(fail);
7075 return;
7076 }
7077 log("Handover Command chan_nr is", actual_new_chan_nr);
7078
7079 /* Now the MSC forwards the RR Handover Command to the other BSC, which
7080 * tells the MS to handover to the new lchan. But the MS never shows up
7081 * on the new lchan. */
7082
7083 BSSAP.receive(tr_BSSMAP_HandoverFailure);
7084
7085 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007086 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02007087
7088 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007089 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
7090 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
7091 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02007092 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007093 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007094 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02007095
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007096 f_sleep(1.0);
7097}
7098testcase TC_ho_in_fail_no_detect2() runs on test_CT {
7099 var MSC_ConnHdlr vc_conn;
7100 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7101
Oliver Smith735b47c2023-02-15 16:03:54 +01007102 pars.fail_on_dlcx := false;
7103
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007104 f_init(1, true);
7105 f_sleep(1.0);
7106
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007107 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007108
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007109 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
7110 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007111
7112 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
7113 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007114
7115 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7116 f_ctrs_bsc_and_bts_add(0, "handover:error");
7117 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
7118 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
7119 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007120 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01007121}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01007122
Oliver Smith7a8594a2023-02-13 14:30:49 +01007123testcase TC_ho_in_fail_mgw_mdcx_timeout() runs on test_CT {
7124 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7125
7126 pars.ignore_mgw_mdcx := true;
7127 pars.expect_ho_fail_lchan_est := true;
7128
7129 f_tc_ho_into_this_bsc_main(pars);
7130 f_shutdown_helper(ho := true);
7131}
7132
Oliver Smith4eed06f2023-02-15 15:43:19 +01007133testcase TC_ho_in_fail_ipa_crcx_timeout() runs on test_CT {
7134 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7135
7136 pars.ignore_ipa_media := true;
7137 pars.expect_ho_fail_lchan_est := true;
7138 pars.fail_on_dlcx := false;
7139
7140 f_tc_ho_into_this_bsc_main(pars);
7141 f_shutdown_helper(ho := true);
7142}
7143
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01007144/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
7145 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
7146 * empty N-Connect case. */
7147testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
7148 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7149 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
7150 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02007151 f_shutdown_helper(ho := true);
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01007152}
7153
Neels Hofmeyr91401012019-07-11 00:42:35 +02007154type record of charstring Commands;
7155
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007156private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02007157{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007158 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007159 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007160 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007161 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007162 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02007163}
7164
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01007165private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
7166{
7167 f_vty_enter_cfg_cs7_inst(pt, 0);
7168 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
7169 f_vty_transceive(pt, cmds[i]);
7170 }
7171 f_vty_transceive(pt, "end");
7172}
7173
Neels Hofmeyr91401012019-07-11 00:42:35 +02007174private function f_probe_for_handover(charstring log_label,
7175 charstring log_descr,
7176 charstring handover_vty_cmd,
7177 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007178 boolean is_inter_bsc_handover := false,
7179 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02007180runs on MSC_ConnHdlr
7181{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02007182 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
7183 * lchans to be established on bts 1 or bts 2. */
7184 f_rslem_suspend(RSL1_PROC);
7185 f_rslem_suspend(RSL2_PROC);
7186
Neels Hofmeyr91401012019-07-11 00:42:35 +02007187 var RSL_Message rsl;
7188
7189 var charstring log_msg := " (expecting handover)"
7190 if (not expect_handover) {
7191 log_msg := " (expecting NO handover)";
7192 }
7193 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
7194 f_vty_transceive(BSCVTY, handover_vty_cmd);
7195
Neels Hofmeyr91401012019-07-11 00:42:35 +02007196 timer T := 2.0;
7197 T.start;
7198
7199 alt {
7200 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
7201 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
7202 log("Rx L3 from net: ", l3);
7203 if (ischosen(l3.msgs.rrm.handoverCommand)) {
7204 var RslChannelNr new_chan_nr;
7205 var GsmArfcn arfcn;
7206 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
7207 new_chan_nr, arfcn);
7208 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
7209 log(l3.msgs.rrm.handoverCommand);
7210
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007211 /* Verify correct TSC in handoverCommand */
7212 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
7213 if (not match(got_tsc, expect_target_tsc)) {
7214 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
7215 expect_target_tsc, " got ", got_tsc);
7216 mtc.stop;
7217 } else {
7218 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
7219 expect_target_tsc, ")");
7220 }
7221
Neels Hofmeyr91401012019-07-11 00:42:35 +02007222 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
7223 * matter on which BTS it really is, we're not going to follow through an entire handover
7224 * anyway. */
7225 f_rslem_register(0, new_chan_nr, RSL1_PROC);
7226 f_rslem_resume(RSL1_PROC);
7227 f_rslem_register(0, new_chan_nr, RSL2_PROC);
7228 f_rslem_resume(RSL2_PROC);
7229
7230 if (expect_handover and not is_inter_bsc_handover) {
7231 setverdict(pass);
7232 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
7233 } else {
7234 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
7235 & log_label & ": " & log_descr);
7236 }
7237
7238 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
7239 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
7240 * Handover Failure. */
7241 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
7242
7243 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
7244 f_sleep(0.5);
7245 RSL1.clear;
7246 RSL2.clear;
7247 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
7248 break;
7249 } else {
7250 repeat;
7251 }
7252 }
7253 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
7254 if (expect_handover and is_inter_bsc_handover) {
7255 setverdict(pass);
7256 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
7257 } else {
7258 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
7259 & log_label & ": " & log_descr);
7260 }
7261
7262 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
7263
7264 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
7265 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
7266 * setting a short timeout and waiting is the only way. */
7267 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
7268 f_sleep(1.5);
7269 log("f_probe_for_handover(" & log_label & "): ...done");
7270
7271 break;
7272 }
7273 [] T.timeout {
7274 if (expect_handover) {
7275 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
7276 & log_label & ": " & log_descr);
7277 } else {
7278 setverdict(pass);
7279 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
7280 }
7281 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
7282 break;
7283 }
7284 }
7285
7286 f_rslem_resume(RSL1_PROC);
7287 f_rslem_resume(RSL2_PROC);
7288 f_sleep(3.0);
7289 RSL.clear;
7290
7291 log("f_probe_for_handover(" & log_label & "): done clearing");
7292}
7293
7294/* Test the effect of various neighbor configuration scenarios:
7295 *
7296 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
7297 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
7298 */
7299private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
7300 g_pars := f_gen_test_hdlr_pars();
7301 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
7302 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007303
7304 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
7305 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
7306
7307 /* Establish lchan at bts 0 */
7308 f_establish_fully(ass_cmd, exp_compl);
7309
7310 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
7311 f_vty_enter_cfg_network(BSCVTY);
7312 f_vty_transceive(BSCVTY, "timer T7 1");
7313 f_vty_transceive(BSCVTY, "end");
7314}
7315
7316private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
7317 f_tc_ho_neighbor_config_start();
7318
7319 /*
7320 * bts 0 ARFCN 871 BSIC 10
7321 * bts 1 ARFCN 871 BSIC 11
7322 * bts 2 ARFCN 871 BSIC 12
7323 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7324 */
7325
7326 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007327 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007328 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
7329 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007330 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007331
7332 f_probe_for_handover("1.b", "HO to unknown cell does not start",
7333 "handover any to arfcn 13 bsic 39",
7334 false);
7335
7336 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
7337 "handover any to arfcn 871 bsic 12",
7338 false);
7339
7340 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
7341 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007342 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007343
7344 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007345}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007346testcase TC_ho_neighbor_config_1() runs on test_CT {
7347 var MSC_ConnHdlr vc_conn;
7348 f_init(3, true, guard_timeout := 60.0);
7349 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007350 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007351 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7352 vc_conn.done;
7353
7354 /* f_tc_ho_neighbor_config_start() */
7355 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7356 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7357
7358 /* 1.a */
7359 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7360 * handover quickly by sending a Handover Failure message. */
7361 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7362 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7363 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7364 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007365 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7366 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007367
7368 /* 1.b */
7369 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7370 f_ctrs_bsc_and_bts_add(0, "handover:error");
7371
7372 /* 1.c */
7373 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7374 f_ctrs_bsc_and_bts_add(0, "handover:error");
7375
7376 /* 1.d */
7377 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7378 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7379 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7380 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007381 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7382 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007383
7384 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007385 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007386}
7387
Neels Hofmeyr91401012019-07-11 00:42:35 +02007388private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7389 f_tc_ho_neighbor_config_start();
7390
7391 /*
7392 * bts 0 ARFCN 871 BSIC 10
7393 * bts 1 ARFCN 871 BSIC 11
7394 * bts 2 ARFCN 871 BSIC 12
7395 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7396 */
7397
7398 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007399 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007400 f_sleep(0.5);
7401
7402 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7403 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007404 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007405
7406 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7407 "handover any to arfcn 871 bsic 12",
7408 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007409 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007410}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007411testcase TC_ho_neighbor_config_2() runs on test_CT {
7412 var MSC_ConnHdlr vc_conn;
7413 f_init(3, true, guard_timeout := 50.0);
7414 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007415 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007416 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7417 vc_conn.done;
7418
7419 /* f_tc_ho_neighbor_config_start() */
7420 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7421 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7422
7423 /* 2.a */
7424 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7425 * handover quickly by sending a Handover Failure message. */
7426 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7427 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7428 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7429 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007430 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7431 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007432
7433 /* 2.b */
7434 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7435 f_ctrs_bsc_and_bts_add(0, "handover:error");
7436
7437 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007438 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007439}
7440
Neels Hofmeyr91401012019-07-11 00:42:35 +02007441private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7442 f_tc_ho_neighbor_config_start();
7443
7444 /*
7445 * bts 0 ARFCN 871 BSIC 10
7446 * bts 1 ARFCN 871 BSIC 11
7447 * bts 2 ARFCN 871 BSIC 12
7448 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7449 */
7450
7451 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007452 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007453 f_sleep(0.5);
7454
7455 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7456 "handover any to arfcn 871 bsic 11",
7457 false);
7458 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",
7459 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007460 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007461 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007462}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007463testcase TC_ho_neighbor_config_3() runs on test_CT {
7464 var MSC_ConnHdlr vc_conn;
7465 f_init(3, true, guard_timeout := 50.0);
7466 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007467 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007468 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7469 vc_conn.done;
7470
7471 /* f_tc_ho_neighbor_config_start() */
7472 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7473 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7474
7475 /* 3.a */
7476 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7477 f_ctrs_bsc_and_bts_add(0, "handover:error");
7478
7479 /* 3.b */
7480 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7481 * handover quickly by sending a Handover Failure message. */
7482 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7483 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7484 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7485 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007486 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7487 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007488
7489 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007490 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007491}
7492
Neels Hofmeyr91401012019-07-11 00:42:35 +02007493private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7494 f_tc_ho_neighbor_config_start();
7495
7496 /*
7497 * bts 0 ARFCN 871 BSIC 10
7498 * bts 1 ARFCN 871 BSIC 11
7499 * bts 2 ARFCN 871 BSIC 12
7500 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7501 */
7502
7503 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007504 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007505 f_sleep(0.5);
7506
7507 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7508 "handover any to arfcn 871 bsic 11",
7509 false);
7510 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7511 "handover any to arfcn 871 bsic 12",
7512 false);
7513 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7514 "handover any to arfcn 123 bsic 45",
7515 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007516 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007517}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007518testcase TC_ho_neighbor_config_4() runs on test_CT {
7519 var MSC_ConnHdlr vc_conn;
7520 f_init(3, true, guard_timeout := 50.0);
7521 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007522 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007523 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7524 vc_conn.done;
7525
7526 /* f_tc_ho_neighbor_config_start() */
7527 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7528 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7529
7530 /* 4.a */
7531 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7532 f_ctrs_bsc_and_bts_add(0, "handover:error");
7533
7534 /* 4.b */
7535 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7536 f_ctrs_bsc_and_bts_add(0, "handover:error");
7537
7538 /* 4.c */
7539 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7540 * handover quickly by timing out after the Handover Required message */
7541 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7542 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7543 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7544 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7545
7546 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007547 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007548}
7549
Neels Hofmeyr91401012019-07-11 00:42:35 +02007550private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7551 f_tc_ho_neighbor_config_start();
7552
7553 /*
7554 * bts 0 ARFCN 871 BSIC 10
7555 * bts 1 ARFCN 871 BSIC 11
7556 * bts 2 ARFCN 871 BSIC 12
7557 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7558 */
7559
7560 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 +02007561 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007562 f_sleep(0.5);
7563
7564 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7565 "handover any to arfcn 871 bsic 12",
7566 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007567 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007568}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007569testcase TC_ho_neighbor_config_5() runs on test_CT {
7570 var MSC_ConnHdlr vc_conn;
7571 f_init(3, true);
7572 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007573 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007574 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7575 vc_conn.done;
7576
7577 /* f_tc_ho_neighbor_config_start() */
7578 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7579 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7580
7581 /* 5 */
7582 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7583 * handover quickly by timing out after the Handover Required message */
7584 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7585 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7586 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7587 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7588
7589 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007590 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007591}
7592
Neels Hofmeyr91401012019-07-11 00:42:35 +02007593private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7594 f_tc_ho_neighbor_config_start();
7595
7596 /*
7597 * bts 0 ARFCN 871 BSIC 10
7598 * bts 1 ARFCN 871 BSIC 11
7599 * bts 2 ARFCN 871 BSIC 12
7600 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7601 */
7602
7603 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7604 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007605 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007606 f_sleep(0.5);
7607
7608 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7609 "handover any to arfcn 871 bsic 12",
7610 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007611 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007612}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007613testcase TC_ho_neighbor_config_6() runs on test_CT {
7614 var MSC_ConnHdlr vc_conn;
7615 f_init(3, true);
7616 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007617 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007618 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7619 vc_conn.done;
7620
7621 /* f_tc_ho_neighbor_config_start() */
7622 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7623 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7624
7625 /* 6.a */
7626 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7627 * handover quickly by timing out after the Handover Required message */
7628 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7629 f_ctrs_bsc_and_bts_add(0, "handover:error");
7630
7631 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007632 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007633}
7634
Neels Hofmeyr91401012019-07-11 00:42:35 +02007635private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7636 f_tc_ho_neighbor_config_start();
7637
7638 /*
7639 * bts 0 ARFCN 871 BSIC 10
7640 * bts 1 ARFCN 871 BSIC 11
7641 * bts 2 ARFCN 871 BSIC 12
7642 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7643 */
7644
7645 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7646 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007647 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007648 f_sleep(0.5);
7649
7650 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7651 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007652 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007653 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7654 "handover any to arfcn 123 bsic 45",
7655 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007656 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007657}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007658testcase TC_ho_neighbor_config_7() runs on test_CT {
7659 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007660 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007661 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007662 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007663 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7664 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007665
7666 /* f_tc_ho_neighbor_config_start() */
7667 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7668 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7669
7670 /* 7.a */
7671 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7672 * handover quickly by sending a Handover Failure message. */
7673 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7674 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7675 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7676 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007677 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7678 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007679
7680 /* 7.b */
7681 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7682 * handover quickly by timing out after the Handover Required message */
7683 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7684 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7685 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7686 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7687
7688 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007689 f_shutdown_helper(ho := true);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007690}
7691
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007692/* OS#3041: Open and close N connections in a normal fashion, and expect no
7693 * BSSMAP Reset just because of that. */
7694testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7695 var default d;
7696 var integer i;
7697 var DchanTuple dt;
7698
7699 f_init();
7700
7701 /* Wait for initial BSSMAP Reset to pass */
7702 f_sleep(4.0);
7703
7704 d := activate(no_bssmap_reset());
7705
7706 /* Setup up a number of connections and RLSD them again from the MSC
7707 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7708 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007709 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007710 /* Since we're doing a lot of runs, give each one a fresh
7711 * T_guard from the top. */
7712 T_guard.start;
7713
7714 /* Setup a BSSAP connection and clear it right away. This is
7715 * the MSC telling the BSC about a planned release, it's not an
7716 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007717 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007718
7719 /* MSC disconnects (RLSD). */
7720 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7721 }
7722
7723 /* In the buggy behavior, a timeout of 2 seconds happens between above
7724 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7725 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7726 f_sleep(4.0);
7727
7728 deactivate(d);
7729 f_shutdown_helper();
7730}
Harald Welte552620d2017-12-16 23:21:36 +01007731
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007732/* OS#3041: Open and close N connections in a normal fashion, and expect no
7733 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7734 * the MSC. */
7735testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7736 var default d;
7737 var integer i;
7738 var DchanTuple dt;
7739 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007740 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7741 var BssmapCause cause := enum2int(cause_val);
7742
7743 f_init();
7744
7745 /* Wait for initial BSSMAP Reset to pass */
7746 f_sleep(4.0);
7747
7748 d := activate(no_bssmap_reset());
7749
7750 /* Setup up a number of connections and RLSD them again from the MSC
7751 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7752 * Let's do it some more times for good measure. */
7753 for (i := 0; i < 8; i := i+1) {
7754 /* Since we're doing a lot of runs, give each one a fresh
7755 * T_guard from the top. */
7756 T_guard.start;
7757
7758 /* Setup a BSSAP connection and clear it right away. This is
7759 * the MSC telling the BSC about a planned release, it's not an
7760 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007761 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007762
7763 /* Instruct BSC to clear channel */
7764 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7765
7766 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007767 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007768 }
7769
7770 /* In the buggy behavior, a timeout of 2 seconds happens between above
7771 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7772 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7773 f_sleep(4.0);
7774
7775 deactivate(d);
7776 f_shutdown_helper();
7777}
7778
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007779/* OS#3041: Open and close N connections in a normal fashion, and expect no
7780 * BSSMAP Reset just because of that. Close connections from the MS side with a
7781 * Release Ind on RSL. */
7782testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7783 var default d;
7784 var integer i;
7785 var DchanTuple dt;
7786 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007787 var integer j;
7788
7789 f_init();
7790
7791 /* Wait for initial BSSMAP Reset to pass */
7792 f_sleep(4.0);
7793
7794 d := activate(no_bssmap_reset());
7795
7796 /* Setup up a number of connections and RLSD them again from the MSC
7797 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7798 * Let's do it some more times for good measure. */
7799 for (i := 0; i < 8; i := i+1) {
7800 /* Since we're doing a lot of runs, give each one a fresh
7801 * T_guard from the top. */
7802 T_guard.start;
7803
7804 /* Setup a BSSAP connection and clear it right away. This is
7805 * the MSC telling the BSC about a planned release, it's not an
7806 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007807 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007808
7809 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007810 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007811
7812 /* expect Clear Request on MSC side */
7813 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7814
7815 /* Instruct BSC to clear channel */
7816 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7817 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7818
7819 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007820 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007821 }
7822
7823 /* In the buggy behavior, a timeout of 2 seconds happens between above
7824 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7825 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7826 f_sleep(4.0);
7827
7828 deactivate(d);
7829 f_shutdown_helper();
7830}
7831
Harald Welte94e0c342018-04-07 11:33:23 +02007832/***********************************************************************
7833 * IPA style dynamic PDCH
7834 ***********************************************************************/
7835
7836private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7837 template (omit) RSL_Cause nack := omit)
7838runs on test_CT {
7839 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7840 var RSL_Message rsl_unused;
7841 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7842 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7843 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007844 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007845 if (istemplatekind(nack, "omit")) {
7846 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007847 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007848 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007849 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007850 }
7851}
7852
7853private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7854 template (omit) RSL_Cause nack := omit)
7855runs on test_CT {
7856 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7857 var RSL_Message rsl_unused;
7858 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7859 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7860 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007861 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_DEACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007862 if (istemplatekind(nack, "omit")) {
7863 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007864 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007865 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007866 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007867 }
7868}
7869
7870private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7871runs on test_CT return charstring {
7872 var charstring cmd, resp;
7873 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007874 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007875}
7876
7877private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7878 template charstring exp)
7879runs on test_CT {
7880 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7881 if (not match(mode, exp)) {
7882 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007883 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007884 }
7885}
7886
7887private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7888runs on test_CT {
7889 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7890 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7891 f_vty_transceive(BSCVTY, "end");
7892}
7893
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007894
7895private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7896 var integer i;
7897 for (i := 0; i < 8; i := i + 1) {
7898 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7899 }
7900}
7901
Harald Welte94e0c342018-04-07 11:33:23 +02007902private const charstring TCHF_MODE := "TCH/F mode";
7903private const charstring TCHH_MODE := "TCH/H mode";
7904private const charstring PDCH_MODE := "PDCH mode";
7905private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007906private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007907
7908/* Test IPA PDCH activation / deactivation triggered by VTY */
7909testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7910 var RSL_Message rsl_unused;
7911
7912 /* change Timeslot 6 before f_init() starts RSL */
7913 f_init_vty();
7914 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7915 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7916
7917 f_init(1, false);
7918 f_sleep(1.0);
7919
7920 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7921
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007922 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007923 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7924 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007925 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7926 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007927 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007928 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007929 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7930
7931 /* De-activate it via VTY */
7932 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7933 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007934 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007935 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7936
7937 /* re-activate it via VTY */
7938 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7939 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007940 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007941 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7942
7943 /* and finally de-activate it again */
7944 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7945 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007946 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007947 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7948
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007949 /* clean up config */
7950 f_ts_set_chcomb(0, 0, 6, "PDCH");
7951
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007952 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007953}
7954
7955/* Test IPA PDCH activation NACK */
7956testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7957 var RSL_Message rsl_unused;
7958
7959 /* change Timeslot 6 before f_init() starts RSL */
7960 f_init_vty();
7961 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7962 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7963
7964 f_init(1, false);
7965 f_sleep(1.0);
7966
7967 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7968
7969 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7970 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007971 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7972 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007973 f_sleep(1.0);
7974 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7975
7976 /* De-activate it via VTY */
7977 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7978 f_sleep(1.0);
7979 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7980
7981 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7982 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7983 f_sleep(1.0);
7984 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7985
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007986 /* clean up config */
7987 f_ts_set_chcomb(0, 0, 6, "PDCH");
7988
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007989 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007990}
7991
7992
7993/***********************************************************************
7994 * Osmocom style dynamic PDCH
7995 ***********************************************************************/
7996
7997private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7998 template (omit) RSL_Cause nack := omit)
7999runs on test_CT {
8000 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
8001 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02008002 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02008003 /* FIXME: no VTY command to activate Osmocom PDCH !! */
8004 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008005 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT(chan_nr, ?));
Harald Welte94e0c342018-04-07 11:33:23 +02008006 if (istemplatekind(nack, "omit")) {
8007 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008008 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02008009 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008010 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02008011 }
8012}
8013
8014private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
8015 template (omit) RSL_Cause nack := omit)
8016runs on test_CT {
8017 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
8018 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02008019 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02008020 /* FIXME: no VTY command to activate Osmocom PDCH !! */
8021 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008022 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02008023 if (istemplatekind(nack, "omit")) {
8024 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008025 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02008026 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008027 //f_ipa_tx(ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02008028 }
8029}
8030
8031/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
8032testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
8033 var RSL_Message rsl_unused;
8034
8035 /* change Timeslot 6 before f_init() starts RSL */
8036 f_init_vty();
8037 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
8038 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8039
8040 f_init(1, false);
8041 f_sleep(1.0);
8042
8043 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
8044
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02008045 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02008046 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
8047 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008048 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02008049
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008050 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02008051 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02008052 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 +02008053 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
8054
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02008055 /* clean up config */
8056 f_ts_set_chcomb(0, 0, 6, "PDCH");
8057
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008058 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02008059}
8060
8061/* Test Osmocom dyn PDCH activation NACK behavior */
8062testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
8063 var RSL_Message rsl_unused;
8064
8065 /* change Timeslot 6 before f_init() starts RSL */
8066 f_init_vty();
8067 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
8068 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8069
8070 f_init(1, false);
8071 f_sleep(1.0);
8072
8073 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
8074
8075 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
8076 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008077 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02008078
8079 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008080 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte94e0c342018-04-07 11:33:23 +02008081 f_sleep(1.0);
8082 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
8083
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02008084 /* clean up config */
8085 f_ts_set_chcomb(0, 0, 6, "PDCH");
8086
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008087 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02008088}
8089
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008090/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
8091testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
8092 var RSL_Message rsl_unused, rsl_msg;
8093 var DchanTuple dt;
8094 var BSSAP_N_CONNECT_ind rx_c_ind;
8095
8096 /* change Timeslot 6 before f_init() starts RSL */
8097 f_init_vty();
8098 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8099 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8100
8101 f_init(1, false);
8102 f_sleep(1.0);
8103
8104 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8105
8106 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8107 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8108 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008109 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008110
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008111 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008112 f_sleep(1.0);
8113 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8114 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8115
8116 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8117 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008118 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008119 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008120 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008121 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008122 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008123 }
8124
8125 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008126 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8127 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8128 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008129
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008130 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008131 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008132 dt.idx := {0, 0};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008133
8134 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008135 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8136 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008137 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
8138
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008139 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 +02008140 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8141 dt.sccp_conn_id := rx_c_ind.connectionId;
8142 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8143
8144 /* Instruct BSC to clear channel */
8145 var BssmapCause cause := 0;
8146 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008147 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008148
8149 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008150 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8151 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008152 f_sleep(1.0);
8153 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8154
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008155 /* Clean up SDCCH lchans */
8156 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
8157 f_perform_clear_test_ct(sdcch_cleanup[i]);
8158 }
8159
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008160 /* clean up config */
8161 f_ts_set_chcomb(0, 0, 6, "PDCH");
8162
8163 f_shutdown_helper();
8164}
8165
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008166/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
8167testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
8168 var ASP_RSL_Unitdata rsl_ud;
8169 var integer i;
8170 var integer chreq_total, chreq_nochan;
8171
8172 f_init_vty();
8173 for (i := 1; i < 8; i := i + 1) {
8174 if (i == 2) {
8175 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8176 } else {
8177 f_ts_set_chcomb(0, 0, i, "PDCH");
8178 }
8179 }
8180 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8181
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008182 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008183
8184 /* The dyn TS want to activate PDCH mode, ACK that. */
8185 var RslChannelNr chan_nr;
8186 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008187 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
8188 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008189
8190 f_sleep(1.0);
8191
8192 /* Exhaust all dedicated SDCCH lchans.
8193 /* GSM 44.018 Table 9.1.8.2:
8194 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
8195 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008196 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008197 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008198 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 +02008199 }
8200
8201 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008202 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 +02008203 /* Also occupy the seven other SDCCH of the dyn TS */
8204 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008205 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 +01008206 }
8207
8208 /* Clean up SDCCH lchans */
8209 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8210 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008211 }
8212
8213 /* clean up config */
8214 f_ts_reset_chcomb(0);
8215
8216 f_shutdown_helper();
8217}
8218
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008219/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
8220 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
8221 it as TCH directly instead. SYS#5309. */
8222testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
8223 var RSL_Message rsl_unused, rsl_msg;
8224 var DchanTuple dt;
8225 var BSSAP_N_CONNECT_ind rx_c_ind;
8226 var integer i;
8227
8228 /* change Timeslot 6 before f_init() starts RSL */
8229 f_init_vty();
8230 for (i := 1; i < 8; i := i + 1) {
8231 if (i == 6) {
8232 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8233 } else {
8234 f_ts_set_chcomb(0, 0, i, "PDCH");
8235 }
8236 }
8237 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8238
8239 f_init(1, false);
8240 f_sleep(1.0);
8241
8242 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8243
8244 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8245 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8246 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008247 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008248
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008249 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008250 f_sleep(1.0);
8251 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8252 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8253
8254 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8255 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008256 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008257 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008258 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008259 dt := f_est_dchan(ra, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008260 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008261 }
8262
8263 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008264 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
8265 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8266 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008267
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008268 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008269 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008270 dt.idx := {0, 0};
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008271
8272 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008273 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8274 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008275 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
8276
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008277 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 +02008278 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8279 dt.sccp_conn_id := rx_c_ind.connectionId;
8280 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8281
8282 /* Instruct BSC to clear channel */
8283 var BssmapCause cause := 0;
8284 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008285 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008286
8287 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008288 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8289 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008290 f_sleep(1.0);
8291 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8292
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008293 /* Clean up SDCCH lchans */
8294 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8295 f_perform_clear_test_ct(chan_cleanup[i]);
8296 }
8297
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008298 /* clean up config */
8299 f_ts_reset_chcomb(0);
8300 /* TODO: clean up other channels? */
8301
8302 f_shutdown_helper();
8303}
8304
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008305/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
8306testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
8307 var RSL_Message rsl_unused, rsl_msg;
8308 var DchanTuple dt;
8309 var BSSAP_N_CONNECT_ind rx_c_ind;
8310 var GsmRrMessage rr;
8311
8312 /* change Timeslot 6 before f_init() starts RSL */
8313 f_init_vty();
8314 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8315 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8316
8317 f_init(1, false);
8318 f_sleep(1.0);
8319
8320 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8321
8322 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8323 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8324 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008325 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008326
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008327 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008328 f_sleep(1.0);
8329 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8330 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8331
8332 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8333 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008334 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008335 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008336 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008337 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008338 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008339 }
8340
8341 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008342 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8343 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8344 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008345
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008346 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008347 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008348 dt.idx := {0, 0};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008349
8350 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008351 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8352 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008353 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8354 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8355 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8356 }
8357
8358 /* FIXME? Currently the TS stays in state BORKEN: */
8359
8360 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008361 /* rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8362 * f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008363 * f_sleep(1.0);
8364 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8365 */
8366
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008367 /* Clean up SDCCH lchans */
8368 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8369 f_perform_clear_test_ct(chan_cleanup[i]);
8370 }
8371
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008372 /* clean up config */
8373 f_ts_set_chcomb(0, 0, 6, "PDCH");
8374
8375 f_shutdown_helper();
8376}
8377
Stefan Sperling0796a822018-10-05 13:01:39 +02008378testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008379 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008380 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8381 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8382 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008383 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008384}
8385
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008386testcase TC_chopped_ipa_payload() runs on test_CT {
8387 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8388 /* TODO: mp_bsc_ctrl_port does not work yet */};
8389 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8390 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8391 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008392 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008393}
8394
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008395/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8396 the BTS does autonomous MS power control loop */
8397testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8398 var MSC_ConnHdlr vc_conn;
8399 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8400 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8401 pars.exp_ms_power_params := true;
8402
8403 f_init(1, true);
8404 f_sleep(1.0);
8405 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8406 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008407 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008408}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008409
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008410/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8411testcase TC_c0_power_red_mode() runs on test_CT {
8412 f_init(1);
8413
8414 for (var integer red := 6; red >= 0; red := red - 2) {
8415 /* Configure BCCH carrier power reduction mode via the VTY */
8416 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8417
8418 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008419 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008420 chan_nr := t_RslChanNr_BCCH(0),
8421 bs_power := tr_RSL_IE_BS_Power(red / 2));
8422 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008423 var RSL_Message unused := f_exp_ipa_rx(tr_rsl_pdu);
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008424
8425 /* Additionally verify the applied value over the CTRL interface */
8426 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8427 if (cred != int2str(red)) {
8428 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8429 cred, " (expected ", red, ")");
8430 }
8431 }
8432
8433 f_shutdown_helper();
8434}
8435
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008436/***********************************************************************
8437 * MSC Pooling
8438 ***********************************************************************/
8439
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008440template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008441 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 +02008442
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008443private 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 +02008444runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008445 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008446 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008447 f_logp(BSCVTY, "Got RSL RR Release");
8448 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008449 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008450 f_logp(BSCVTY, "Got RSL Deact SACCH");
8451 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008452 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008453 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008454 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8455 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008456 break;
8457 }
8458 }
8459}
8460
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008461private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8462 var MgcpCommand mgcp_cmd;
Oliver Smithab7354b2023-05-08 11:34:30 +02008463 var template MgcpMessage msg_dlcx := {
8464 command := tr_DLCX
8465 }
8466 var MGCP_RecvFrom mrf;
8467
8468 [g_pars.aoip] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008469 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8470 repeat;
8471 }
Oliver Smithab7354b2023-05-08 11:34:30 +02008472
8473 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
8474 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
8475 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
8476 }));
8477 repeat;
8478 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008479}
8480
8481private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8482 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8483 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8484 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8485 repeat;
8486 }
8487}
8488
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008489friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8490 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008491runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008492 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8493 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008494 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008495 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8496 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008497 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008498 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008499 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008500 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008501 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008502 }
8503 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008504 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008505 /* Also drop the SCCP connection */
8506 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8507 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008508 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008509 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008510 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8511 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008512 }
8513 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008514 deactivate(ack_dlcx);
8515 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008516}
8517
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008518friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8519runs on MSC_ConnHdlr {
8520 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8521 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8522 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8523 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8524 interleave {
8525 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8526 f_logp(BSCVTY, "Got RSL Deact SACCH");
8527 }
8528 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8529 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8530 /* Also drop the SCCP connection */
8531 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8532 }
8533 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8534 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8535 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8536 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8537 }
8538 }
8539 deactivate(ack_dlcx);
8540 deactivate(ack_rel_req);
8541}
8542
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008543friend function f_perform_clear_no_lchan()
8544runs on MSC_ConnHdlr {
8545 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8546 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8547 BSSAP.receive(tr_BSSMAP_ClearComplete);
8548 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8549 /* Also drop the SCCP connection */
8550 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8551}
8552
Vadim Yanitskiy65d879d2022-06-23 18:15:39 +07008553friend function f_perform_clear_test_ct(DchanTuple dt)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008554 runs on test_CT
8555{
8556 /* Instruct BSC to clear channel */
8557 var BssmapCause cause := 0;
8558 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008559 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008560}
8561
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008562private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8563 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008564runs on MSC_ConnHdlr {
8565 timer T := 10.0;
8566 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8567
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008568 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008569 f_create_bssmap_exp(l3_enc);
8570
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008571 /* RSL_Emulation.f_chan_est() on rsl_pt:
8572 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008573 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8574 */
8575 var RSL_Message rx_rsl;
8576 var GsmRrMessage rr;
8577
8578 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008579 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008580 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008581 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008582 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8583 */
8584 timer Tt := 10.0;
8585
8586 /* request a channel to be established */
8587 Tt.start;
8588 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008589 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008590 Tt.stop;
8591 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008592 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008593 setverdict(fail, "Unexpected RSL message on DCHAN");
8594 mtc.stop;
8595 }
8596 [] Tt.timeout {
8597 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8598 mtc.stop;
8599 }
8600 }
8601 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8602 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008603 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008604
8605
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008606 if (expect_bssmap_l3) {
8607 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8608 var template PDU_BSSAP exp_l3_compl;
8609 exp_l3_compl := tr_BSSMAP_ComplL3()
8610 if (g_pars.aoip == false) {
8611 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8612 } else {
8613 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8614 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008615
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008616 var PDU_BSSAP bssap;
8617 T.start;
8618 alt {
8619 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8620 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8621 log("rx exp_l3_compl = ", bssap);
8622 }
8623 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8624 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8625 }
8626 [] T.timeout {
8627 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8628 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008629 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008630
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008631 /* start ciphering, if requested */
8632 if (ispresent(g_pars.encr)) {
8633 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008634 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008635 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008636 }
8637
8638 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008639 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008640 }
8641 setverdict(pass);
8642 f_sleep(1.0);
8643}
8644
8645private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8646 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8647 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008648 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008649 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008650 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008651 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008652 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008653 }
8654}
8655
8656/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8657private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8658 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008659 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8660 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02008661 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(ts_MI_IMSI_LV('001010000000003'H)) );
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008662 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 +02008663}
8664testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8665
8666 f_init(1, true);
8667 f_sleep(1.0);
8668 var MSC_ConnHdlr vc_conn;
8669 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008670
8671 f_ctrs_msc_init();
8672
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008673 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8674 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008675
8676 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008677 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008678}
8679
8680/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8681/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8682 * just as well using only RSL. */
8683testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8684
8685 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8686 f_sleep(1.0);
8687
8688 /* Control which MSC gets chosen next by the round-robin, otherwise
8689 * would be randomly affected by which other tests ran before this. */
8690 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8691
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008692 f_ctrs_msc_init();
8693
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008694 var MSC_ConnHdlr vc_conn1;
8695 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8696 pars1.mscpool.rsl_idx := 0;
8697 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8698 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8699 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008700 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008701
8702 var MSC_ConnHdlr vc_conn2;
8703 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8704 pars2.mscpool.rsl_idx := 1;
8705 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8706 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8707 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008708 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008709
8710 /* Test round-robin wrap to the first MSC */
8711 var MSC_ConnHdlr vc_conn3;
8712 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8713 pars3.mscpool.rsl_idx := 2;
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02008714 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(ts_MI_IMSI_LV('001010000000003'H)));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008715 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8716 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008717 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008718 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008719}
8720
8721/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8722 * (configured in osmo-bsc.cfg). */
8723/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8724 * just as well using only RSL. */
8725testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8726
8727 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8728 f_sleep(1.0);
8729
8730 /* Control which MSC gets chosen next by the round-robin, otherwise
8731 * would be randomly affected by which other tests ran before this. */
8732 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8733
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008734 f_ctrs_msc_init();
8735
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008736 var MSC_ConnHdlr vc_conn1;
8737 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8738 pars1.mscpool.rsl_idx := 0;
8739 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8740 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8741 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008742 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008743
8744 var MSC_ConnHdlr vc_conn2;
8745 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8746 pars2.mscpool.rsl_idx := 1;
8747 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8748 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8749 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008750 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008751
8752 /* Test round-robin wrap to the first MSC */
8753 var MSC_ConnHdlr vc_conn3;
8754 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8755 pars3.mscpool.rsl_idx := 2;
8756 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8757 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8758 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008759 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008760 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008761}
8762
8763/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8764 * (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
8765 * NULL-NRI setting is stronger than that. */
8766/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8767 * just as well using only RSL. */
8768testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8769
8770 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8771 f_sleep(1.0);
8772
8773 /* Control which MSC gets chosen next by the round-robin, otherwise
8774 * would be randomly affected by which other tests ran before this. */
8775 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8776
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008777 f_ctrs_msc_init();
8778
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008779 var MSC_ConnHdlr vc_conn1;
8780 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8781 pars1.mscpool.rsl_idx := 0;
8782 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8783 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8784 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008785 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008786
8787 var MSC_ConnHdlr vc_conn2;
8788 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8789 pars2.mscpool.rsl_idx := 1;
8790 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8791 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8792 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008793 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008794
8795 /* Test round-robin wrap to the first MSC */
8796 var MSC_ConnHdlr vc_conn3;
8797 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8798 pars3.mscpool.rsl_idx := 2;
8799 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8800 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8801 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008802 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008803 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008804}
8805
8806/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8807 * assigned to any MSC (configured in osmo-bsc.cfg). */
8808/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8809 * just as well using only RSL. */
8810testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8811
8812 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8813 f_sleep(1.0);
8814
8815 /* Control which MSC gets chosen next by the round-robin, otherwise
8816 * would be randomly affected by which other tests ran before this. */
8817 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8818
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008819 f_ctrs_msc_init();
8820
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008821 var MSC_ConnHdlr vc_conn1;
8822 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8823 pars1.mscpool.rsl_idx := 0;
8824 /* An NRI that is not assigned to any MSC */
8825 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8826 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8827 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008828 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008829
8830 var MSC_ConnHdlr vc_conn2;
8831 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8832 pars2.mscpool.rsl_idx := 1;
8833 /* An NRI that is not assigned to any MSC */
8834 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8835 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8836 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008837 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008838
8839 /* Test round-robin wrap to the first MSC */
8840 var MSC_ConnHdlr vc_conn3;
8841 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8842 pars3.mscpool.rsl_idx := 2;
8843 /* An NRI that is not assigned to any MSC */
8844 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8845 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8846 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008847 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008848 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008849}
8850
8851/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8852 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8853/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8854 * just as well using only RSL. */
8855testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8856
8857 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8858 f_sleep(1.0);
8859
8860 /* Control which MSC gets chosen next by the round-robin, otherwise
8861 * would be randomly affected by which other tests ran before this. */
8862 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8863
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008864 f_ctrs_msc_init();
8865
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008866 var MSC_ConnHdlr vc_conn1;
8867 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8868 pars1.mscpool.rsl_idx := 0;
8869 /* An NRI that is assigned to an unconnected MSC */
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02008870 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(ts_MI_TMSI_NRI_LV(512)));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008871 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8872 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008873 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8874 f_ctrs_msc_add(0, "mscpool:subscr:new");
8875 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008876
8877 var MSC_ConnHdlr vc_conn2;
8878 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8879 pars2.mscpool.rsl_idx := 1;
8880 /* An NRI that is assigned to an unconnected MSC */
8881 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8882 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8883 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008884 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8885 f_ctrs_msc_add(1, "mscpool:subscr:new");
8886 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008887
8888 /* Test round-robin wrap to the first MSC */
8889 var MSC_ConnHdlr vc_conn3;
8890 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8891 pars3.mscpool.rsl_idx := 2;
8892 /* An NRI that is assigned to an unconnected MSC */
8893 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8894 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8895 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008896 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8897 f_ctrs_msc_add(0, "mscpool:subscr:new");
8898 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008899 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008900}
8901
8902/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8903 * osmo-bsc.cfg). */
8904/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8905 * just as well using only RSL. */
8906testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8907
8908 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8909 f_sleep(1.0);
8910
8911 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8912 * this is not using round-robin. */
8913 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8914
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008915 f_ctrs_msc_init();
8916
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008917 var MSC_ConnHdlr vc_conn1;
8918 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8919 pars1.mscpool.rsl_idx := 0;
8920 /* An NRI of the second MSC's range (256-511) */
8921 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8922 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8923 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008924 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008925
8926 var MSC_ConnHdlr vc_conn2;
8927 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8928 pars2.mscpool.rsl_idx := 1;
8929 /* An NRI of the second MSC's range (256-511) */
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02008930 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(ts_MI_TMSI_NRI_LV(260)));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008931 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8932 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008933 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008934
8935 var MSC_ConnHdlr vc_conn3;
8936 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8937 pars3.mscpool.rsl_idx := 2;
8938 /* An NRI of the second MSC's range (256-511) */
8939 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8940 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8941 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008942 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008943 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008944}
8945
8946/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8947 * while a round-robin remains unaffected by that. */
8948/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8949 * just as well using only RSL. */
8950testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8951
8952 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8953 f_sleep(1.0);
8954
8955 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8956 * this is not using round-robin. */
8957 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8958
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008959 f_ctrs_msc_init();
8960
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008961 var MSC_ConnHdlr vc_conn1;
8962 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8963 pars1.mscpool.rsl_idx := 0;
8964 /* An NRI of the third MSC's range (512-767) */
8965 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8966 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8967 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008968 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008969
8970 var MSC_ConnHdlr vc_conn2;
8971 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8972 pars2.mscpool.rsl_idx := 1;
8973 /* An NRI of the third MSC's range (512-767) */
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02008974 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(ts_MI_TMSI_NRI_LV(678)));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008975 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8976 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008977 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008978
8979 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8980 var MSC_ConnHdlr vc_conn3;
8981 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8982 pars3.mscpool.rsl_idx := 2;
8983 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8984 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8985 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008986 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008987 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008988}
8989
8990/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8991/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8992 * just as well using only RSL. */
8993testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8994
8995 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8996 f_sleep(1.0);
8997
8998 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8999 * instead, and hits msc 0. */
9000 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9001
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009002 f_ctrs_msc_init();
9003
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009004 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
9005 var MSC_ConnHdlr vc_conn1;
9006 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9007 pars1.mscpool.rsl_idx := 0;
9008 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
9009 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9010 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009011 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009012
9013 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
9014 var MSC_ConnHdlr vc_conn2;
9015 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
9016 pars2.mscpool.rsl_idx := 1;
9017 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
9018 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9019 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009020 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009021 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009022}
9023
9024/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
9025 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
9026private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
9027 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
9028 //cid_list := { cIl_allInBSS := ''O };
9029 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
9030 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
9031 var BSSAP_N_UNITDATA_req paging;
9032 var hexstring imsi := '001010000000123'H;
9033
9034 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9035
Neels Hofmeyr90f80962020-06-12 16:16:55 +02009036 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009037 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
9038 BSSAP.send(paging);
9039
9040 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
9041 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
9042 * channel number is picked here. */
9043 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
9044 f_rslem_register(0, new_chan_nr);
9045 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
9046 f_rslem_unregister(0, new_chan_nr);
9047
9048 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
9049 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02009050 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(ts_MI_IMSI_LV(imsi)) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009051 f_sleep(1.0);
9052}
9053testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
9054 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
9055 f_sleep(1.0);
9056
9057 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
9058 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
9059 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
9060
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009061 f_ctrs_msc_init();
9062
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009063 var MSC_ConnHdlr vc_conn1;
9064 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9065 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02009066 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
9067 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009068 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
9069 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009070 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009071 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009072}
9073
9074/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
9075 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
9076private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
9077 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
9078 //cid_list := { cIl_allInBSS := ''O };
9079 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
9080 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
9081 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01009082 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009083 var BSSAP_N_UNITDATA_req paging;
9084
9085 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9086
Neels Hofmeyr90f80962020-06-12 16:16:55 +02009087 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009088 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
9089 BSSAP.send(paging);
9090
9091 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
9092 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
9093 * channel number is picked here. */
9094 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
9095 f_rslem_register(0, new_chan_nr);
9096 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
9097 f_rslem_unregister(0, new_chan_nr);
9098
9099 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
9100 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
9101 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02009102 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(ts_MI_TMSI_NRI_LV(nri_v)) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009103 f_sleep(1.0);
9104}
9105testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
9106 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
9107 f_sleep(1.0);
9108
9109 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
9110 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
9111 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
9112
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009113 f_ctrs_msc_init();
9114
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009115 var MSC_ConnHdlr vc_conn1;
9116 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9117 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02009118 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
9119 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009120 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
9121 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009122 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009123 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009124}
9125
9126/* For round-robin, skip an MSC that has 'no allow-attach' set. */
9127/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
9128 * just as well using only RSL. */
9129testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
9130
9131 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9132 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009133 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9134 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009135
9136 /* Control which MSC gets chosen next by the round-robin, otherwise
9137 * would be randomly affected by which other tests ran before this. */
9138 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9139
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009140 f_ctrs_msc_init();
9141
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009142 var MSC_ConnHdlr vc_conn1;
9143 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9144 pars1.mscpool.rsl_idx := 0;
9145 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
9146 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9147 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009148 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009149
9150 var MSC_ConnHdlr vc_conn2;
9151 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
9152 pars2.mscpool.rsl_idx := 1;
9153 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9154 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9155 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009156 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009157
9158 var MSC_ConnHdlr vc_conn3;
9159 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
9160 pars3.mscpool.rsl_idx := 2;
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02009161 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(ts_MI_IMSI_LV('001010000000003'H)));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009162 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9163 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009164 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009165 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009166}
9167
9168/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
9169 * TMSI NRI. */
9170testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
9171
9172 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9173 f_sleep(1.0);
9174
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009175 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9176 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
9177
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009178 /* Control which MSC gets chosen next by the round-robin, otherwise
9179 * would be randomly affected by which other tests ran before this. */
9180 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9181
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009182 f_ctrs_msc_init();
9183
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009184 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
9185 var MSC_ConnHdlr vc_conn1;
9186 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
9187 pars1.mscpool.rsl_idx := 0;
9188 /* An NRI of the second MSC's range (256-511) */
9189 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
9190 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9191 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009192 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009193
9194 var MSC_ConnHdlr vc_conn2;
9195 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
9196 pars2.mscpool.rsl_idx := 1;
9197 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9198 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9199 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009200 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009201
9202 var MSC_ConnHdlr vc_conn3;
9203 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
9204 pars3.mscpool.rsl_idx := 2;
9205 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
9206 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9207 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009208 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009209 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009210}
9211
Neels Hofmeyr2bdc6b62023-04-05 02:45:19 +02009212/* When an MSC point-code gets an SCCP N-PCSTATE saying it is unreachable, immediately mark the MSC as unusable. */
9213testcase TC_mscpool_sccp_n_pcstate_detaches_msc() runs on test_CT {
9214
9215 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
9216 f_sleep(1.0);
9217
9218 /* Control which MSC gets chosen next by the round-robin, otherwise
9219 * would be randomly affected by which other tests ran before this. */
9220 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9221
9222 f_ctrs_msc_init();
9223
9224 var MSC_ConnHdlr vc_conn1;
9225 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9226 pars1.mscpool.rsl_idx := 0;
9227 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
9228 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9229 vc_conn1.done;
9230 f_ctrs_msc_expect(0, "mscpool:subscr:new");
9231
9232 var MSC_ConnHdlr vc_conn2;
9233 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
9234 pars2.mscpool.rsl_idx := 1;
9235 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9236 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9237 vc_conn2.done;
9238 f_ctrs_msc_expect(1, "mscpool:subscr:new");
9239
9240 f_logp(BSCVTY, "disconnecting msc0");
Neels Hofmeyr38632aa2023-04-05 03:50:51 +02009241 f_bssap_idx_disconnect(0);
Neels Hofmeyr2bdc6b62023-04-05 02:45:19 +02009242
9243 /* Now round-robin would wrap to the first MSC, but since the first MSC is disconnected, it wraps around to msc
9244 * 2 again. */
9245 var MSC_ConnHdlr vc_conn3;
9246 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
9247 pars3.mscpool.rsl_idx := 2;
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02009248 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(ts_MI_IMSI_LV('001010000000003'H)));
Neels Hofmeyr2bdc6b62023-04-05 02:45:19 +02009249 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9250 vc_conn3.done;
9251 f_ctrs_msc_expect(1, "mscpool:subscr:new");
9252 f_shutdown_helper();
9253}
9254
Neels Hofmeyr38632aa2023-04-05 03:50:51 +02009255/* When an MSC point-code gets an SCCP N-PCSTATE saying it is now reachable, immediately trigger RESET and bring up the
9256 * MSC. */
9257testcase TC_mscpool_sccp_n_pcstate_attaches_msc() runs on test_CT {
9258
9259 f_init(nr_bts := 3, handler_mode := true, nr_msc := 1);
9260 f_sleep(1.0);
9261
9262 /* Control which MSC gets chosen next by the round-robin, otherwise
9263 * would be randomly affected by which other tests ran before this. */
9264 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9265
9266 f_ctrs_msc_init();
9267
9268 /* There is only one MSC, round robin stays on msc0 */
9269 var MSC_ConnHdlr vc_conn1;
9270 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
9271 pars1.mscpool.rsl_idx := 0;
9272 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('0010100230000001'H)), '00F110'O));
9273 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9274 vc_conn1.done;
9275 f_ctrs_msc_expect(0, "mscpool:subscr:new");
9276
9277 var MSC_ConnHdlr vc_conn2;
9278 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
9279 pars2.mscpool.rsl_idx := 1;
9280 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010023000002'H))));
9281 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9282 vc_conn2.done;
9283 f_ctrs_msc_expect(0, "mscpool:subscr:new");
9284
9285 f_logp(BSCVTY, "connecting msc1");
9286 f_vty_msc_allow_attach(BSCVTY, { true, true });
9287 f_bssap_idx_init(1);
9288 f_sleep(1.0);
9289
9290 /* This time round-robin wraps to the second MSC, because it is now online. */
9291 var MSC_ConnHdlr vc_conn4;
9292 var TestHdlrParams pars4 := f_gen_test_hdlr_pars(bssap_idx := 1);
9293 pars4.mscpool.rsl_idx := 2;
Neels Hofmeyr2bc75892023-04-07 00:00:34 +02009294 pars4.mscpool.l3_info := valueof(ts_PAG_RESP(ts_MI_IMSI_LV('001010023000003'H)));
Neels Hofmeyr38632aa2023-04-05 03:50:51 +02009295 vc_conn4 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars4);
9296 vc_conn4.done;
9297 f_ctrs_msc_expect(1, "mscpool:subscr:new");
9298
9299 f_shutdown_helper();
9300}
9301
Philipp Maier783681c2020-07-16 16:47:06 +02009302/* Allow/Deny emergency calls globally via VTY */
9303private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
9304 f_vty_enter_cfg_msc(BSCVTY, 0);
9305 if (allow) {
9306 f_vty_transceive(BSCVTY, "allow-emergency allow");
9307 } else {
9308 f_vty_transceive(BSCVTY, "allow-emergency deny");
9309 }
9310 f_vty_transceive(BSCVTY, "exit");
9311 f_vty_transceive(BSCVTY, "exit");
9312}
9313
9314/* Allow/Deny emergency calls per BTS via VTY */
9315private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
9316 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9317 if (allow) {
9318 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
9319 } else {
9320 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
9321 }
9322 f_vty_transceive(BSCVTY, "exit");
9323 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00009324 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02009325}
9326
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02009327/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
9328private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
9329 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9330 if (allow) {
9331 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
9332 } else {
9333 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
9334 }
9335 f_vty_transceive(BSCVTY, "exit");
9336 f_vty_transceive(BSCVTY, "exit");
9337 f_vty_transceive(BSCVTY, "exit");
9338}
9339
Pau Espin Pedrol14475352021-07-22 15:48:16 +02009340/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
9341private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
9342 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9343 if (allow) {
9344 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
9345 } else {
9346 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
9347 }
9348 f_vty_transceive(BSCVTY, "exit");
9349 f_vty_transceive(BSCVTY, "exit");
9350 f_vty_transceive(BSCVTY, "exit");
9351}
9352
Pau Espin Pedrol35609792023-01-03 16:56:59 +01009353/* Begin assignment procedure and send an EMERGENCY SETUP (RR) */
Philipp Maier783681c2020-07-16 16:47:06 +02009354private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
9355 var PDU_ML3_MS_NW emerg_setup;
9356 var octetstring emerg_setup_enc;
9357 var RSL_Message emerg_setup_data_ind;
9358
9359 f_establish_fully(omit, omit);
9360
9361 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
9362 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
9363 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
9364
9365 RSL.send(emerg_setup_data_ind);
9366}
9367
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009368/* expect EmergencySetup on BSSAP after calling f_assignment_emerg_setup() */
9369private function f_assignment_emerg_setup_exp_bssap()
9370runs on MSC_ConnHdlr {
Philipp Maier783681c2020-07-16 16:47:06 +02009371 var PDU_BSSAP emerg_setup_data_ind_bssap;
9372 var PDU_ML3_MS_NW emerg_setup;
9373 timer T := 3.0;
9374
Philipp Maier783681c2020-07-16 16:47:06 +02009375 T.start;
9376 alt {
9377 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
9378 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
9379 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
9380 setverdict(fail, "no emergency setup");
9381 }
9382 }
9383 [] BSSAP.receive {
9384 setverdict(fail, "unexpected BSSAP message!");
9385 }
9386 [] T.timeout {
9387 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
9388 }
9389 }
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009390}
9391
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009392private function f_assignment_emerg_setup_voice()
9393runs on MSC_ConnHdlr {
9394 /* Go on with voice call assignment */
9395 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9396 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9397
9398 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
9399 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
9400 * seems a good idea to see how osmo-bsc reacts to this. */
9401 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
9402 elementIdentifier := '0B'O, /* overwritten */
9403 lengthIndicator := 0, /* overwritten */
9404 speechOrDataIndicator := '0001'B, /* speech */
9405 spare1_4 := '0000'B,
9406 channelRateAndType := ChRate_TCHForH_Fpref,
9407 speechId_DataIndicator := 'c2918105'O
9408 };
9409 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
9410 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
9411
9412 f_rslem_dchan_queue_enable();
9413
9414 var ExpectCriteria mgcpcrit := {
9415 connid := omit,
9416 endpoint := omit,
9417 transid := omit
9418 };
9419 f_create_mgcp_expect(mgcpcrit);
9420
9421 BSSAP.send(ass_cmd);
9422
9423 var AssignmentState st := valueof(ts_AssignmentStateInit);
Oliver Smithce2dd692023-04-17 10:25:50 +02009424 st.rtp_stream := true;
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009425 st.is_assignment := false;
9426 alt {
9427 [] as_modify(st);
9428 [] as_Media();
9429 [st.modify_done] BSSAP.receive(exp_compl) {
9430 setverdict(pass);
9431 }
9432 }
9433
9434 /* Voice call carries on ... */
9435 f_sleep(2.0);
9436}
9437
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009438/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
9439 * CALLS are permitted by the BSC config. */
9440private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
9441
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009442 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
9443 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
9444 * another lchan. */
9445 g_pars.ra := f_rnd_ra_emerg();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009446 f_assignment_emerg_setup();
9447 f_assignment_emerg_setup_exp_bssap();
Pau Espin Pedrol14076d32023-01-03 17:07:59 +01009448 f_assignment_emerg_setup_voice();
Philipp Maier783681c2020-07-16 16:47:06 +02009449
9450 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009451 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02009452}
9453
9454/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
9455 * forbidden by the BSC config. */
9456private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
9457 var PDU_BSSAP emerg_setup_data_ind_bssap;
9458 timer T := 3.0;
9459
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +01009460 f_assignment_emerg_setup();
Philipp Maier783681c2020-07-16 16:47:06 +02009461
9462 T.start;
9463 alt {
9464 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9465 setverdict(pass);
9466 }
9467 [] RSL.receive {
9468 setverdict(fail, "unexpected RSL message!");
9469 }
9470 [] T.timeout {
9471 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
9472 }
9473 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009474 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01009475 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02009476}
9477
9478/* EMERGENCY CALL situation #1, allowed globally and by BTS */
9479testcase TC_assignment_emerg_setup_allow() runs on test_CT {
9480 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9481 var MSC_ConnHdlr vc_conn;
9482
9483 f_init(1, true);
9484 f_sleep(1.0);
9485
9486 f_vty_allow_emerg_msc(true);
9487 f_vty_allow_emerg_bts(true, 0);
9488 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9489 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009490 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009491}
9492
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +01009493/* Test MO emergency call using MobileIdentity=IMEI (possible for emergency
9494 * calls from phones without SIM card).
9495 * 3GPP TS 24.008 section 10.5.1.4, OS#5849 */
9496testcase TC_assignment_emerg_setup_allow_imei() runs on test_CT {
9497 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9498 var MSC_ConnHdlr vc_conn;
9499
9500 /* Remove IMSI set by f_gen_test_hdlr_pars(), then IMEI will be used to place the call */
9501 pars.imsi := omit;
9502
9503 f_init(1, true);
9504 f_sleep(1.0);
9505
9506 f_vty_allow_emerg_msc(true);
9507 f_vty_allow_emerg_bts(true, 0);
9508 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9509 vc_conn.done;
9510 f_shutdown_helper();
9511}
9512
Philipp Maier783681c2020-07-16 16:47:06 +02009513/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
9514testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
9515 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9516 var MSC_ConnHdlr vc_conn;
9517
9518 f_init(1, true);
9519 f_sleep(1.0);
9520
9521 f_vty_allow_emerg_msc(false);
9522 f_vty_allow_emerg_bts(true, 0);
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009523 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx): */
9524 pars.ra := f_rnd_ra_emerg();
Philipp Maier783681c2020-07-16 16:47:06 +02009525 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9526 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009527 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009528}
9529
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009530/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS.
9531 * The RACH req (and hence CHAN RQD) indicate other than emergency call.
9532 * Hence BSC only learns about it being an emergency call later during call setup.
9533 * If interested in the ra="emergency call" + deny bts policy case,
9534 * see TC_chan_rqd_emerg_deny.
9535 */
Philipp Maier783681c2020-07-16 16:47:06 +02009536testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9537 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9538 var MSC_ConnHdlr vc_conn;
9539
9540 /* Note: This simulates a spec violation by the MS, correct MS
9541 * implementations would not try to establish an emergency call because
9542 * the system information tells in advance that emergency calls are
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009543 * not allowed */
Philipp Maier783681c2020-07-16 16:47:06 +02009544
9545 f_init(1, true);
9546 f_sleep(1.0);
9547
9548 f_vty_allow_emerg_msc(true);
9549 f_vty_allow_emerg_bts(false, 0);
Pau Espin Pedrol6b869f42023-01-17 12:06:03 +01009550 /* Note: Here we implicitly leave default g_pars.ra which is different than "emergency call" */
Philipp Maier783681c2020-07-16 16:47:06 +02009551 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9552 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009553 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009554}
9555
Philipp Maier82812002020-08-13 18:48:27 +02009556/* Test what happens when an emergency call arrives while all TCH channels are
9557 * busy, the BSC is expected to terminate one call in favor of the incoming
9558 * emergency call */
9559testcase TC_emerg_premption() runs on test_CT {
9560 var ASP_RSL_Unitdata rsl_ud;
9561 var integer i;
9562 var integer chreq_total, chreq_nochan;
9563 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009564 var octetstring l3_payload := gen_l3_valid_payload();
Philipp Maier82812002020-08-13 18:48:27 +02009565
9566 f_init(1);
9567 f_sleep(1.0);
9568
9569 f_vty_allow_emerg_msc(true);
9570 f_vty_allow_emerg_bts(true, 0);
9571
9572 /* Fill up all channels on the BTS */
9573 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9574 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9575 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 +02009576 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009577 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009578 IPA_RSL[0][0].clear;
Philipp Maier82812002020-08-13 18:48:27 +02009579 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9580 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9581
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009582 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9583 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009584 f_ipa_tx(ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009585
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009586 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9587 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009588 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009589 var integer sccp_conn_id := rx_c_ind.connectionId;
9590 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9591
Philipp Maier82812002020-08-13 18:48:27 +02009592 /* Send Channel request for emegergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009593 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier82812002020-08-13 18:48:27 +02009594
9595 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009596 f_expect_chan_rel(first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009597 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009598
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009599 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9600 var BSSAP_N_DATA_ind rx_clear_req;
9601 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9602 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9603 log("XXX ", rx_clear_req);
9604 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9605 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9606 }
9607
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009608 /* Expect the BSC to send activate/assign the channel for the emergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009609 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009610 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9611 setverdict(fail, "different TCH lchan activated than expected");
9612 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009613 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(first_tch, 33));
9614 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009615
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009616 /* complete the BSSMAP Clear to satisfy the conn leak check */
9617 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9618 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9619 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9620 }
9621
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009622 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009623}
9624
9625/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009626private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009627private type record FHParamsTs {
9628 boolean enabled,
9629 uint6_t hsn,
9630 uint6_t maio,
9631 ArfcnList ma
9632};
9633
9634/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009635private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009636 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009637 FHParamsTs ts[8]
9638};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009639
9640/* Randomly generate the hopping parameters for the given timeslot numbers */
9641private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9642runs on test_CT return FHParamsTrx {
9643 var FHParamsTrx fhp;
9644
Philipp Maier798d8952021-10-19 14:43:19 +02009645 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9646 * fall in the GSM900 band. */
9647 fhp.arfcn.arfcn := f_rnd_int(3);
9648 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009649
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009650 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9651 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009652 fhp.ts[tn].enabled := false;
9653 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009654 continue;
9655 }
9656
9657 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009658 fhp.ts[tn].hsn := f_rnd_int(64);
9659 fhp.ts[tn].maio := f_rnd_int(64);
9660 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009661
9662 /* Random Mobile Allocation (hopping channels) */
9663 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9664 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9665 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009666 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009667 }
9668
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009669 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009670 }
9671
9672 log("f_TC_fh_params_gen(): ", fhp);
9673 return fhp;
9674}
9675
9676/* Make sure that the given Channel Description IE matches the hopping configuration */
9677private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9678{
9679 var template (present) ChannelDescription tr_cd;
9680 var template (present) MaioHsn tr_maio_hsn;
9681 var uint3_t tn := cd.chan_nr.tn;
9682
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009683 if (fhp.ts[tn].enabled) {
9684 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009685 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9686 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009687 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009688 }
9689
9690 if (not match(cd, tr_cd)) {
9691 setverdict(fail, "Channel Description IE does not match: ",
9692 cd, " vs expected ", tr_cd);
9693 }
9694}
9695
9696/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9697private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9698 in MobileAllocationLV ma)
9699{
9700 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9701
9702 if (not match(ma, tr_ma)) {
9703 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9704 tn, "): ", ma, " vs expected: ", tr_ma);
9705 } else {
9706 setverdict(pass);
9707 }
9708}
9709
9710private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9711 in MobileAllocationLV ma)
9712return template MobileAllocationLV {
9713 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009714 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009715 return { len := 0, ma := ''B };
9716 }
9717
9718 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9719 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9720 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009721
9722 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009723 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9724 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9725 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009726 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009727 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009728 }
9729 }
9730
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009731 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009732 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009733
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009734 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009735 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9736 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009737 }
9738
9739 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009740 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009741 if (full_mask[i] != '1'B)
9742 { continue; }
9743
9744 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9745 if (slot_mask[i] == '1'B) {
9746 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009747 } else {
9748 ma_mask := ma_mask & '0'B;
9749 }
9750 }
9751
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009752 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9753 if (full_mask[0] == '1'B) {
9754 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9755 if (slot_mask[0] == '1'B) {
9756 ma_mask := ma_mask & '1'B;
9757 } else {
9758 ma_mask := ma_mask & '0'B;
9759 }
9760 }
9761
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009762 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009763 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009764 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9765
9766 return { len := ma_mask_len, ma := ma_mask };
9767}
9768
Philipp Maier798d8952021-10-19 14:43:19 +02009769/* Configure the appropriate band for a given arfcn, exc */
9770private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9771{
9772 var charstring band;
9773 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9774
9775 select (arfcn_) {
9776 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9777 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9778 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9779 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9780 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9781 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9782 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9783 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9784 case else { return; }
9785 }
9786
9787 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9788 f_vty_transceive(BSCVTY, "band " & band);
9789 f_vty_transceive(BSCVTY, "end");
9790}
9791
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009792/* Configure the hopping parameters in accordance with the given record */
9793private function f_TC_fh_params_set(in FHParamsTrx fhp,
9794 uint8_t bts_nr := 0,
9795 uint8_t trx_nr := 0)
9796runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009797
9798 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9799
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009800 /* Enter the configuration node for the given BTS/TRX numbers */
9801 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9802
Philipp Maier798d8952021-10-19 14:43:19 +02009803 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009804
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009805 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009806 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9807
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009808 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009809 f_vty_transceive(BSCVTY, "hopping enabled 0");
9810 f_vty_transceive(BSCVTY, "exit"); /* go back */
9811 continue;
9812 }
9813
9814 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009815 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9816 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009817
9818 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009819 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9820 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009821 }
9822
9823 f_vty_transceive(BSCVTY, "hopping enabled 1");
9824 f_vty_transceive(BSCVTY, "exit"); /* go back */
9825 }
9826
9827 f_vty_transceive(BSCVTY, "end");
9828}
9829
9830/* Disable frequency hopping on all timeslots */
9831private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9832 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009833 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009834 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009835runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009836
9837 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9838
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009839 /* Enter the configuration node for the given BTS/TRX numbers */
9840 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9841
Philipp Maier798d8952021-10-19 14:43:19 +02009842 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009843
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009844 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009845 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9846
9847 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009848 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9849 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009850 }
9851
9852 f_vty_transceive(BSCVTY, "hopping enabled 0");
9853 f_vty_transceive(BSCVTY, "exit"); /* go back */
9854 }
9855
9856 f_vty_transceive(BSCVTY, "end");
9857 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9858}
9859
9860/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9861 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9862testcase TC_fh_params_chan_activ() runs on test_CT {
9863 var FHParamsTrx fhp := f_TC_fh_params_gen();
9864 var RSL_Message rsl_msg;
9865 var RSL_IE_Body ie;
9866
9867 f_init_vty();
9868
9869 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9870 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9871
9872 f_init(1);
9873
9874 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9875 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009876 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9877 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009878
9879 /* Make sure that Channel Identification IE is present */
9880 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9881 setverdict(fail, "RSL Channel Identification IE is absent");
9882 continue;
9883 }
9884
9885 /* Make sure that hopping parameters (HSN/MAIO) match */
9886 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9887
9888 /* "Mobile Allocation shall be included but empty" - let's check this */
9889 if (ie.chan_ident.ma.v.len != 0) {
9890 setverdict(fail, "Mobile Allocation IE is not empty: ",
9891 ie.chan_ident.ma, ", despite it shall be");
9892 continue;
9893 }
9894 }
9895
9896 /* Disable frequency hopping */
9897 f_TC_fh_params_unset(fhp);
9898
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009899 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009900}
9901
9902/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9903testcase TC_fh_params_imm_ass() runs on test_CT {
9904 var FHParamsTrx fhp := f_TC_fh_params_gen();
9905 var RSL_Message rsl_msg;
9906 var RSL_IE_Body ie;
9907
9908 f_init_vty();
9909
9910 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9911 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9912
9913 f_init(1);
9914
9915 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9916 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009917 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9918 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009919
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009920 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9921 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009922
9923 /* Make sure that Full Immediate Assign Info IE is present */
9924 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9925 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9926 continue;
9927 }
9928
9929 /* Decode the actual Immediate Assignment message */
9930 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9931 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9932 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9933 continue;
9934 }
9935
9936 /* Make sure that hopping parameters (HSN/MAIO) match */
9937 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9938
9939 /* Make sure that the Mobile Allocation IE matches */
9940 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9941 rr_msg.payload.imm_ass.mobile_allocation);
9942 }
9943
9944 /* Disable frequency hopping */
9945 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009946
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009947 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009948}
9949
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009950/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9951testcase TC_fh_params_assignment_cmd() runs on test_CT {
9952 var FHParamsTrx fhp := f_TC_fh_params_gen();
9953 var RSL_Message rsl_msg;
9954 var RSL_IE_Body ie;
9955
9956 f_init_vty();
9957
9958 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9959 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9960
9961 f_init(1);
9962
9963 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02009964 vc_MGCP[0].stop;
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009965
9966 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9967 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9968
9969 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9970 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9971 for (var integer i := 0; i < 3; i := i + 1) {
9972 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009973 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009974
9975 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9976 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009977 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009978
9979 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009980 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9981 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009982
9983 /* Make sure that L3 Information IE is present */
9984 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9985 setverdict(fail, "RSL L3 Information IE is absent");
9986 continue;
9987 }
9988
9989 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9990 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9991 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9992 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9993 continue;
9994 }
9995
9996 /* Make sure that hopping parameters (HSN/MAIO) match */
9997 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9998 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9999
10000 /* Make sure that Cell Channel Description IE is present if FH is enabled */
10001 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +070010002 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010003 continue;
10004 }
10005
10006 /* Make sure that the Mobile Allocation IE matches (if present) */
10007 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
10008 if (chan_desc.h and ma_present) {
10009 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
10010 l3_msg.payload.ass_cmd.mobile_allocation.v);
10011 } else if (chan_desc.h and not ma_present) {
10012 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
10013 continue;
10014 } else if (not chan_desc.h and ma_present) {
10015 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
10016 continue;
10017 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010018
10019 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010020 }
10021
10022 /* Give the IUT some time to release all channels */
10023 f_sleep(3.0);
10024
10025 /* Disable frequency hopping */
10026 f_TC_fh_params_unset(fhp);
10027
Vadim Yanitskiy21726312020-09-04 01:45:36 +070010028 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010029}
10030
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010031/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
10032private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
10033runs on test_CT {
10034 var RSL_Message rsl_msg;
10035 var RSL_IE_Body ie;
10036 var DchanTuple dt;
10037
10038 /* Establish a dedicated channel, so we can trigger handover */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010010039 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +030010040 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010041
10042 /* Trigger handover from BTS0 to BTS1 */
10043 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
10044 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
10045
10046 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010047 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx := {1, 0});
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010048
10049 /* ACKnowledge channel activation and expect (RR) Handover Command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010050 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33), idx := {1, 0});
10051 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010052
10053 /* Make sure that L3 Information IE is present */
10054 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
10055 setverdict(fail, "RSL L3 Information IE is absent");
10056 return;
10057 }
10058
10059 /* Decode the L3 message and make sure it is (RR) Handover Command */
10060 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
10061 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
10062 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
10063 return;
10064 }
10065
10066 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
10067 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
10068 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
10069 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
10070 return;
10071 }
10072
10073 /* Make sure that hopping parameters (HSN/MAIO) match */
10074 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
10075
10076 /* Make sure that Cell Channel Description IE is present */
10077 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
10078 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
10079 return;
10080 }
10081
10082 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
10083 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
10084 if (ma_present) {
10085 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
10086 l3_msg.payload.ho_cmd.mobile_allocation.v);
10087 } else {
10088 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
10089 return;
10090 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010091
10092 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010093}
10094testcase TC_fh_params_handover_cmd() runs on test_CT {
10095 var FHParamsTrx fhp := f_TC_fh_params_gen();
10096
10097 f_init_vty();
10098
10099 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
10100 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
10101
10102 f_vty_transceive(BSCVTY, "timeslot 0");
10103 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
10104 f_vty_transceive(BSCVTY, "exit"); /* go back */
10105
10106 f_vty_transceive(BSCVTY, "timeslot 1");
10107 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
10108 f_vty_transceive(BSCVTY, "end"); /* we're done */
10109
10110 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
10111 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
10112
10113 f_init(2);
10114
10115 f_TC_fh_params_handover_cmd(fhp);
10116
10117 /* Disable frequency hopping on BTS1 */
10118 f_TC_fh_params_unset(fhp, 1);
10119
10120 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
10121 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
10122
10123 f_vty_transceive(BSCVTY, "timeslot 0");
10124 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
10125 f_vty_transceive(BSCVTY, "exit"); /* go back */
10126
10127 f_vty_transceive(BSCVTY, "timeslot 1");
10128 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
10129 f_vty_transceive(BSCVTY, "end"); /* we're done */
10130
10131 f_shutdown_helper();
10132}
10133
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010134/* Verify the hopping parameters in System Information Type 4 */
10135testcase TC_fh_params_si4_cbch() runs on test_CT {
10136 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
10137 var ASP_RSL_Unitdata rx_rsl_ud;
10138 timer T := 5.0;
10139
10140 f_init_vty();
10141
10142 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
10143 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
10144
10145 f_vty_transceive(BSCVTY, "timeslot 0");
10146 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
10147 f_vty_transceive(BSCVTY, "exit"); /* go back */
10148
10149 f_vty_transceive(BSCVTY, "timeslot 1");
10150 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
10151 f_vty_transceive(BSCVTY, "end"); /* we're done */
10152
10153 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
10154 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10155
10156 f_init(1);
10157
10158 T.start;
10159 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010160 [] 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 +070010161 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
10162 var SystemInformation si := dec_SystemInformation(ie.other.payload);
10163
10164 /* Make sure that what we decoded is System Information Type 4 */
10165 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
10166 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
10167 repeat;
10168 }
10169
10170 /* Make sure that CBCH Channel Description IE is present */
10171 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
10172 setverdict(fail, "CBCH Channel Description IE is absent");
10173 break;
10174 }
10175
10176 /* Finally, check the hopping parameters (HSN, MAIO) */
10177 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
10178 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
10179
10180 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
10181 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
10182 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
10183 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
10184 break;
10185 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
10186 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
10187 si.payload.si4.cbch_mobile_alloc.v);
10188 }
10189 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010190 [] IPA_RSL[0][0].receive { repeat; }
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010191 [] T.timeout {
10192 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
10193 }
10194 }
10195
10196 /* Disable frequency hopping */
10197 f_TC_fh_params_unset(fhp);
10198
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +070010199 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010200 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
10201
10202 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +070010203 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010204 f_vty_transceive(BSCVTY, "exit"); /* go back */
10205
10206 f_vty_transceive(BSCVTY, "timeslot 1");
10207 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
10208 f_vty_transceive(BSCVTY, "end"); /* we're done */
10209
Vadim Yanitskiy21726312020-09-04 01:45:36 +070010210 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010211}
10212
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010213template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
10214 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
10215
10216private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
10217 template (present) BSSLAP_PDU expect_bsslap)
10218{
10219 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
10220 if (not match(bsslap, expect_bsslap)) {
10221 log("EXPECTING BSSLAP: ", expect_bsslap);
10222 log("GOT BSSLAP: ", bsslap);
10223 setverdict(fail, "BSSLAP is not as expected");
10224 mtc.stop;
10225 }
10226 setverdict(pass);
10227}
10228
10229/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
10230const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
10231
10232private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
10233 var PDU_BSSAP_LE rx_bsslap;
10234 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
10235 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
10236}
10237
10238/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10239 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
10240private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
10241 f_sleep(1.0);
10242
10243 f_establish_fully(omit, omit);
10244 f_bssap_le_register_imsi(g_pars.imsi, omit);
10245
10246 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10247 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10248
10249 var PDU_BSSAP_LE plr;
10250 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10251
10252 if (not do_ta_request) {
10253 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
10254 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
10255 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
10256 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
10257 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
10258 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
10259 mtc.stop;
10260 }
10261 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
10262 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
10263 if (not match(bsslap, expect_ta_layer3)) {
10264 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
10265 log("GOT BSSLAP: ", bsslap);
10266 setverdict(fail, "BSSLAP is not as expected");
10267 mtc.stop;
10268 }
10269 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
10270 * has no need to request the TA from the BSC and directly responds. */
10271 } else {
10272 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10273 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10274 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10275 }
10276
10277 /* SMLC got the TA from the BSC, now responds with geo information data. */
10278 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10279 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10280 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10281
10282 /* The LCS was using an active A-interface conn. It should still remain active after this. */
10283 f_mo_l3_transceive();
10284
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010285 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010286
10287 f_sleep(2.0);
10288 setverdict(pass);
10289}
10290
10291/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10292 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
10293private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
10294 f_lcs_loc_req_for_active_ms(false);
10295}
10296testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
10297 var MSC_ConnHdlr vc_conn;
10298 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10299
10300 f_init(1, true);
10301 f_sleep(1.0);
10302 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
10303 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010304 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010305}
10306
10307/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10308 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
10309private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
10310 f_lcs_loc_req_for_active_ms(true);
10311}
10312testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
10313 var MSC_ConnHdlr vc_conn;
10314 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10315
10316 f_init(1, true);
10317 f_sleep(1.0);
10318 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
10319 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010320 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010321}
10322
10323/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
10324 * conn without an active lchan. */
10325private function f_clear_A_conn() runs on MSC_ConnHdlr
10326{
10327 var BssmapCause cause := 0;
10328 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10329 BSSAP.receive(tr_BSSMAP_ClearComplete);
10330 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10331
10332 timer no_more_bssap := 5.0;
10333 no_more_bssap.start;
10334 alt {
10335 [] no_more_bssap.timeout { break; }
10336 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
10337 setverdict(fail, "Expected no more BSSAP after Clear Complete");
10338 mtc.stop;
10339 }
10340 }
10341 setverdict(pass);
10342}
10343
10344/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
10345 * for LCS, for cases where there is only an A conn without an active lchan. */
10346private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
10347{
10348 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
10349
10350 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
10351 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
10352 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
10353 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10354 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10355 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10356
10357 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
10358 f_clear_A_conn();
10359 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10360 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10361}
10362
10363/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10364 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
10365 */
10366private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
10367 f_sleep(1.0);
10368
10369 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10370 f_bssap_le_register_imsi(g_pars.imsi, omit);
10371
10372 /* Register to receive the Paging Command */
10373 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10374 g_chan_nr := new_chan_nr;
10375 f_rslem_register(0, g_chan_nr);
10376
10377 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10378 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10379 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10380 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10381
10382 var PDU_BSSAP_LE plr;
10383 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10384
10385 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10386 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10387
10388 /* OsmoBSC needs to Page */
10389 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
10390 f_logp(BSCVTY, "got Paging Command");
10391
10392 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
10393 * the MSC, and releases the lchan directly. */
Neels Hofmeyr2bc75892023-04-07 00:00:34 +020010394 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(ts_MI_IMSI_LV(g_pars.imsi)), do_clear := false, expect_bssmap_l3 := false);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010395 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010396
10397 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
10398
10399 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10400
10401 /* SMLC got the TA from the BSC, now responds with geo information data. */
10402 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10403 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10404
10405 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10406
10407 /* The lchan is gone, the A-interface conn was created for the LCS only.
10408 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
10409 f_verify_active_A_conn_and_clear();
10410
10411 f_sleep(2.0);
10412 setverdict(pass);
10413}
10414testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
10415 var MSC_ConnHdlr vc_conn;
10416 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10417
10418 f_init(1, true);
10419 f_sleep(1.0);
10420
10421 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10422 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10423
10424 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
10425 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010426 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010427}
10428
10429/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
10430 */
10431private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
10432 f_sleep(1.0);
10433
10434 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10435 f_bssap_le_register_imsi(g_pars.imsi, omit);
10436
10437 /* provoke an abort by omitting both IMSI and IMEI */
10438 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10439 valueof(ts_BSSMAP_Perform_Location_Request(omit,
10440 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
10441 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10442
10443 /* BSC tells MSC about failure */
10444 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10445 locationEstimate := omit, positioningData := omit,
10446 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
10447
10448 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10449 f_verify_active_A_conn_and_clear();
10450
10451 f_sleep(2.0);
10452 setverdict(pass);
10453}
10454testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
10455 var MSC_ConnHdlr vc_conn;
10456 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10457
10458 f_init(1, true);
10459 f_sleep(1.0);
10460
10461 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10462 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10463
10464 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
10465 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010466 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010467}
10468
10469/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10470 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
10471private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
10472 f_sleep(1.0);
10473
10474 f_establish_fully(omit, omit);
10475 f_bssap_le_register_imsi(g_pars.imsi, omit);
10476
10477 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10478 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10479
10480 var PDU_BSSAP_LE plr;
10481 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10482
10483 if (do_ta) {
10484 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10485 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10486 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10487 }
10488
10489 /* SMLC fails to respond, BSC runs into timeout */
10490 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
10491 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10492
10493 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10494 locationEstimate := omit, positioningData := omit,
10495 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
10496
10497 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10498 f_verify_active_A_conn_and_clear();
10499
10500 f_sleep(2.0);
10501 setverdict(pass);
10502}
10503
10504/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10505 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
10506private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
10507 f_lcs_loc_req_for_active_ms_le_timeout(false);
10508}
10509
10510testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
10511 var MSC_ConnHdlr vc_conn;
10512 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10513
10514 f_init(1, true);
10515 f_sleep(1.0);
10516 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
10517 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010518 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010519}
10520
10521/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10522 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
10523private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
10524 f_lcs_loc_req_for_active_ms_le_timeout(true);
10525}
10526
10527testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
10528 var MSC_ConnHdlr vc_conn;
10529 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10530
10531 f_init(1, true);
10532 f_sleep(1.0);
10533 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10534 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010535 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010536}
10537
10538/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10539private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10540 f_sleep(1.0);
10541
10542 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10543 f_bssap_le_register_imsi(g_pars.imsi, omit);
10544
10545 /* Register to receive the Paging Command */
10546 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10547 g_chan_nr := new_chan_nr;
10548 f_rslem_register(0, g_chan_nr);
10549
10550 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10551 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10552 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10553 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10554
10555 var PDU_BSSAP_LE plr;
10556 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10557
10558 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10559 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10560
10561 /* OsmoBSC needs to Page */
10562 var PDU_BSSAP_LE rx_bsslap;
10563 alt {
10564 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10565 f_logp(BSCVTY, "got Paging Command");
10566 repeat;
10567 }
10568 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10569 /* MS does not respond to Paging, TA Req runs into timeout. */
10570 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10571 }
10572 }
10573
10574 /* SMLC responds with failure */
10575 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10576 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10577
10578 /* BSC tells MSC about failure */
10579 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10580 locationEstimate := omit, positioningData := omit,
10581 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10582
10583 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10584 f_verify_active_A_conn_and_clear();
10585
10586 f_sleep(2.0);
10587 setverdict(pass);
10588}
10589testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10590 var MSC_ConnHdlr vc_conn;
10591 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10592
10593 f_init(1, true);
10594 f_sleep(1.0);
10595
10596 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10597 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10598
10599 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10600 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010601 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010602}
10603
10604/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10605 * over. */
10606private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10607 f_sleep(1.0);
10608
10609 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10610 f_bssap_le_register_imsi(g_pars.imsi, omit);
10611
10612 /* Register to receive the Paging Command */
10613 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10614 g_chan_nr := new_chan_nr;
10615 f_rslem_register(0, g_chan_nr);
10616
10617 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10618 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10619 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10620 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10621
10622 var PDU_BSSAP_LE plr;
10623 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10624
10625 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10626 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010627 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 +020010628 do_clear := false, expect_bssmap_l3 := true);
10629
10630 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10631 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10632
10633 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10634 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10635
10636 /* SMLC got the TA from the BSC, now responds with geo information data. */
10637 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10638 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10639 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10640
10641 /* The lchan should still exist, it was from a CM Service Request. */
10642 f_mo_l3_transceive();
10643
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010644 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010645
10646 f_sleep(2.0);
10647 setverdict(pass);
10648}
10649testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10650 var MSC_ConnHdlr vc_conn;
10651 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10652
10653 f_init(1, true);
10654 f_sleep(1.0);
10655
10656 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10657 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10658
10659 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10660 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010661 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010662}
10663
10664/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10665 * the new lchan after handover. */
10666private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10667 f_sleep(1.0);
10668
10669 f_establish_fully(omit, omit);
10670 f_bssap_le_register_imsi(g_pars.imsi, omit);
10671
10672 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10673 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10674
10675 var PDU_BSSAP_LE plr;
10676 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10677
10678 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10679 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10680
10681 var HandoverState hs := {
10682 rr_ho_cmpl_seen := false,
10683 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010684 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010685 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010686 };
10687 /* issue hand-over command on VTY */
10688 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10689 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10690 f_rslem_suspend(RSL1_PROC);
10691
10692 /* From the MGW perspective, a handover is is characterized by
10693 * performing one MDCX operation with the MGW. So we expect to see
10694 * one more MDCX during handover. */
10695 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10696
10697 alt {
10698 [] as_handover(hs);
10699 }
10700
10701 var PDU_BSSAP_LE rx_bsslap;
10702
10703 interleave {
10704 /* Expect the BSC to inform the MSC about the handover */
10705 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10706
10707 /* Expect the BSC to inform the SMLC about the handover */
10708 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10709 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10710 }
10711 }
10712
10713 /* SMLC now responds with geo information data. */
10714 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10715 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10716 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10717
10718 /* lchan still active */
10719 f_mo_l3_transceive(RSL1);
10720
10721 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010722 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010723
10724 f_sleep(2.0);
10725 setverdict(pass);
10726}
10727testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10728 var MSC_ConnHdlr vc_conn;
10729 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10730
10731 f_init(2, true);
10732 f_sleep(1.0);
10733 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10734 vc_conn.done;
Oliver Smith39f53072022-10-27 14:44:04 +020010735 f_shutdown_helper(ho := true);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010736}
10737
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010738private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10739{
10740 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10741 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10742 * another lchan. */
Pau Espin Pedrol1809bce2023-01-03 16:54:41 +010010743 g_pars.ra := f_rnd_ra_emerg();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010744 f_assignment_emerg_setup();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +010010745 f_assignment_emerg_setup_exp_bssap();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010746
10747 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10748
10749 /* Do a Location Request in-between the CC call setup */
10750 f_bssap_le_register_imsi(g_pars.imsi, omit);
10751 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10752 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10753 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10754 /* SMLC got the TA from the BSC, now responds with geo information data. */
10755 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10756 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10757 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10758
Pau Espin Pedrol14076d32023-01-03 17:07:59 +010010759 f_assignment_emerg_setup_voice();
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010760
10761 setverdict(pass);
10762 f_perform_clear();
10763}
10764
10765testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10766 var MSC_ConnHdlr vc_conn;
10767 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10768
10769 f_init(1, true);
10770 f_sleep(1.0);
10771 f_vty_allow_emerg_msc(true);
10772 f_vty_allow_emerg_bts(true, 0);
10773 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10774 vc_conn.done;
10775 f_shutdown_helper();
10776}
10777
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010778private altstep no_bssmap_clear_req() runs on MSC_ConnHdlr {
10779 [] BSSAP.receive(tr_BSSMAP_ClearRequest) {
10780 setverdict(fail, "unexpected BSSMAP Clear Request");
10781 mtc.stop;
10782 }
10783}
10784
10785private type enumerated RslRel {
10786 RSLREL_REL_IND,
10787 RSLREL_CONN_FAIL
10788};
10789
10790private function f_emerg_call_and_lcs_loc_req_early_lchan_release(RslRel rsl_rel) runs on MSC_ConnHdlr
10791{
10792 g_pars.ra := f_rnd_ra_emerg();
10793 f_assignment_emerg_setup();
Pau Espin Pedrol39bd33c2023-01-03 17:05:27 +010010794 f_assignment_emerg_setup_exp_bssap();
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010795
10796 /* Start a Location Request to locate the emergency */
10797 f_bssap_le_register_imsi(g_pars.imsi, omit);
10798 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10799 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10800 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10801
10802 /* 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
10803 * do a Clear Command when the Location Response arrives. */
10804 activate(no_bssmap_clear_req());
10805
10806 /* the lchan gets interrupted while the Location Request has no response */
10807 select (rsl_rel) {
10808 case (RSLREL_REL_IND) {
10809 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10810 f_expect_lchan_rel(RSL, RSL_PROC);
10811 }
10812 case (RSLREL_CONN_FAIL) {
10813 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
10814 }
10815 case else {
10816 setverdict(fail, "Unknown RslRel type");
10817 mtc.stop;
10818 }
10819 }
10820
10821 /* Still expect the Location Response to find its way to the MSC. */
10822 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10823 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10824 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10825
10826 setverdict(pass);
10827
10828 select (rsl_rel) {
10829 case (RSLREL_REL_IND) {
10830 f_perform_clear_no_lchan();
10831 }
10832 case (RSLREL_CONN_FAIL) {
10833 f_perform_clear();
10834 }
10835 }
10836}
10837
10838private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind(charstring id) runs on MSC_ConnHdlr
10839{
10840 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_REL_IND);
10841}
10842
10843testcase TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() runs on test_CT {
10844 var MSC_ConnHdlr vc_conn;
10845 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10846
10847 f_init(1, true);
10848 f_sleep(1.0);
10849 f_vty_allow_emerg_msc(true);
10850 f_vty_allow_emerg_bts(true, 0);
10851 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind), pars);
10852 vc_conn.done;
10853 f_shutdown_helper();
10854}
10855
10856private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail(charstring id) runs on MSC_ConnHdlr
10857{
10858 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_CONN_FAIL);
10859}
10860
10861testcase TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() runs on test_CT {
10862 var MSC_ConnHdlr vc_conn;
10863 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10864
10865 f_init(1, true);
10866 f_sleep(1.0);
10867 f_vty_allow_emerg_msc(true);
10868 f_vty_allow_emerg_bts(true, 0);
10869 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail), pars);
10870 vc_conn.done;
10871 f_shutdown_helper();
10872}
10873
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010874/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10875private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10876 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10877
10878 /* Also disable attach for the single connected MSC */
10879 f_vty_msc_allow_attach(BSCVTY, { false });
10880
10881 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) ));
10882 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10883
10884 /* No MSC is found, expecting a proper release on RSL */
10885 interleave {
10886 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10887 f_logp(BSCVTY, "Got RSL RR Release");
10888 }
10889 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10890 f_logp(BSCVTY, "Got RSL Deact SACCH");
10891 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010892 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010893 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10894 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010895 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010896 }
10897 }
10898 setverdict(pass);
10899}
10900testcase TC_no_msc() runs on test_CT {
10901
10902 f_init(1, true);
10903 f_sleep(1.0);
10904 var MSC_ConnHdlr vc_conn;
10905 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10906
10907 f_ctrs_bsc_init(counternames_bsc_mscpool);
10908
10909 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10910 vc_conn.done;
10911
10912 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10913 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010914 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010915}
10916
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010917/* Dyn PDCH todo:
10918 * activate OSMO as TCH/F
10919 * activate OSMO as TCH/H
10920 * does the BSC-located PCU socket get the updated INFO?
10921 * what if no PCU is connected at the time?
10922 * is the info correct on delayed PCU (re)connect?
10923 */
Harald Welte94e0c342018-04-07 11:33:23 +020010924
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010925private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +020010926 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020010927 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010928
10929 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10930 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10931 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10932 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10933 g_pars.ass_codec_list.codecElements[0];
10934 if (isvalue(g_pars.expect_mr_s0_s7)) {
10935 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10936 g_pars.expect_mr_s0_s7;
10937 }
10938 }
10939 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10940 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10941 log("expecting ASS COMPL like this: ", exp_compl);
10942
10943 f_establish_fully(ass_cmd, exp_compl);
10944
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010945 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 +000010946
10947 var RSL_Message rsl;
10948
10949 timer T := 5.0;
10950 T.start;
10951 alt {
10952 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10953 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10954 log("Rx L3 from net: ", l3);
10955 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10956 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10957 mtc.stop;
10958 }
10959 }
10960 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10961 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10962 mtc.stop;
10963 }
10964 [] T.timeout {
10965 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10966 setverdict(pass);
10967 }
10968 }
10969 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010970
10971 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010972}
10973
10974/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10975 * osmo-bsc. */
10976testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10977 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10978 var MSC_ConnHdlr vc_conn;
10979
10980 f_init(1, true);
10981 f_sleep(1.0);
10982
10983 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10984 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10985 vc_conn.done;
10986 f_shutdown_helper();
10987}
10988
10989/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10990 */
10991testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10992 f_init_vty();
10993
10994 f_init(1, false);
10995 f_sleep(1.0);
10996
10997 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10998
10999 var ASP_RSL_Unitdata rx_rsl_ud;
11000 timer T := 5.0;
11001
11002 T.start;
11003 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011004 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011005 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
11006 T.stop;
11007 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
11008 mtc.stop;
11009 }
11010 repeat;
11011 }
11012 [] T.timeout {
11013 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
11014 setverdict(pass);
11015 }
11016 }
11017}
11018
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011019private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
11020 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011021 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011022
11023 /* Trigger re-assignment to another lchan */
11024 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
11025
11026 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
11027 * one MDCX on MGCP. */
11028 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
11029
11030 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
11031 * as the old lchan used. */
11032 g_media.bts.ipa_crcx_seen := false;
11033 g_media.bts.ipa_mdcx_seen := false;
11034
11035 /* Send different BTS side RTP port number for the new lchan */
11036 g_media.bts.bts.port_nr := 4223;
11037
11038 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
11039
11040 /* Trigger re-assignment. */
11041 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
11042
11043 timer T := 5.0;
11044 T.start;
11045 alt {
11046 [] as_assignment(assignment_st);
11047 [] as_Media();
11048 [] T.timeout {
11049 break;
11050 }
11051 }
11052
11053 if (not assignment_st.assignment_done) {
11054 setverdict(fail, "Assignment did not complete");
11055 mtc.stop;
11056 }
11057
11058 f_check_mgcp_expectations()
11059 setverdict(pass);
11060
11061 f_sleep(2.0);
11062 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
11063
11064 /* Instruct BSC to clear channel */
11065 var BssmapCause cause := 0;
11066 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
11067 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011068 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
11069 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020011070 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011071 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020011072 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011073 }
11074 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
11075 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11076 }
11077 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020011078 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011079
11080 f_sleep(0.5);
11081}
11082
11083testcase TC_reassignment_fr() runs on test_CT {
11084 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11085 var MSC_ConnHdlr vc_conn;
11086
11087 f_init(1, true);
11088 f_sleep(1.0);
11089
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010011090 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011091
11092 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11093 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
11094 vc_conn.done;
11095
11096 /* from f_establish_fully() */
11097 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
11098 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
11099 /* from re-assignment */
11100 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
11101 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
11102 f_ctrs_bsc_and_bts_verify();
11103 f_shutdown_helper();
11104}
11105
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011106const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
11107const charstring REEST_CLEAR := "REEST_CLEAR";
11108const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
11109
11110/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
11111 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
11112 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
11113 * the MSC as the CM Re-Establishment is handled.
11114 *
11115 * MS bts0 bts1 bsc msc test-component
11116 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
11117 * | | _1 wait a bit, to settle down
11118 * |<-x x--| | _1 "lose connection"
11119 * | | REEST_LOST_CONNECTION
11120 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
11121 * | | REEST_CLEAR
11122 * | |<-0---| _1 Clear Command on first A-conn
11123 * | |--0-->| _1 Clear Complete
11124 * | |<----------------->| | _1 Release first channel
11125 * | | REEST_CLEAR_DONE
11126 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
11127 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
11128 *
11129 */
11130private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
11131 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11132 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11133
11134 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11135 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11136
11137 f_establish_fully(ass_cmd, exp_compl);
11138
11139 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
11140 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
11141 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
11142 f_sleep(2.0);
11143 COORD.send(REEST_LOST_CONNECTION);
11144
11145 alt {
11146 [] COORD.receive(REEST_CLEAR);
11147 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
11148 setverdict(fail, "Unexpected channel release");
11149 mtc.stop;
11150 }
11151 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
11152 setverdict(fail, "Unexpected channel release");
11153 mtc.stop;
11154 }
11155 }
11156 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020011157 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011158 COORD.send(REEST_CLEAR_DONE);
11159}
11160
11161private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
11162 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
11163
11164 /* The MS lost the connection on the first channel, now establishes another one */
11165 COORD.receive(REEST_LOST_CONNECTION);
11166
11167 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
11168 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
11169 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
11170
11171 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011172 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 +020011173 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
11174
11175 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
11176 COORD.send(REEST_CLEAR);
11177 COORD.receive(REEST_CLEAR_DONE);
11178
11179 f_sleep(2.0);
11180
11181 /* Answer the CM Re-Establishment with an Assignment Command. */
11182 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
11183 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11184 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11185 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11186
11187 var AssignmentState st := valueof(ts_AssignmentStateInit);
Oliver Smithce2dd692023-04-17 10:25:50 +020011188 st.rtp_stream := true;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011189 st.is_assignment := true;
11190
11191 var ExpectCriteria mgcpcrit := {
11192 connid := omit,
11193 endpoint := omit,
11194 transid := omit
11195 };
11196 f_create_mgcp_expect(mgcpcrit);
11197
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011198 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011199
11200 BSSAP.send(ass_cmd);
11201
11202 var PDU_BSSAP bssap;
11203
11204 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011205 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
11206 [] as_Media_ipacc(RSL1, RSL2);
11207 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011208 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
11209 break;
11210 }
11211 }
11212
11213 f_sleep(3.0);
11214
11215 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020011216 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011217}
11218
11219testcase TC_cm_reestablishment() runs on test_CT {
11220 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11221 var MSC_ConnHdlr vc_conn1;
11222
11223 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11224 var MSC_ConnHdlr vc_conn2;
11225 pars2.imsi := pars1.imsi;
11226 pars2.media_nr := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011227 pars2.expect_tsc := c_BtsParams[1].tsc;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011228
11229 f_init(2, true, guard_timeout := 40.0);
11230 f_sleep(1.0);
11231
11232 vc_conn1 := f_start_handler_create(pars1);
11233 vc_conn2 := f_start_handler_create(pars2);
11234 connect(vc_conn1:COORD, vc_conn2:COORD);
11235 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
11236 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
11237 vc_conn1.done;
11238 vc_conn2.done;
11239
11240 f_shutdown_helper();
11241}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011242
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011243function f_exp_ipa_rx_nonfatal(template (present) RSL_Message t_rx,
11244 boolean ignore_other_rx := true,
11245 BtsTrxIdx idx := {0, 0},
11246 float Tval := 2.0)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011247runs on test_CT return template (omit) RSL_Message {
11248 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011249 timer T := Tval;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011250
11251 T.start;
11252 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011253 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011254 T.stop;
11255 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011256 [ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
11257 [not ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011258 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
11259 T.stop;
11260 return omit;
11261 }
11262 [] T.timeout {
11263 return omit;
11264 }
11265 }
11266 return rx_rsl_ud.rsl;
11267}
11268
11269private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
11270 f_vty_enter_cfg_bts(pt, bts_nr);
11271 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
11272 f_vty_transceive(pt, "exit");
11273 f_vty_transceive(pt, "exit");
11274 f_vty_transceive(pt, "exit");
11275}
11276
11277private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030011278 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011279 template (present) uint12_t arfcn := ?,
11280 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011281{
11282 var RSL_IE_Body full_imm_ass_info;
11283 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
11284 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
11285 mtc.stop;
11286 }
11287
11288 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
11289 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
11290 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011291 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011292 page_mode := ?);
11293 if (not match(rr_imm_ass, expect_imm_ass)) {
11294 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
11295 setverdict(fail, "Failed to match Immediate Assignment");
11296 mtc.stop;
11297 }
11298}
11299
11300testcase TC_imm_ass_post_chan_ack() runs on test_CT {
11301 var RSL_Message chan_act;
11302 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011303 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011304
11305 f_init(1, false);
11306 f_sleep(1.0);
11307
11308 /* (should be the default anyway, just to make things clear) */
11309 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
11310
11311 /* RA containing reason=LU */
11312 var GsmFrameNumber fn := 2342;
11313 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011314 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011315
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011316 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011317
11318 /* First send the Chan Act ACK */
11319 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011320 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011321 var RSL_IE_Body chan_ident_ie;
11322 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11323 setverdict(fail, "RSL Channel Identification IE is absent");
11324 mtc.stop;
11325 }
11326
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011327 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011328
11329 /* Then expect the Immediate Assignment, after we ACKed the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011330 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011331
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011332 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11333 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011334
11335 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011336 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011337
11338 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011339 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011340 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011341 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11342
11343 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011344 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011345 f_shutdown_helper();
11346}
11347
11348testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
11349 var RSL_Message chan_act;
11350 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011351 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011352
11353 f_init(1, false);
11354 f_sleep(1.0);
11355
11356 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11357
11358 /* RA containing reason=LU */
11359 var GsmFrameNumber fn := 2342;
11360 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011361 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011362
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011363 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011364 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011365 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011366 var RSL_IE_Body chan_ident_ie;
11367 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11368 setverdict(fail, "RSL Channel Identification IE is absent");
11369 mtc.stop;
11370 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011371
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011372 /* (set bts 0 cfg back to default) */
11373 f_vty_set_imm_ass(BSCVTY);
11374
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011375 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011376 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011377 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11378 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011379
11380 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011381 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011382
11383 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011384 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011385
11386 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011387 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011388 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011389 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11390
11391 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011392 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011393 f_shutdown_helper();
11394}
11395
Neels Hofmeyr23158742021-09-07 19:08:07 +020011396testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
11397 var RSL_Message chan_act;
11398 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011399 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr23158742021-09-07 19:08:07 +020011400
11401 f_init(1, false);
11402 f_sleep(1.0);
11403
11404 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11405
11406 /* RA containing reason=LU */
11407 var GsmFrameNumber fn := 2342;
11408 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011409 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011410
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011411 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011412 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011413 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr23158742021-09-07 19:08:07 +020011414 var RSL_IE_Body chan_ident_ie;
11415 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11416 setverdict(fail, "RSL Channel Identification IE is absent");
11417 mtc.stop;
11418 }
11419
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011420 /* (set bts 0 cfg back to default) */
11421 f_vty_set_imm_ass(BSCVTY);
11422
Neels Hofmeyr23158742021-09-07 19:08:07 +020011423 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011424 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011425 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11426 chan_ident_ie.chan_ident.ch_desc.v.tsc);
11427
11428 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011429 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011430
11431 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011432 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011433
11434 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011435 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011436 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020011437 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11438
11439 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011440 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020011441 f_shutdown_helper();
11442}
11443
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011444testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
11445 /* change Timeslot 6 before f_init() starts RSL */
11446 f_init_vty();
11447 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11448 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11449
11450 f_init(1, false);
11451 f_sleep(1.0);
11452
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011453 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011454 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11455 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011456 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11457 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011458
11459 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11460 f_ts_set_chcomb(0, 0, 6, "PDCH");
11461
11462 /* block all static timeslots so that the dyn TS will be used */
11463 f_disable_all_tch_f();
11464 f_disable_all_tch_h();
11465 f_disable_all_sdcch();
11466
11467 var RSL_Message chan_act;
11468 var RSL_Message imm_ass;
11469
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011470 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11471
11472 /* RA containing reason=LU */
11473 var GsmFrameNumber fn := 2342;
11474 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011475 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011476
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011477 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011478 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
11479 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011480
11481 /* Now activation as SDCCH8 */
11482 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011483 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011484
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011485 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011486 var RSL_IE_Body chan_ident_ie;
11487 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11488 setverdict(fail, "RSL Channel Identification IE is absent");
11489 mtc.stop;
11490 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011491
11492 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011493 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011494 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11495 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011496
11497 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011498 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011499
11500 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011501 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011502
11503 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011504 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011505 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011506 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11507
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011508 /* (set bts 0 cfg back to default) */
11509 f_vty_set_imm_ass(BSCVTY);
11510
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011511 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011512 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011513 f_shutdown_helper();
11514}
11515
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011516testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
11517 /* change Timeslot 6 before f_init() starts RSL */
11518 f_init_vty();
11519 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11520 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11521
11522 f_init(1, false);
11523 f_sleep(1.0);
11524
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011525 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011526 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11527 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011528 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11529 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011530
11531 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11532 f_ts_set_chcomb(0, 0, 6, "PDCH");
11533
11534 /* block all static timeslots so that the dyn TS will be used */
11535 f_disable_all_tch_f();
11536 f_disable_all_tch_h();
11537 f_disable_all_sdcch();
11538
11539 var RSL_Message chan_act;
11540 var RSL_Message imm_ass;
11541
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011542 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11543
11544 /* RA containing reason=LU */
11545 var GsmFrameNumber fn := 2342;
11546 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011547 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011548
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011549 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011550 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011551
11552 /* And already the Immediate Assignment even before the PDCH Deact ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011553 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011554
11555 /* continue the Osmo style PDCH Deact (usual chan rel) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011556 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011557
11558 /* Now activation as SDCCH8 */
11559 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011560 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011561
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011562 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011563 var RSL_IE_Body chan_ident_ie;
11564 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11565 setverdict(fail, "RSL Channel Identification IE is absent");
11566 mtc.stop;
11567 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011568 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011569
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011570 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11571 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011572
11573 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011574 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011575
11576 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011577 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011578 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011579 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11580
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011581 /* (set bts 0 cfg back to default) */
11582 f_vty_set_imm_ass(BSCVTY);
11583
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011584 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011585 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011586 f_shutdown_helper();
11587}
11588
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011589/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11590testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11591 var MSC_ConnHdlr vc_conn;
11592
11593 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11594 f_sleep(1.0);
11595
11596 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11597 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11598 "0,0,operational,unlocked,on,rsl-up;" &
11599 "1,0,operational,unlocked,on,rsl-up;" &
11600 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011601 "2,1,operational,unlocked,on,rsl-down;" &
11602 "2,2,operational,unlocked,on,rsl-down;" &
11603 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011604 "3,0,inoperational,locked,on,rsl-down;");
11605
11606 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11607 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11608 /* give it a moment to settle the FSM status */
11609 f_sleep(1.0);
11610
11611 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11612 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11613 * of "off"? But that's for a future patch if at all. */
11614 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11615 "0,0,operational,unlocked,on,rsl-up;" &
11616 "1,0,operational,locked,on,rsl-up;" &
11617 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011618 "2,1,operational,unlocked,on,rsl-down;" &
11619 "2,2,operational,unlocked,on,rsl-down;" &
11620 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011621 "3,0,inoperational,locked,on,rsl-down;");
11622
11623 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11624 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11625 f_sleep(1.0);
11626 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11627 "0,0,operational,unlocked,on,rsl-up;" &
11628 "1,0,operational,locked,on,rsl-up;" &
11629 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011630 "2,1,operational,unlocked,on,rsl-down;" &
11631 "2,2,operational,unlocked,on,rsl-down;" &
11632 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011633 "3,0,inoperational,locked,on,rsl-down;");
11634
11635 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11636 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11637 f_sleep(1.0);
11638 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11639 "0,0,operational,unlocked,on,rsl-up;" &
11640 "1,0,operational,unlocked,on,rsl-up;" &
11641 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011642 "2,1,operational,unlocked,on,rsl-down;" &
11643 "2,2,operational,unlocked,on,rsl-down;" &
11644 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011645 "3,0,inoperational,locked,on,rsl-down;");
11646
11647 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11648 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11649 f_sleep(1.0);
11650 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11651 "0,0,operational,unlocked,on,rsl-up;" &
11652 "1,0,operational,unlocked,on,rsl-up;" &
11653 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011654 "2,1,operational,unlocked,on,rsl-down;" &
11655 "2,2,operational,unlocked,on,rsl-down;" &
11656 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011657 "3,0,inoperational,locked,on,rsl-down;");
11658
11659 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11660 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11661 f_sleep(1.0);
11662 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11663 "0,0,operational,unlocked,on,rsl-up;" &
11664 "1,0,operational,unlocked,on,rsl-up;" &
11665 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011666 "2,1,operational,unlocked,on,rsl-down;" &
11667 "2,2,operational,unlocked,on,rsl-down;" &
11668 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011669 "3,0,inoperational,locked,on,rsl-down;");
11670
11671 f_shutdown_helper();
11672}
11673
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011674const CounterNameVals counternames_cm_serv_rej := {
11675 { "cm_serv_rej", 0 },
11676 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11677 { "cm_serv_rej:illegal_ms", 0 },
11678 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11679 { "cm_serv_rej:imei_not_accepted", 0 },
11680 { "cm_serv_rej:illegal_me", 0 },
11681 { "cm_serv_rej:plmn_not_allowed", 0 },
11682 { "cm_serv_rej:loc_not_allowed", 0 },
11683 { "cm_serv_rej:roaming_not_allowed", 0 },
11684 { "cm_serv_rej:network_failure", 0 },
11685 { "cm_serv_rej:synch_failure", 0 },
11686 { "cm_serv_rej:congestion", 0 },
11687 { "cm_serv_rej:srv_opt_not_supported", 0 },
11688 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11689 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11690 { "cm_serv_rej:call_can_not_be_identified", 0 },
11691 { "cm_serv_rej:incorrect_message", 0 },
11692 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11693 { "cm_serv_rej:msg_type_not_implemented", 0 },
11694 { "cm_serv_rej:msg_type_not_compatible", 0 },
11695 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11696 { "cm_serv_rej:condtional_ie_error", 0 },
11697 { "cm_serv_rej:msg_not_compatible", 0 },
11698 { "cm_serv_rej:protocol_error", 0 },
11699 { "cm_serv_rej:retry_in_new_cell", 0 }
11700};
11701
11702private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11703{
11704 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011705 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011706 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011707 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11708 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011709 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011710}
11711testcase TC_cm_serv_rej() runs on test_CT {
11712 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11713 var MSC_ConnHdlr vc_conn;
11714
11715 f_init(1, true);
11716 f_sleep(1.0);
11717
11718 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11719
11720 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11721 vc_conn.done;
11722
11723 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11724 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11725 f_ctrs_bts_verify();
11726
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011727 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011728 f_shutdown_helper();
11729}
11730
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011731/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11732 * Activ Ack (SYS#5627). */
11733private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11734 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011735
11736 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11737 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011738
11739 var BSSMAP_FIELD_CodecType codecType;
11740 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11741
11742 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11743
11744 /* First establish a signalling lchan */
11745 f_create_chan_and_exp();
11746 f_rslem_dchan_queue_enable();
11747
11748 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011749
11750 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
Oliver Smith735b47c2023-02-15 16:03:54 +010011751 activate(as_Media_mgw());
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011752
11753 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11754 f_rslem_register(0, chan_nr);
11755
11756 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11757 BSSAP.send(ass_cmd);
11758
11759
11760 /* Wait for the Channel Activ for the TCH channel */
11761 var ASP_RSL_Unitdata rx_rsl_ud;
11762 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11763
11764 /* make the original SDCCH disappear */
11765 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11766
11767 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11768 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11769
11770 interleave {
11771 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11772 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11773 }
11774
11775 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11776 BSSAP.receive(tr_BSSMAP_ClearComplete);
11777 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11778
11779 var MgcpCommand mgcp;
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011780 var MGCP_RecvFrom mrf;
11781 var template MgcpMessage msg_dlcx := { command := tr_DLCX };
11782 alt {
11783 [g_pars.aoip] MGCP.receive(tr_DLCX) -> value mgcp {
11784 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11785 }
11786 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
11787 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
11788 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
11789 }));
11790 }
11791 }
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011792
11793 f_sleep(0.5);
11794}
11795testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11796 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11797 var MSC_ConnHdlr vc_conn;
11798
Oliver Smith735b47c2023-02-15 16:03:54 +010011799 pars.fail_on_dlcx := false;
11800
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011801 f_init(1, true);
11802 f_sleep(1.0);
11803
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011804 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11805 vc_conn.done;
11806
11807 f_shutdown_helper();
11808}
11809
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011810const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11811 { "all_allocated:sdcch", 0 },
11812 { "all_allocated:static_sdcch", 0 },
11813 { "all_allocated:tch", 0 },
11814 { "all_allocated:static_tch", 0 }
11815}
11816
11817private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11818{
11819 /* Make sure counters settle first */
11820 f_sleep(1.0);
11821
11822 /* Take a baseline of counters */
11823 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11824
11825 /* Elapse some time so that we see changes in counters, hopefully where expected */
11826 f_sleep(2.0);
11827
11828 /* Get new counters */
11829 var charstring_list all_changed := {};
11830 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11831 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11832
11833 /* Compare with expectations */
11834 var charstring_list all_expect_changed := {};
11835 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11836 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11837 }
11838 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11839}
11840
11841testcase TC_ratectr_all_available_allocated() runs on test_CT {
11842 var ASP_RSL_Unitdata rsl_ud;
11843 var integer i;
11844 var integer chreq_total, chreq_nochan;
11845
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011846 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011847 f_sleep(1.0);
11848
11849 /* Exhaust all dedicated SDCCH lchans.
11850 /* GSM 44.018 Table 9.1.8.2:
11851 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11852 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011853 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011854 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011855 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 +020011856 }
11857
11858 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11859 * level.
11860 * All SDCCH are now occupied. */
11861 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11862
11863 /* Also fill up all remaining (TCH) channels */
11864 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011865 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 +020011866 }
11867
11868 /* All TCH are now also occupied */
11869 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11870 "all_allocated:tch", "all_allocated:static_tch"});
11871
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011872 /* Clean up SDCCH lchans */
11873 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11874 f_perform_clear_test_ct(chan_cleanup[i]);
11875 }
11876
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011877 f_shutdown_helper();
11878}
11879
11880testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11881 var ASP_RSL_Unitdata rsl_ud;
11882 var integer i;
11883 var integer chreq_total, chreq_nochan;
11884
11885 f_init_vty();
11886 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11887 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11888 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11889
11890 f_init(1, guard_timeout := 60.0);
11891 f_sleep(1.0);
11892
11893 /* The dyn TS wants to activate PDCH mode, ACK that. */
11894 var RslChannelNr chan_nr;
11895 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011896 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11897 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011898
11899 /* Exhaust all dedicated SDCCH lchans.
11900 /* GSM 44.018 Table 9.1.8.2:
11901 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11902 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011903 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011904 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011905 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 +020011906 }
11907
11908 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11909 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11910 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11911
11912 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11913 * Will release them later, so remember all the DchanTuples. */
11914 var DchanTuples dyn_sddch := {};
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011915 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 +020011916
11917 /* Also occupy the seven other SDCCH of the dyn TS */
11918 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011919 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 +020011920 }
11921
11922 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11923 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11924
11925 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11926 for (i := 0; i < 5; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011927 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 +020011928 }
11929
11930 /* All TCH lchans are now also occupied, both static and dynamic */
11931 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11932 "all_allocated:tch", "all_allocated:static_tch"});
11933
11934 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11935 * incrementing. */
11936 var BssmapCause cause := 0;
11937 var DchanTuple dt := dyn_sddch[0];
11938 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011939 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011940
11941 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11942 * count as occupied, so those still both increment. */
11943 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11944 "all_allocated:tch", "all_allocated:static_tch"});
11945
11946 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11947 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11948 dt := dyn_sddch[i];
11949 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011950 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011951 }
11952
11953 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11954 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011955 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11956 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011957
11958 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11959 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11960
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011961 /* Clean up SDCCH lchans */
11962 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11963 f_perform_clear_test_ct(chan_cleanup[i]);
11964 }
11965
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011966 /* clean up config */
11967 f_ts_reset_chcomb(0);
11968
11969 f_shutdown_helper();
11970}
11971
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011972private function f_TC_chan_alloc_algo(DchanTuple dt, BtsTrxIdx idx)
11973runs on test_CT {
11974 /* MSC sends an Assignment Request */
11975 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11976 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11977 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11978 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
11979
11980 /* Expect the BSC to allocate a TCH channel on the given BTS/TRX */
11981 var RSL_Message rsl_chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
11982 /* Send CHAN ACT NACK, so that the requested TCH channel becomes BORKEN */
11983 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(rsl_chan_act.ies[0].body.chan_nr, RSL_ERR_EQUIPMENT_FAIL), idx);
11984 /* Expect to receive an Assignment Failure */
11985 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail));
11986}
11987
11988testcase TC_chan_alloc_algo_ascending() runs on test_CT {
11989 /* We need to access BTS2, which has 4 TRXs */
11990 f_init(nr_bts := 3);
11991
11992 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011993 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011994
11995 f_vty_enter_cfg_bts(BSCVTY, 2);
11996 f_vty_transceive(BSCVTY, "channel allocator ascending");
11997 f_vty_transceive(BSCVTY, "end");
11998
11999 /* Expect the BSC to allocate 4 x TCH/F channels on BTS2/TRX0 */
12000 for (var integer i := 0; i < 4; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010012001 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012002 f_TC_chan_alloc_algo(dt, {2, 0});
12003 f_perform_clear_test_ct(dt);
12004 }
12005
12006 /* At this point all 4 x TCH/F channels are BORKEN, but they will be
12007 * resurrected upon the A-bis/OML link re-establishment. */
12008 f_shutdown_helper();
12009}
12010
12011testcase TC_chan_alloc_algo_descending() runs on test_CT {
12012 /* We need to access BTS2, which has 4 TRXs */
12013 f_init(nr_bts := 3);
12014
12015 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020012016 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012017
12018 f_vty_enter_cfg_bts(BSCVTY, 2);
12019 f_vty_transceive(BSCVTY, "channel allocator descending");
12020 f_vty_transceive(BSCVTY, "end");
12021
12022 /* Expect the BSC to allocate 5 x TCH/F channels on BTS2/TRX3 */
12023 for (var integer i := 0; i < 5; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010012024 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012025 f_TC_chan_alloc_algo(dt, {2, 3});
12026 f_perform_clear_test_ct(dt);
12027 }
12028
12029 /* At this point all 5 x TCH/F channels are BORKEN, but they will be
12030 * resurrected upon the A-bis/OML link re-establishment. */
12031 f_shutdown_helper();
12032}
12033
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012034testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
12035 const BtsTrxIdx TRX0 := {2, 0};
12036 const BtsTrxIdx TRX3 := {2, 3};
12037
12038 /* We need to access BTS2, which has 4 TRXs */
12039 f_init(nr_bts := 3);
12040
12041 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020012042 vc_MGCP[0].stop;
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012043
12044 f_vty_enter_cfg_bts(BSCVTY, 2);
12045 f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
12046 f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
12047 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
12048 f_vty_transceive(BSCVTY, "end");
12049
12050 var DchanTuple dt;
12051
12052 f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010012053 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012054 f_TC_chan_alloc_algo(dt, TRX0);
12055 f_perform_clear_test_ct(dt);
12056
12057 f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010012058 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012059 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
12060 ts_RSL_IE_UplinkMeas(30, 0),
12061 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070012062 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012063 f_TC_chan_alloc_algo(dt, TRX0);
12064 f_perform_clear_test_ct(dt);
12065
12066 f_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010012067 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012068 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
12069 ts_RSL_IE_UplinkMeas(45, 0),
12070 ts_RSL_IE_BS_Power(0)), TRX0);
12071 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
12072 ts_RSL_IE_UplinkMeas(48, 0),
12073 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070012074 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012075 f_TC_chan_alloc_algo(dt, TRX0);
12076 f_perform_clear_test_ct(dt);
12077
12078 f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010012079 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012080 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
12081 ts_RSL_IE_UplinkMeas(50, 0),
12082 ts_RSL_IE_BS_Power(0)), TRX0);
12083 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
12084 ts_RSL_IE_UplinkMeas(58, 0),
12085 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070012086 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012087 f_TC_chan_alloc_algo(dt, TRX3);
12088 f_perform_clear_test_ct(dt);
12089
12090 f_vty_enter_cfg_bts(BSCVTY, 2);
12091 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
12092 f_vty_transceive(BSCVTY, "end");
12093
12094 f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010012095 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012096 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
12097 ts_RSL_IE_UplinkMeas(50, 0),
12098 ts_RSL_IE_BS_Power(0)), TRX0);
12099 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
12100 ts_RSL_IE_UplinkMeas(58, 0),
12101 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070012102 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012103 f_TC_chan_alloc_algo(dt, TRX0);
12104 f_perform_clear_test_ct(dt);
12105
12106 f_vty_enter_cfg_bts(BSCVTY, 2);
12107 f_vty_transceive(BSCVTY, "channel allocator ascending");
12108 f_vty_transceive(BSCVTY, "end");
12109
12110 /* At this point some TCH/F channels are BORKEN, but they will be
12111 * resurrected upon the A-bis/OML link re-establishment. */
12112 f_shutdown_helper();
12113}
12114
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012115private function f_vty_mgw_enable(integer mgw_nr := 1) runs on test_CT {
12116 var rof_charstring cmds := {
12117 "remote-ip " & mp_test_ip,
12118 "remote-port " & int2str(2427 + mgw_nr)
12119 };
12120 f_vty_config3(BSCVTY, {"network", "mgw " & int2str(mgw_nr)}, cmds);
12121 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " reconnect")
12122}
12123private function f_vty_mgw_disable(integer mgw_nr := 1) runs on test_CT {
12124 f_vty_config3(BSCVTY, {"network"}, { "no mgw " &int2str(mgw_nr) });
12125}
12126private function f_vty_mgw_block(integer mgw_nr := 1, boolean blocked := true) runs on test_CT {
12127 var charstring arg;
12128 if (blocked) {
12129 arg := "block";
12130 } else {
12131 arg := "unblock";
12132 }
12133 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " " & arg);
12134}
Pau Espin Pedrolbd598422023-06-15 17:29:09 +020012135private function f_vty_mgw_cfg_keepalive(integer mgw_nr := 1, integer req_intval := 0, charstring req_endp := "null", integer rx_timeout := 0) runs on test_CT {
12136 var charstring arg;
12137 var rof_charstring cmds := {
12138 "keepalive request-interval " & int2str(req_intval),
12139 "keepalive request-endpoint " & req_endp,
12140 "keepalive timeout " & int2str(rx_timeout)
12141 };
12142 f_vty_config3(BSCVTY, {"network", "mgw " & int2str(mgw_nr)}, cmds);
12143}
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012144private const charstring COORD_CMD_ESTABLISHED := "COORD_CMD_ESTABLISHED";
12145private function f_TC_mgwpool_call_seq_1(charstring id) runs on MSC_ConnHdlr {
12146 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
12147 var PDU_BSSAP ass_cmd := f_gen_ass_req();
12148 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
12149 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
12150
12151 f_establish_fully(ass_cmd, exp_compl);
12152 COORD.send(COORD_CMD_ESTABLISHED);
12153
12154 COORD.receive(COORD_CMD_ESTABLISHED);
12155 f_perform_clear()
12156 f_create_mgcp_delete_ep(g_media.mgcp_ep);
12157}
12158private function f_TC_mgwpool_call_seq_2(charstring id) runs on MSC_ConnHdlr {
12159 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
12160 var PDU_BSSAP ass_cmd := f_gen_ass_req();
12161 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
12162 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
12163
12164
12165 COORD.receive(COORD_CMD_ESTABLISHED);
12166 f_establish_fully(ass_cmd, exp_compl);
12167 COORD.send(COORD_CMD_ESTABLISHED);
12168
12169 f_perform_clear()
12170 f_create_mgcp_delete_ep(g_media.mgcp_ep);
12171}
12172/* Test load is spread around 2 available MGWs */
12173testcase TC_mgwpool_all_used() runs on test_CT {
12174 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
12175 var MSC_ConnHdlr vc_conn1;
12176 pars1.mgwpool_idx := 0;
12177
12178 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12179 var MSC_ConnHdlr vc_conn2;
12180 pars2.mgwpool_idx := 1;
12181
12182 f_init(1, true, nr_mgw := 2);
12183 f_sleep(1.0);
12184
12185 f_vty_mgw_enable(1);
12186
12187 vc_conn1 := f_start_handler_create(pars1);
12188 vc_conn2 := f_start_handler_create(pars2);
12189 connect(vc_conn1:COORD, vc_conn2:COORD);
12190 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12191 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12192 vc_conn1.done;
12193 vc_conn2.done;
12194
12195 f_vty_mgw_disable(1);
12196
12197 f_shutdown_helper();
12198}
12199
12200/* Test blocked MGW in the pool are not selected */
12201testcase TC_mgwpool_blocked_not_used() runs on test_CT {
12202 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
12203 var MSC_ConnHdlr vc_conn1;
12204 pars1.mgwpool_idx := 0;
12205
12206 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12207 var MSC_ConnHdlr vc_conn2;
12208 pars2.mgwpool_idx := 0; /* expect it in the first one, since the second will be blocked */
12209 pars2.media_nr := 2;
12210
12211 f_init(1, true, nr_mgw := 2);
12212 f_sleep(1.0);
12213
12214 f_vty_mgw_enable(1);
12215 f_vty_mgw_block(1, true);
12216
12217 vc_conn1 := f_start_handler_create(pars1);
12218 vc_conn2 := f_start_handler_create(pars2);
12219 connect(vc_conn1:COORD, vc_conn2:COORD);
12220 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12221 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12222 vc_conn1.done;
12223 vc_conn2.done;
12224
12225 f_vty_mgw_disable(1);
12226
12227 f_shutdown_helper();
12228}
12229
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012230/* Test BTS pinning to an MGW is applied */
12231testcase TC_mgwpool_pin_bts() runs on test_CT {
12232 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
12233 var MSC_ConnHdlr vc_conn1;
12234 pars1.mgwpool_idx := 0;
12235
12236 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12237 var MSC_ConnHdlr vc_conn2;
12238 pars2.mgwpool_idx := 0; /* expect it in the first one, since the BTS is pinned to the first MGW */
12239 pars2.media_nr := 2;
12240
12241 f_init(1, true, nr_mgw := 2);
12242 f_sleep(1.0);
12243
12244 f_vty_mgw_enable(1);
12245 f_vty_cfg_bts(BSCVTY, 0, { "mgw pool-target 0" });
12246
12247 vc_conn1 := f_start_handler_create(pars1);
12248 vc_conn2 := f_start_handler_create(pars2);
12249 connect(vc_conn1:COORD, vc_conn2:COORD);
12250 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
12251 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
12252 vc_conn1.done;
12253 vc_conn2.done;
12254
12255 f_vty_cfg_bts(BSCVTY, 0, { "no mgw pool-target" } );
Vadim Yanitskiy389d7e02022-10-25 17:44:05 +070012256 f_vty_mgw_disable(1);
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012257
12258 f_shutdown_helper();
12259}
12260
Pau Espin Pedrolbd598422023-06-15 17:29:09 +020012261/* Test keepalive procedure on the MGW */
12262private function f_TC_mgwpool_keepalive_mgw0(charstring id) runs on MSC_ConnHdlr {
12263 /* Make sure the MGW is considered DOWN by the keepalive. See "timeout"
12264 * param in TC_mgwpool_keepalive. */
12265 f_sleep(3.0);
12266
12267 COORD.send(COORD_CMD_ESTABLISHED);
12268
12269 /* Wait for signal that call was established successfully over the other MSC/MGW: */
12270 COORD.receive(COORD_CMD_ESTABLISHED);
12271}
12272private function f_TC_mgwpool_keepalive_mgw1(charstring id) runs on MSC_ConnHdlr {
12273 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
12274 var PDU_BSSAP ass_cmd := f_gen_ass_req();
12275 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
12276 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
12277
12278 /* Wait for other MSC/MGW component to tell us the timeout is done and
12279 * we can start the call, which will be assigned to use because the other
12280 * MGW will be seen as DOWN. */
12281 COORD.receive(COORD_CMD_ESTABLISHED);
12282 f_establish_fully(ass_cmd, exp_compl);
12283 /* signal that call was established successfully over the other MSC/MGW: */
12284 COORD.send(COORD_CMD_ESTABLISHED);
12285
12286 f_perform_clear()
12287 f_create_mgcp_delete_ep(g_media.mgcp_ep);
12288}
12289testcase TC_mgwpool_keepalive_down_not_used() runs on test_CT {
12290 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
12291 var MSC_ConnHdlr vc_conn1;
12292 pars1.mgwpool_idx := 0;
12293
12294 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
12295 var MSC_ConnHdlr vc_conn2;
12296 pars2.mgwpool_idx := 1; /* expect it in the second one, since the first will be considered DOWN */
12297 pars2.media_nr := 2;
12298
12299 f_init(1, true, nr_mgw := 2);
12300 f_sleep(1.0);
12301
Vadim Yanitskiycf25a3a2023-06-20 17:27:18 +070012302 f_vty_mgw_cfg_keepalive(0, req_intval := 1, req_endp := "null", rx_timeout := 3);
Pau Espin Pedrolbd598422023-06-15 17:29:09 +020012303 f_vty_mgw_enable(1);
12304 f_vty_mgw_block(1, false);
Pau Espin Pedrolbd598422023-06-15 17:29:09 +020012305
12306 vc_conn1 := f_start_handler_create(pars1);
12307 vc_conn2 := f_start_handler_create(pars2);
12308 connect(vc_conn1:COORD, vc_conn2:COORD);
12309 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_keepalive_mgw0), pars1);
12310 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_keepalive_mgw1), pars2);
12311 vc_conn1.done;
12312 vc_conn2.done;
12313
12314 f_vty_mgw_disable(1);
12315 /* disable keepalive (default status): */
12316 f_vty_mgw_cfg_keepalive(0, req_intval := 0, req_endp := "null", rx_timeout := 0);
12317
12318 f_shutdown_helper();
12319}
12320
Oliver Smithc9a5f532022-10-21 11:32:23 +020012321private function f_tc_ho_meas_rep_multi_band(charstring id) runs on MSC_ConnHdlr {
12322 g_pars := f_gen_test_hdlr_pars();
12323 var PDU_BSSAP ass_req := f_gen_ass_req();
12324 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
12325 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
12326 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
12327 f_establish_fully(ass_req, exp_compl);
12328
12329 /* Send a measurement report with bad rxlev except on 3rd entry. The
12330 * measurement report is divided into two sub lists, as described in
12331 * 3GPP TS 04.08 § 10.5.2.20. */
12332 var NcellReports neighbor_rep := {
12333 /* Sub list 1: same band */
Oliver Smitha6773042022-10-24 12:56:30 +020012334 { rxlev := 0, bcch_freq := 0, bsic := 12 }, /* ARFCN 800, band 1800, LAC 98 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012335 /* Sub list 2: different band */
Oliver Smitha6773042022-10-24 12:56:30 +020012336 { rxlev := 0, bcch_freq := 1, bsic := 13 }, /* ARFCN 200, band 850, LAC 97 */
12337 { rxlev := 40, bcch_freq := 2, bsic := 14 }, /* ARFCN 1000, band 900, LAC 99 */
12338 { rxlev := 0, bcch_freq := 3, bsic := 11 } /* ARFCN 0, band 900, LAC 96 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012339 };
12340 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
12341 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
12342 l3_mr, 0));
12343
12344 /* Expect a handover to the third entry. If the BSC parsed the report
Oliver Smitha6773042022-10-24 12:56:30 +020012345 * correctly, the third entry has LAC 99. */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012346 var template BSSMAP_FIELD_CellIdentificationList cid_list := {
Oliver Smitha6773042022-10-24 12:56:30 +020012347 cIl_LAC := { ts_BSSMAP_CI_LAC(99) }
Oliver Smithc9a5f532022-10-21 11:32:23 +020012348 };
12349 alt {
12350 [] BSSAP.receive(tr_BSSMAP_HandoverRequired(cid_list := cid_list)) {
12351 setverdict(pass);
12352 }
12353 [] BSSAP.receive(tr_BSSMAP_HandoverRequired()) {
12354 setverdict(fail, "Handover has unexpected LAC in Cell Identification List. The BSC probably"
12355 & " didn't parse the multi-band measurement report correctly.");
12356 }
12357 }
12358
12359 f_ho_out_of_this_bsc(skip_meas_rep := true);
12360}
12361testcase TC_ho_meas_rep_multi_band() runs on test_CT {
12362 /* Verify that the BSC parses the measurement report correctly when
12363 * neighbors in multiple bands are configured (OS#5717). See
12364 * gsm_arfcn2band_rc() in libosmocore src/gsm/gsm_utils.c for the
12365 * ARFCN -> band mapping. The MS is connected to band 1800. */
12366 var MSC_ConnHdlr vc_conn;
12367
12368 f_init_vty();
12369 f_bts_0_cfg(BSCVTY,
12370 {"neighbor-list mode automatic",
12371 "handover 1",
12372 "handover algorithm 2",
12373 "handover2 window rxlev averaging 1",
12374 "no neighbors",
12375 "neighbor lac 99 arfcn 1000 bsic any", /* band 900 */
12376 "neighbor lac 98 arfcn 800 bsic any", /* band 1800 */
12377 "neighbor lac 97 arfcn 200 bsic any", /* band 850 */
Oliver Smitha6773042022-10-24 12:56:30 +020012378 "neighbor lac 96 arfcn 0 bsic any"}); /* band 900 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012379 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
12380
12381 f_init(1, true);
12382 f_sleep(1.0);
12383
12384 f_ctrs_bsc_and_bts_handover_init();
12385
12386 vc_conn := f_start_handler(refers(f_tc_ho_meas_rep_multi_band));
12387 vc_conn.done;
12388
12389 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
12390 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
12391 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
12392 f_ctrs_bsc_and_bts_add(0, "handover:completed");
12393 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
12394 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
12395 f_ctrs_bsc_and_bts_verify();
12396 f_shutdown_helper(ho := true);
12397}
12398
Harald Welte28d943e2017-11-25 15:00:50 +010012399control {
Harald Welte898113b2018-01-31 18:32:21 +010012400 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010012401 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010012402 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020012403 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
12404 * these in the AoIP test suite. */
12405 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12406 execute( TC_stat_num_msc_connected_1() );
12407 execute( TC_stat_num_msc_connected_2() );
12408 execute( TC_stat_num_msc_connected_3() );
12409 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020012410 execute( TC_stat_num_bts_connected_1() );
12411 execute( TC_stat_num_bts_connected_2() );
12412 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010012413 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012414 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020012415 execute( TC_ctrl_location() );
12416 }
Harald Welte898113b2018-01-31 18:32:21 +010012417
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012418 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020012419 execute( TC_si2quater_2_earfcns() );
12420 execute( TC_si2quater_3_earfcns() );
12421 execute( TC_si2quater_4_earfcns() );
12422 execute( TC_si2quater_5_earfcns() );
12423 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020012424 execute( TC_si2quater_12_earfcns() );
12425 execute( TC_si2quater_23_earfcns() );
12426 execute( TC_si2quater_32_earfcns() );
12427 execute( TC_si2quater_33_earfcns() );
12428 execute( TC_si2quater_42_earfcns() );
12429 execute( TC_si2quater_48_earfcns() );
12430 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020012431 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020012432 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012433
Harald Welte898113b2018-01-31 18:32:21 +010012434 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010012435 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010012436 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010012437 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020012438 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020012439 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010012440 execute( TC_chan_act_ack_est_ind_noreply() );
12441 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010012442 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010012443 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070012444 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010012445 execute( TC_chan_rel_rll_rel_ind() );
12446 execute( TC_chan_rel_conn_fail() );
12447 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020012448 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
12449 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010012450 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010012451 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020012452 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010012453 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010012454 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020012455 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010012456
Harald Weltecfe2c962017-12-15 12:09:32 +010012457 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010012458
12459 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010012460 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010012461 execute( TC_assignment_csd() );
12462 execute( TC_assignment_ctm() );
12463 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012464 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12465 execute( TC_assignment_aoip_tla_v6() );
12466 }
Harald Welte235ebf12017-12-15 14:18:16 +010012467 execute( TC_assignment_fr_a5_0() );
12468 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012469 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020012470 execute( TC_assignment_fr_a5_1_codec_missing() );
12471 }
Harald Welte235ebf12017-12-15 14:18:16 +010012472 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020012473 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020012474 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020012475 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012476 execute( TC_ciph_mode_a5_0() );
12477 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020012478 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020012479 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012480 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020012481 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010012482
Harald Welte60aa5762018-03-21 19:33:13 +010012483 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020012484 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010012485 execute( TC_assignment_codec_hr() );
12486 execute( TC_assignment_codec_efr() );
12487 execute( TC_assignment_codec_amr_f() );
12488 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012489
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012490 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010012491 execute( TC_assignment_codec_amr_f_S1() );
12492 execute( TC_assignment_codec_amr_h_S1() );
12493 execute( TC_assignment_codec_amr_f_S124() );
12494 execute( TC_assignment_codec_amr_h_S124() );
12495 execute( TC_assignment_codec_amr_f_S0() );
12496 execute( TC_assignment_codec_amr_f_S02() );
12497 execute( TC_assignment_codec_amr_f_S024() );
12498 execute( TC_assignment_codec_amr_f_S0247() );
12499 execute( TC_assignment_codec_amr_h_S0() );
12500 execute( TC_assignment_codec_amr_h_S02() );
12501 execute( TC_assignment_codec_amr_h_S024() );
12502 execute( TC_assignment_codec_amr_h_S0247() );
12503 execute( TC_assignment_codec_amr_f_S01234567() );
12504 execute( TC_assignment_codec_amr_f_S0234567() );
12505 execute( TC_assignment_codec_amr_f_zero() );
12506 execute( TC_assignment_codec_amr_f_unsupp() );
12507 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000012508 execute( TC_assignment_codec_amr_f_start_mode_auto() );
12509 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000012510 execute( TC_assignment_codec_amr_f_start_mode_4() );
12511 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000012512 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012513 }
Harald Welte60aa5762018-03-21 19:33:13 +010012514
Philipp Maierac09bfc2019-01-08 13:41:39 +010012515 execute( TC_assignment_codec_fr_exhausted_req_hr() );
12516 execute( TC_assignment_codec_fr_exhausted_req_fr() );
12517 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
12518 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
12519 execute( TC_assignment_codec_hr_exhausted_req_fr() );
12520 execute( TC_assignment_codec_hr_exhausted_req_hr() );
12521 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
12522 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
12523 execute( TC_assignment_codec_req_hr_fr() );
12524 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020012525 execute( TC_assignment_sdcch_exhausted_req_signalling() );
12526 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
12527 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010012528
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +020012529 execute( TC_assignment_codec_hr_osmux_on() );
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020012530 execute( TC_assignment_osmux() );
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020012531 execute( TC_assignment_osmux_cn() );
12532 execute( TC_assignment_osmux_bts() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020012533
Harald Welte898113b2018-01-31 18:32:21 +010012534 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010012535 execute( TC_rll_est_ind_inact_lchan() );
12536 execute( TC_rll_est_ind_inval_sapi1() );
12537 execute( TC_rll_est_ind_inval_sapi3() );
12538 execute( TC_rll_est_ind_inval_sacch() );
12539
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070012540 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
12541 execute( TC_tch_dlci_link_id_sapi() );
12542
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012543 /* SAPI N Reject triggered by RLL establishment failures */
12544 execute( TC_rll_rel_ind_sapi_n_reject() );
12545 execute( TC_rll_err_ind_sapi_n_reject() );
12546 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070012547 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012548
Harald Welte898113b2018-01-31 18:32:21 +010012549 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010012550 execute( TC_paging_imsi_nochan() );
12551 execute( TC_paging_tmsi_nochan() );
12552 execute( TC_paging_tmsi_any() );
12553 execute( TC_paging_tmsi_sdcch() );
12554 execute( TC_paging_tmsi_tch_f() );
12555 execute( TC_paging_tmsi_tch_hf() );
12556 execute( TC_paging_imsi_nochan_cgi() );
12557 execute( TC_paging_imsi_nochan_lac_ci() );
12558 execute( TC_paging_imsi_nochan_ci() );
12559 execute( TC_paging_imsi_nochan_lai() );
12560 execute( TC_paging_imsi_nochan_lac() );
12561 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010012562 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
12563 execute( TC_paging_imsi_nochan_rnc() );
12564 execute( TC_paging_imsi_nochan_lac_rnc() );
12565 execute( TC_paging_imsi_nochan_lacs() );
12566 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010012567 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010012568 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010012569 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010012570 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010012571 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020012572 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020012573 execute( TC_paging_450req_no_paging_load_ind() );
Pau Espin Pedrol07657ae2023-01-03 12:08:05 +010012574 execute( TC_paging_imsi_nochan_ci_resp_invalid_mi() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010012575
12576 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010012577 execute( TC_rsl_unknown_unit_id() );
12578
12579 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012580
12581 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020012582 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012583 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010012584 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010012585 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010012586 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010012587 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012588
Harald Welte261af4b2018-02-12 21:20:39 +010012589 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020012590 execute( TC_ho_int_a5_0() );
12591 execute( TC_ho_int_a5_1() );
12592 execute( TC_ho_int_a5_3() );
12593 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000012594 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012595
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012596 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020012597 execute( TC_ho_out_fail_no_msc_response() );
12598 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020012599 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012600
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012601 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020012602 execute( TC_ho_into_this_bsc_a5_0() );
12603 execute( TC_ho_into_this_bsc_a5_1() );
12604 execute( TC_ho_into_this_bsc_a5_3() );
12605 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010012606 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
12607 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010012608 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012609 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12610 execute( TC_ho_into_this_bsc_tla_v6() );
12611 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020012612 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030012613 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010012614 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020012615 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020012616 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
12617 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012618 execute( TC_ho_in_fail_msc_clears() );
12619 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
12620 execute( TC_ho_in_fail_no_detect() );
12621 execute( TC_ho_in_fail_no_detect2() );
Oliver Smith7a8594a2023-02-13 14:30:49 +010012622 execute( TC_ho_in_fail_mgw_mdcx_timeout() );
Oliver Smith4eed06f2023-02-15 15:43:19 +010012623 execute( TC_ho_in_fail_ipa_crcx_timeout() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010012624 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012625
Neels Hofmeyr91401012019-07-11 00:42:35 +020012626 execute( TC_ho_neighbor_config_1() );
12627 execute( TC_ho_neighbor_config_2() );
12628 execute( TC_ho_neighbor_config_3() );
12629 execute( TC_ho_neighbor_config_4() );
12630 execute( TC_ho_neighbor_config_5() );
12631 execute( TC_ho_neighbor_config_6() );
12632 execute( TC_ho_neighbor_config_7() );
12633
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012634 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010012635 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010012636 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020012637
12638 execute( TC_dyn_pdch_ipa_act_deact() );
12639 execute( TC_dyn_pdch_ipa_act_nack() );
12640 execute( TC_dyn_pdch_osmo_act_deact() );
12641 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010012642 execute( TC_dyn_ts_sdcch8_act_deact() );
12643 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
12644 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
12645 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012646
Stefan Sperling0796a822018-10-05 13:01:39 +020012647 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020012648 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020012649
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010012650 /* Power control related */
12651 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020012652 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020012653
12654 /* MSC pooling */
12655 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
12656 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
12657 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
12658 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
12659 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12660 execute( TC_mscpool_L3Compl_on_1_msc() );
12661 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
12662 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
12663 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
12664 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
12665 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
12666 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
12667 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
12668 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
12669 execute( TC_mscpool_paging_and_response_imsi() );
12670 execute( TC_mscpool_paging_and_response_tmsi() );
12671 execute( TC_mscpool_no_allow_attach_round_robin() );
12672 execute( TC_mscpool_no_allow_attach_valid_nri() );
Neels Hofmeyr2bdc6b62023-04-05 02:45:19 +020012673
12674 execute( TC_mscpool_sccp_n_pcstate_detaches_msc() );
Neels Hofmeyr38632aa2023-04-05 03:50:51 +020012675 execute( TC_mscpool_sccp_n_pcstate_attaches_msc() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020012676 }
12677
Harald Welte99f3ca02018-06-14 13:40:29 +020012678 execute( TC_early_conn_fail() );
12679 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020012680 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012681
Philipp Maier783681c2020-07-16 16:47:06 +020012682 /* Emergency call handling (deny / allow) */
12683 execute( TC_assignment_emerg_setup_allow() );
Pau Espin Pedrolb27653c2023-01-03 14:07:21 +010012684 execute( TC_assignment_emerg_setup_allow_imei() );
Philipp Maier783681c2020-07-16 16:47:06 +020012685 execute( TC_assignment_emerg_setup_deny_msc() );
12686 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020012687 execute( TC_emerg_premption() );
12688
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070012689 /* Frequency hopping parameters handling */
12690 execute( TC_fh_params_chan_activ() );
12691 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070012692 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070012693 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070012694 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012695
12696 if (mp_enable_lcs_tests) {
12697 execute( TC_lcs_loc_req_for_active_ms() );
12698 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
12699 execute( TC_lcs_loc_req_for_idle_ms() );
12700 execute( TC_lcs_loc_req_no_subscriber() );
12701 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
12702 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
12703 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
12704 execute( TC_cm_service_during_lcs_loc_req() );
12705 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020012706 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020012707 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() );
12708 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012709 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000012710
12711 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000012712
12713 execute( TC_refuse_chan_act_to_vamos() );
12714 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000012715
12716 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020012717
12718 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020012719
12720 execute( TC_imm_ass_post_chan_ack() );
12721 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020012722 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020012723 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020012724 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020012725
12726 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012727
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020012728 execute( TC_ratectr_all_available_allocated() );
12729 execute( TC_ratectr_all_available_allocated_dyn() );
12730
Neels Hofmeyrb7581872021-11-07 14:02:49 +010012731 execute( TC_cm_serv_rej() );
12732
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012733 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012734
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012735 /* Channel allocator */
12736 execute( TC_chan_alloc_algo_ascending() );
12737 execute( TC_chan_alloc_algo_descending() );
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012738 execute( TC_chan_alloc_algo_ass_dynamic() );
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012739
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012740 /* MGW pool */
Pau Espin Pedrol4e431832023-02-08 12:43:47 +010012741 execute( TC_mgwpool_all_used() );
12742 execute( TC_mgwpool_blocked_not_used() );
12743 execute( TC_mgwpool_pin_bts() );
Pau Espin Pedrolbd598422023-06-15 17:29:09 +020012744 execute( TC_mgwpool_keepalive_down_not_used() );
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012745
Oliver Smithc9a5f532022-10-21 11:32:23 +020012746 execute( TC_ho_meas_rep_multi_band() );
12747
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012748 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
12749 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
12750 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010012751}
12752
12753}