blob: 4753ae9376d7d0c08f49df1d427826c61458f352 [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;
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020025
Neels Hofmeyr4f118412020-06-04 15:25:10 +020026import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010027import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010028import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010029import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010030import from IPL4asp_Types all;
31
Harald Welte6f521d82017-12-11 19:52:02 +010032import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020033import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020034import from BSSAP_LE_Adapter all;
35import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020036import from BSSAP_LE_Types all;
37import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010038import from BSSAP_CodecPort all;
39import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010040import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010041import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010042import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020043import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010044import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010045import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010046import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010047import from MGCP_Templates all;
48import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020049import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010050
Harald Welte96c94412017-12-09 03:12:45 +010051import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010052import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010053import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010054
Daniel Willmannebdecc02020-08-12 15:30:17 +020055import from StatsD_Types all;
56import from StatsD_CodecPort all;
57import from StatsD_CodecPort_CtrlFunct all;
58import from StatsD_Checker all;
59
Harald Weltebc03c762018-02-12 18:09:38 +010060import from Osmocom_VTY_Functions all;
61import from TELNETasp_PortType all;
62
Harald Welte6f521d82017-12-11 19:52:02 +010063import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010064import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010065import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010066import from L3_Templates all;
67import from GSM_RR_Types all;
68
Stefan Sperlingc307e682018-06-14 15:15:46 +020069import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010070import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020071import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010072
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010073import from SCCPasp_Types all;
74
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020075import from GSM_SystemInformation all;
76import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020077import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020078
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060079const integer NUM_TRX := 4;
Harald Welte5d1a2202017-12-13 19:51:29 +010080const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020081const integer NUM_BTS_CFG := 4; /* we have 4 BTS in the osmo-bsc.cfg (for inter-BSC HO tests) but use only 3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060082const 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 +020083const integer NUM_MSC := 3;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020084const integer NUM_MGW := 2;
Harald Welteae026692017-12-09 01:03:01 +010085const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010086
Harald Welte799c97b2017-12-14 17:50:30 +010087/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020088const integer NUM_TCHH_PER_BTS := 2;
89const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020090const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010091
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060092friend type record BtsTrxIdx {
93 uint8_t bts,
94 uint8_t trx
95}
96
97private type record BtsParams {
98 integer trx_num,
99 integer tsc
100}
101
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200102/* Default Training Sequence Code expected for bts[i]:
103 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
104 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
105 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
106 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
107 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600108private const BtsParams c_BtsParams[NUM_BTS_CFG] := {
109 /* BTS0 */ { trx_num := 1, tsc := 2 },
110 /* BTS1 */ { trx_num := 1, tsc := 3 },
Vadim Yanitskiy7a3d2932022-05-29 20:37:46 +0600111 /* BTS2 */ { trx_num := 4, tsc := 4 },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600112 /* BTS3 */ { trx_num := 1, tsc := 4 }
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200113}
Harald Welte4003d112017-12-09 22:35:39 +0100114
Vadim Yanitskiy59494702022-09-14 15:29:04 +0700115private const RSL_IE_Body c_mr_conf_5_90 :=
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +0200116 valueof(RSL_IE_Body:{multirate_cfg := ts_RSL_MultirateCfg(true, 0, '00000100'B /* 5,90k */)});
117
Harald Welte21b46bd2017-12-17 19:46:32 +0100118/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100119type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100120 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100121 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100122}
123
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200124/* Default list of counters for an 'msc' entity. */
125const CounterNameVals counternames_msc_mscpool := {
126 { "mscpool:subscr:new", 0 },
127 { "mscpool:subscr:known", 0 },
128 { "mscpool:subscr:reattach", 0 },
129 { "mscpool:subscr:attach_lost", 0 },
130 { "mscpool:subscr:paged", 0 }
131};
132
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000133/* List of global mscpool counters, not related to a specific 'msc' entity. */
134const CounterNameVals counternames_bsc_mscpool := {
135 { "mscpool:subscr:no_msc", 0 }
136};
137
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000138/* Default list of counters for 'bsc' and 'bts' entities. */
139const CounterNameVals counternames_bsc_bts_handover := {
140 { "assignment:attempted", 0 },
141 { "assignment:completed", 0 },
142 { "assignment:stopped", 0 },
143 { "assignment:no_channel", 0 },
144 { "assignment:timeout", 0 },
145 { "assignment:failed", 0 },
146 { "assignment:error", 0 },
147
148 { "handover:attempted", 0 },
149 { "handover:completed", 0 },
150 { "handover:stopped", 0 },
151 { "handover:no_channel", 0 },
152 { "handover:timeout", 0 },
153 { "handover:failed", 0 },
154 { "handover:error", 0 },
155
156 { "intra_cell_ho:attempted", 0 },
157 { "intra_cell_ho:completed", 0 },
158 { "intra_cell_ho:stopped", 0 },
159 { "intra_cell_ho:no_channel", 0 },
160 { "intra_cell_ho:timeout", 0 },
161 { "intra_cell_ho:failed", 0 },
162 { "intra_cell_ho:error", 0 },
163
164 { "intra_bsc_ho:attempted", 0 },
165 { "intra_bsc_ho:completed", 0 },
166 { "intra_bsc_ho:stopped", 0 },
167 { "intra_bsc_ho:no_channel", 0 },
168 { "intra_bsc_ho:timeout", 0 },
169 { "intra_bsc_ho:failed", 0 },
170 { "intra_bsc_ho:error", 0 },
171
172 { "interbsc_ho_out:attempted", 0 },
173 { "interbsc_ho_out:completed", 0 },
174 { "interbsc_ho_out:stopped", 0 },
175 { "interbsc_ho_out:timeout", 0 },
176 { "interbsc_ho_out:failed", 0 },
177 { "interbsc_ho_out:error", 0 },
178
179 { "interbsc_ho_in:attempted", 0 },
180 { "interbsc_ho_in:completed", 0 },
181 { "interbsc_ho_in:stopped", 0 },
182 { "interbsc_ho_in:no_channel", 0 },
183 { "interbsc_ho_in:timeout", 0 },
184 { "interbsc_ho_in:failed", 0 },
185 { "interbsc_ho_in:error", 0 }
186};
187
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100188const CounterNameVals counternames_bts_handover := {
189 { "incoming_intra_bsc_ho:attempted", 0 },
190 { "incoming_intra_bsc_ho:completed", 0 },
191 { "incoming_intra_bsc_ho:stopped", 0 },
192 { "incoming_intra_bsc_ho:no_channel", 0 },
193 { "incoming_intra_bsc_ho:timeout", 0 },
194 { "incoming_intra_bsc_ho:failed", 0 },
195 { "incoming_intra_bsc_ho:error", 0 }
196};
197
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200198/* Set of all System Information received during one RSL port's startup.
199 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
200 * broadcast that SI type. That will be reflected as 'omit' here.
201 */
202type record SystemInformationConfig {
203 SystemInformationType1 si1 optional,
204 SystemInformationType2 si2 optional,
205 SystemInformationType2bis si2bis optional,
206 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200207 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200208 SystemInformationType3 si3 optional,
209 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100210 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200211 SystemInformationType5 si5 optional,
212 SystemInformationType5bis si5bis optional,
213 SystemInformationType5ter si5ter optional,
214 SystemInformationType6 si6 optional
215};
216
217const SystemInformationConfig SystemInformationConfig_omit := {
218 si1 := omit,
219 si2 := omit,
220 si2bis := omit,
221 si2ter := omit,
222 si2quater := omit,
223 si3 := omit,
224 si4 := omit,
225 si13 := omit,
226 si5 := omit,
227 si5bis := omit,
228 si5ter := omit,
229 si6 := omit
230};
231
232/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
233template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
234 template uint3_t meas_bw := 3)
235:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
236 meas_bw_presence := '1'B,
237 meas_bw := meas_bw);
238
239/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200240template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200241 template uint3_t prio := 3,
242 template (present) uint5_t thresh_high := 20,
243 template uint5_t thresh_low := 10,
244 template uint5_t qrxlevmin := 22)
245:= tr_EUTRAN_NeighbourCells(
246 cell_desc_list := cell_desc_list,
247 prio_presence := '1'B,
248 prio := prio,
249 thresh_high := thresh_high,
250 thresh_low_presence := '1'B,
251 thresh_low := thresh_low,
252 qrxlevmin_presence := '1'B,
253 qrxlevmin := qrxlevmin);
254
255template SystemInformationConfig SystemInformationConfig_default := {
256 si1 := {
257 cell_chan_desc := '8FB38000000000000000000000000000'O,
258 rach_control := {
259 max_retrans := RACH_MAX_RETRANS_7,
260 tx_integer := '1001'B,
261 cell_barr_access := false,
262 re_not_allowed := true,
263 acc := '0000010000000000'B
264 },
265 rest_octets := ?
266 },
267 si2 := {
268 bcch_freq_list := '00000000000000000000000000000000'O,
269 ncc_permitted := '11111111'B,
270 rach_control := {
271 max_retrans := RACH_MAX_RETRANS_7,
272 tx_integer := '1001'B,
273 cell_barr_access := false,
274 re_not_allowed := true,
275 acc := '0000010000000000'B
276 }
277 },
278 si2bis := omit,
279 si2ter := {
280 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
281 rest_octets := ?
282 },
283 si2quater := {
284 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
285 },
286 si3 := {
287 cell_id := 0,
288 lai := {
289 mcc_mnc := '001F01'H,
290 lac := 1
291 },
292 ctrl_chan_desc := {
293 msc_r99 := true,
294 att := true,
295 bs_ag_blks_res := 1,
296 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
297 si22ind := false,
298 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
299 spare := '00'B,
300 bs_pa_mfrms := 3,
301 t3212 := 30
302 },
303 cell_options := {
304 dn_ind := false,
305 pwrc := false,
306 dtx := MS_SHALL_USE_UL_DTX,
307 radio_link_tout_div4 := 7
308 },
309 cell_sel_par := {
310 cell_resel_hyst_2dB := 2,
311 ms_txpwr_max_cch := 7,
312 acs := '0'B,
313 neci := true,
314 rxlev_access_min := 0
315 },
316 rach_control := {
317 max_retrans := RACH_MAX_RETRANS_7,
318 tx_integer := '1001'B,
319 cell_barr_access := false,
320 re_not_allowed := true,
321 acc := '0000010000000000'B
322 },
323 rest_octets := {
324 sel_params := {
325 presence := '0'B,
326 params := omit
327 },
328 pwr_offset := {
329 presence := '0'B,
330 offset := omit
331 },
332 si_2ter_ind := '1'B,
333 early_cm_ind := '0'B,
334 sched_where := {
335 presence := '0'B,
336 where := omit
337 },
338 gprs_ind := {
339 presence := '1'B,
340 ind := {
341 ra_colour := 0,
342 si13_pos := '0'B
343 }
344 },
345 umts_early_cm_ind := '1'B,
346 si2_quater_ind := {
347 presence := '1'B,
348 ind := '0'B
349 },
350 iu_mode_ind := omit,
351 si21_ind := {
352 presence := '0'B,
353 pos := omit
354 }
355 }
356 },
357 si4 := {
358 lai := {
359 mcc_mnc := '001F01'H,
360 lac := 1
361 },
362 cell_sel_par := {
363 cell_resel_hyst_2dB := 2,
364 ms_txpwr_max_cch := 7,
365 acs := '0'B,
366 neci := true,
367 rxlev_access_min := 0
368 },
369 rach_control := {
370 max_retrans := RACH_MAX_RETRANS_7,
371 tx_integer := '1001'B,
372 cell_barr_access := false,
373 re_not_allowed := true,
374 acc := '0000010000000000'B
375 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200376 cbch_chan_desc := {
377 iei := '64'O,
378 v := {
379 chan_nr := {
380 u := {
381 sdcch4 := {
382 tag := '001'B,
383 sub_chan := 2
384 }
385 },
386 tn := 0
387 },
388 tsc := 2,
389 h := false,
390 arfcn := 871,
391 maio_hsn := omit
392 }
393 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200394 cbch_mobile_alloc := omit,
395 rest_octets := {
396 sel_params := {
397 presence := '0'B,
398 params := omit
399 },
400 pwr_offset := {
401 presence := '0'B,
402 offset := omit
403 },
404 gprs_ind := {
405 presence := '1'B,
406 ind := {
407 ra_colour := 0,
408 si13_pos := '0'B
409 }
410 },
411 s_presence := '0'B,
412 s := omit
413 }
414 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100415 si13 := {
416 rest_octets := {
417 presence := '1'B,
418 bcch_change_mark := ?,
419 si_change_field := '0000'B,
420 presence2 := '0'B,
421 si13_change_mark := omit,
422 gprs_ma := omit,
423 zero := '0'B, /* PBCCH not present in cell */
424 rac := 0,
425 spgc_ccch_sup := '0'B,
426 priority_access_thr := '110'B,
427 network_control_order := '00'B,
428 gprs_cell_opts := {
429 nmo := '01'B,
430 t3168 := '011'B,
431 t3192 := '010'B,
432 drx_timer_max := '011'B,
433 access_burst_type := '0'B,
434 control_ack_type := '1'B,
435 bs_cv_max := 15,
436 pan_presence := '1'B,
437 pan_dec := 1,
438 pan_inc := 1,
439 pan_max := '111'B,
440 ext_info_presence := ?,
441 ext_info_length := *,
442 ext_info := *
443 },
444 gprs_pwr_ctrl_params := {
445 alpha := 0,
446 t_avg_w := '10000'B,
447 t_avg_t := '10000'B,
448 pc_meas_chan := '0'B,
449 n_avg_i := '1000'B
450 }
451 }
452 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200453 si5 := {
454 bcch_freq_list := '10000000000000000000000000000000'O
455 },
456 si5bis := omit,
457 si5ter := {
458 extd_bcch_freq_list := '9E050020000000000000000000000000'O
459 },
460 si6 := {
461 cell_id := 0,
462 lai := {
463 mcc_mnc := '001F01'H,
464 lac := 1
465 },
466 cell_options := {
467 dtx_ext := '1'B,
468 pwrc := false,
469 dtx := '01'B,
470 radio_link_timeout := '0111'B
471 },
472 ncc_permitted := '11111111'B,
Vadim Yanitskiy348b07c2022-03-10 17:11:22 +0300473 rest_octets := {
474 pch_nch_info := ?,
475 vbs_vgcs_options := ?,
476 dtm_support := '0'B,
477 rac := omit,
478 max_lapdm := omit,
479 band_ind := '0'B /* C0 ARFCN indicates 1800 band */
480 }
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200481 }
482 };
483
484
485/* List of all the System Information received on all RSL ports */
486type record of SystemInformationConfig SystemInformationConfig_list;
487
488function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
489{
490 var RSL_IE_Body sysinfo_type_ie;
491 var RSL_IE_SysinfoType si_type;
492 var octetstring data;
493
494 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
495 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
496 mtc.stop;
497 }
498 si_type := sysinfo_type_ie.sysinfo_type;
499
500 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
501 var RSL_IE_Body bcch_ie;
502 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
503 data := bcch_ie.other.payload;
504 }
505 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
506 var RSL_IE_Body l3_ie;
507 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
508 data := l3_ie.l3_info.payload;
509 }
510 } else {
511 setverdict(fail, "Don't understand this System Information message");
512 mtc.stop;
513 }
514
515 var boolean handled := false;
516
517 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
518 handled := true;
519
520 if (si_type == RSL_SYSTEM_INFO_1) {
521 if (not isbound(data)) {
522 si.si1 := omit;
523 } else {
524 si.si1 := dec_SystemInformation(data).payload.si1;
525 }
526 } else if (si_type == RSL_SYSTEM_INFO_2) {
527 if (not isbound(data)) {
528 si.si2 := omit;
529 } else {
530 si.si2 := dec_SystemInformation(data).payload.si2;
531 }
532 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
533 if (not isbound(data)) {
534 si.si2bis := omit;
535 } else {
536 si.si2bis := dec_SystemInformation(data).payload.si2bis;
537 }
538 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
539 if (not isbound(data)) {
540 si.si2ter := omit;
541 } else {
542 si.si2ter := dec_SystemInformation(data).payload.si2ter;
543 }
544 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
545 if (not isbound(data)) {
546 si.si2quater := {};
547 } else {
548 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
549 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
550 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
551 }
552 } else if (si_type == RSL_SYSTEM_INFO_3) {
553 if (not isbound(data)) {
554 si.si3 := omit;
555 } else {
556 si.si3 := dec_SystemInformation(data).payload.si3;
557 }
558 } else if (si_type == RSL_SYSTEM_INFO_4) {
559 if (not isbound(data)) {
560 si.si4 := omit;
561 } else {
562 si.si4 := dec_SystemInformation(data).payload.si4;
563 }
564 } else if (si_type == RSL_SYSTEM_INFO_13) {
565 if (not isbound(data)) {
566 si.si13 := omit;
567 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100568 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200569 }
570 } else {
571 handled := false;
572 }
573 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
574 handled := true;
575
576 if (si_type == RSL_SYSTEM_INFO_5) {
577 if (not isbound(data)) {
578 si.si5 := omit;
579 } else {
580 si.si5 := dec_SystemInformation(data).payload.si5;
581 }
582 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
583 if (not isbound(data)) {
584 si.si5bis := omit;
585 } else {
586 si.si5bis := dec_SystemInformation(data).payload.si5bis;
587 }
588 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
589 if (not isbound(data)) {
590 si.si5ter := omit;
591 } else {
592 si.si5ter := dec_SystemInformation(data).payload.si5ter;
593 }
594 } else if (si_type == RSL_SYSTEM_INFO_6) {
595 if (not isbound(data)) {
596 si.si6 := omit;
597 } else {
598 si.si6 := dec_SystemInformation(data).payload.si6;
599 }
600 } else {
601 handled := false;
602 }
603 }
604
605 if (not handled) {
606 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
607 }
608}
609
Harald Weltea4ca4462018-02-09 00:17:14 +0100610type component test_CT extends CTRL_Adapter_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600611 /* Array of per-BTS/TRX state */
612 var BTS_State bts[NUM_BTS][NUM_TRX];
Harald Welte89ab1912018-02-23 18:56:29 +0100613 /* RSL common Channel Port (for RSL_Emulation) */
614 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600615 /* array of per-BTS/TRX RSL test ports */
616 port IPA_RSL_PT IPA_RSL[NUM_BTS][NUM_TRX];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100617 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200618 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
619 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200620 /* Configure/manage IPA_Emulation per-BTS/TRX port: */
621 port IPA_CFG_PT IPA_CFG_PORT[NUM_BTS][NUM_TRX];
Harald Weltea5d2ab22017-12-09 14:21:42 +0100622
Pau Espin Pedrol3c630532022-10-20 19:00:11 +0200623 var MGCP_Emulation_CT vc_MGCP[NUM_MGW];
624 var integer g_nr_mgw; /* number of vc_MGCP to initialize */
Harald Weltebc03c762018-02-12 18:09:38 +0100625 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100626
Daniel Willmannebdecc02020-08-12 15:30:17 +0200627 /* StatsD */
628 var StatsD_Checker_CT vc_STATSD;
629
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200630 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200631 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100632 /* for old legacy-tests only */
633 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200634 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100635
Harald Welte21b46bd2017-12-17 19:46:32 +0100636 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100637 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100638
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200639 /* Osmux is enabled through VTY */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200640 var boolean g_osmux_enabled_cn := false;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +0200641 var boolean g_osmux_enabled_bts := false;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200642
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100643 /*Configure T(tias) over VTY, seconds */
644 var integer g_bsc_sccp_timer_ias := 7 * 60;
645 /*Configure T(tiar) over VTY, seconds */
646 var integer g_bsc_sccp_timer_iar := 15 * 60;
647
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200648 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100649 timer T_guard := 30.0;
650
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200651 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000652 var CounterNameValsList g_ctr_bsc;
653 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200654
655 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
656 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100657}
658
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200659type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100660modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100661 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100662 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100663 /* port number to which to establish the IPA OML connections */
664 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100665 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100666 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100667 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100668 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200669 /* port number to which to listen for STATSD metrics */
670 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100671 /* IP address at which the test binds */
672 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100673
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200674 RAN_Configurations mp_bssap_cfg := {
675 {
676 transport := BSSAP_TRANSPORT_AoIP,
677 sccp_service_type := "mtp3_itu",
678 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
679 own_pc := 185, /* 0.23.1 first MSC emulation */
680 own_ssn := 254,
681 peer_pc := 187, /* 0.23.3 osmo-bsc */
682 peer_ssn := 254,
683 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200684 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200685 },
686 {
687 transport := BSSAP_TRANSPORT_AoIP,
688 sccp_service_type := "mtp3_itu",
689 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
690 own_pc := 2, /* 0.0.2 second MSC emulation */
691 own_ssn := 254,
692 peer_pc := 187, /* 0.23.3 osmo-bsc */
693 peer_ssn := 254,
694 sio := '83'O,
695 rctx := 2
696 },
697 {
698 transport := BSSAP_TRANSPORT_AoIP,
699 sccp_service_type := "mtp3_itu",
700 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
701 own_pc := 3, /* 0.0.3 third MSC emulation */
702 own_ssn := 254,
703 peer_pc := 187, /* 0.23.3 osmo-bsc */
704 peer_ssn := 254,
705 sio := '83'O,
706 rctx := 3
707 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100708 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200709
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200710 /* Must match per BTS config in osmo-bsc.cfg */
711 phys_chan_configs phys_chan_config := {
712 "CCCH+SDCCH4+CBCH",
713 "TCH/F",
714 "TCH/F",
715 "TCH/F",
716 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600717 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200718 "PDCH",
719 "PDCH"
720 };
721
Harald Welte47cd0e32020-08-21 12:39:11 +0200722 BSSAP_LE_Configuration mp_bssap_le_cfg := {
723 sccp_service_type := "mtp3_itu",
724 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200725 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200726 own_ssn := 252, /* SMLC side SSN */
727 peer_pc := 187, /* 0.23.3 osmo-bsc */
728 peer_ssn := 250, /* BSC side SSN */
729 sio := '83'O,
730 rctx := 6
731 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200732 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200733
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100734 /* Value set in osmo-bsc.cfg "ms max power" */
735 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600736
737 /* Whether to check for memory leaks */
738 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100739}
740
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200741friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200742
743 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200744 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200745 pars.aoip := true;
746 } else {
747 pars.aoip := false;
748 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100749 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200750 pars.mscpool.bssap_idx := bssap_idx;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600751 pars.expect_tsc := c_BtsParams[0].tsc;
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300752 pars.imsi := f_rnd_imsi('00101'H);
753
754 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200755
Philipp Maier48604732018-10-09 15:00:37 +0200756 return pars;
757}
758
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200759/* Convenience functions for rate counters using g_ctr_msc. */
760
761private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
762 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
763 log("initial msc rate counters: ", g_ctr_msc);
764}
765
766private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200767 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200768}
769
770/* f_ctrs_msc_init();
771 * f_do_thing(on_msc := 0);
772 * f_do_thing(on_msc := 0);
773 * f_do_other(on_msc := 1);
774 * f_ctrs_msc_add(0, "thing", 2);
775 * f_ctrs_msc_add(1, "other");
776 * f_ctrs_msc_verify();
777 */
778private function f_ctrs_msc_verify() runs on test_CT {
779 log("verifying msc rate counters: ", g_ctr_msc);
780 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
781}
782
783/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
784 * f_ctrs_msc_init();
785 * f_do_thing(on_msc := 0);
786 * f_do_thing(on_msc := 0);
787 * f_do_thing(on_msc := 0);
788 * f_ctrs_msc_expect(0, "thing", 3);
789 */
790private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
791 f_ctrs_msc_add(msc_nr, countername, val);
792 f_ctrs_msc_verify();
793}
794
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000795/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
796
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100797private 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 +0000798 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100799 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100800}
801
802function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
803 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000804 f_ctrs_bsc_init(counternames);
805}
806
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100807private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
808 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100809 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100810 f_ctrs_bsc_init(counternames_bsc_bts_handover);
811}
812
813private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000814 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100815}
816
817private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
818 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000819 f_ctrs_bsc_add(countername, val);
820}
821
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100822function f_ctrs_bts_verify() runs on test_CT {
823 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
824}
825
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000826/* f_ctrs_bsc_and_bts_init();
827 * f_do_thing(on_bts := 0);
828 * f_do_thing(on_bts := 0);
829 * f_do_other(on_bts := 1);
830 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
831 * f_ctrs_bsc_and_bts_add(1, "other");
832 * f_ctrs_bsc_and_bts_verify();
833 */
834private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100835 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000836 f_ctrs_bsc_verify();
837}
838
839/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
840 * f_ctrs_bsc_and_bts_init();
841 * f_do_thing(on_bts := 0);
842 * f_do_thing(on_bts := 0);
843 * f_do_thing(on_bts := 0);
844 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
845 */
846private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
847 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
848 f_ctrs_bsc_and_bts_verify();
849}
850
851
852/* Convenience functions for rate counters using g_ctr_bsc. */
853
854private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
855 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
856 log("initial bsc rate counters: ", g_ctr_bsc);
857}
858
859private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
860 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
861}
862
863/* f_ctrs_bsc_init();
864 * f_do_thing();
865 * f_do_thing();
866 * f_do_other();
867 * f_ctrs_bsc_add("thing", 2);
868 * f_ctrs_bsc_add("other");
869 * f_ctrs_bsc_verify();
870 */
871private function f_ctrs_bsc_verify() runs on test_CT {
872 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
873}
874
875/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
876 * f_ctrs_bsc_init();
877 * f_do_thing();
878 * f_ctrs_bsc_expect("thing", 1);
879 */
880private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
881 f_ctrs_bsc_add(countername, val);
882 f_ctrs_bsc_verify();
883}
884
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200885
Oliver Smith39f53072022-10-27 14:44:04 +0200886friend function f_shutdown_helper(boolean ho := false) runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100887 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600888 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100889 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
890 }
891
Oliver Smith39f53072022-10-27 14:44:04 +0200892 /* Reset handover related configuration */
893 if (ho) {
894 f_bts_0_cfg(BSCVTY,
895 {"no neighbors",
896 "neighbor-list mode manual-si5",
897 "neighbor-list add arfcn 100",
898 "neighbor-list add arfcn 200",
899 "si5 neighbor-list add arfcn 10",
900 "si5 neighbor-list add arfcn 20",
901 "handover algorithm 1"});
902 }
903
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200904 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100905 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200906 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100907}
908
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200909private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100910 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200911 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100912 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200913 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 +0200914 ts_BSSMAP_Reset(0, g_osmux_enabled_cn)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100915 T.start;
916 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200917 [] 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 +0200918 tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200919 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100920 }
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200921 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200922 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100923 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200924 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200925 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100926 repeat;
927 }
928 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200929 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200930 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200931 /* If we received a RESET after ours was sent, it
932 may be a race condition where the other peer beacame
933 available after we sent it, but we are in a desired
934 state anyway, so go forward. */
935 if (not reset_received) {
936 setverdict(fail);
937 }
938 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100939 }
Harald Welte28d943e2017-11-25 15:00:50 +0100940}
941
Harald Welteae026692017-12-09 01:03:01 +0100942type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100943 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100944 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100945 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100946 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100947 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100948 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100949 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100950 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100951}
952
Harald Welte21b46bd2017-12-17 19:46:32 +0100953/*! Start the IPA/RSL related bits for one IPA_Client.
954 * \param clnt IPA_Client for which to establish
955 * \param bsc_host IP address / hostname of the BSC
956 * \param bsc_port TCP port number of the BSC
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600957 * \param idx BTS/TRX index values
Harald Welte21b46bd2017-12-17 19:46:32 +0100958 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600959function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port,
960 BtsTrxIdx idx := {0, 0}, boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100961runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100962 timer T := 10.0;
963
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600964 clnt.id := "IPA-BTS" & int2str(idx.bts) & "-TRX" & int2str(idx.trx) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100965 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100966 clnt.ccm_pars := c_IPA_default_ccm_pars;
967 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600968 clnt.ccm_pars.unit_id := int2str(1234 + idx.bts) & "/0/" & int2str(idx.trx);
Harald Welte624f9632017-12-16 19:26:04 +0100969 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100970 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600971 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[idx.bts]);
Harald Welte624f9632017-12-16 19:26:04 +0100972 }
Harald Welteae026692017-12-09 01:03:01 +0100973
974 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200975 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100976 if (handler_mode) {
977 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
978 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600979 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100980 }
Harald Welteae026692017-12-09 01:03:01 +0100981
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600982 var integer local_port := 10000 + idx.bts * 1000 + idx.trx;
983 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", local_port, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100984 if (handler_mode) {
985 clnt.vc_RSL.start(RSL_Emulation.main());
986 return;
987 }
Harald Welteae026692017-12-09 01:03:01 +0100988
989 /* wait for IPA RSL link to connect and send ID ACK */
990 T.start;
991 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600992 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100993 T.stop;
Harald Welteae026692017-12-09 01:03:01 +0100994 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600995 [] IPA_RSL[idx.bts][idx.trx].receive(ASP_IPA_Event:?) { repeat }
996 [] IPA_RSL[idx.bts][idx.trx].receive { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100997 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100998 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200999 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +01001000 }
1001 }
1002}
1003
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001004function f_ipa_rsl_stop(inout IPA_Client clnt, BtsTrxIdx idx := {0, 0}) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001005 var IPL4asp_Types.Result res := {
1006 errorCode := omit,
1007 connId := omit,
1008 os_error_code := omit,
1009 os_error_text := omit
1010 };
1011
Harald Welte12055472018-03-17 20:10:08 +01001012 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
1013 return;
1014 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001015
1016 /* Alive components don't finish sockets (TCP FIN) when they are
1017 * stopped. Hence, we need to manually call close() on them to make sure
1018 * the IUT knows about it. */
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001019 f_ipa_cfg_disconnect(IPA_CFG_PORT[idx.bts][idx.trx], res);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001020
Harald Welte12055472018-03-17 20:10:08 +01001021 clnt.vc_IPA.stop;
1022 if (isbound(clnt.vc_RSL)) {
1023 clnt.vc_RSL.stop;
1024 }
1025}
1026
Harald Welte21b46bd2017-12-17 19:46:32 +01001027/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +01001028function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1029 timer T := secs_max;
1030 T.start;
1031 while (true) {
1032 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1033 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001034 /* the 'degraded' state exists from OML connection time, and we have to wait
1035 * until all MO's are initialized */
1036 T.start(1.0);
1037 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001038 return;
1039 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001040 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001041 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001042 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001043 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001044 }
1045 }
1046}
1047
Harald Welte21b46bd2017-12-17 19:46:32 +01001048/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001049altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001050 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001051 [] T_guard.timeout {
1052 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001053 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001054 }
Harald Welte60e823a2017-12-10 14:10:59 +01001055 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001056 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001057 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001058 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Harald Welte69c1c262017-12-13 21:02:08 +01001059 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001060 }
Harald Welte28d943e2017-11-25 15:00:50 +01001061}
1062
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001063altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001064 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001065 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001066 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001067 }
1068}
1069
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001070function f_init_mgcp(integer mgw_nr, charstring id) runs on test_CT {
1071 id := id & "-MGCP-" & int2str(mgw_nr);
Daniel Willmann191e0d92018-01-17 12:44:35 +01001072
1073 var MGCPOps ops := {
1074 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1075 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1076 };
1077 var MGCP_conn_parameters mgcp_pars := {
1078 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001079 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001080 mgw_ip := mp_test_ip,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001081 mgw_udp_port := 2427 + mgw_nr,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001082 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
Pau Espin Pedrol36eeaf72022-10-20 16:50:31 +02001083 the one with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001084 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001085 };
1086
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001087 vc_MGCP[mgw_nr] := MGCP_Emulation_CT.create(id) alive;
1088 vc_MGCP[mgw_nr].start(MGCP_Emulation.main(ops, mgcp_pars, id));
Daniel Willmann191e0d92018-01-17 12:44:35 +01001089}
1090
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001091/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1092 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1093 * OsmuxCID IE.
1094 */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001095private function f_vty_allow_osmux_cn(boolean allow) runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001096 f_vty_enter_cfg_msc(BSCVTY, 0);
1097 if (allow) {
1098 f_vty_transceive(BSCVTY, "osmux on");
1099 } else {
1100 f_vty_transceive(BSCVTY, "osmux off");
1101 }
1102 f_vty_transceive(BSCVTY, "exit");
1103 f_vty_transceive(BSCVTY, "exit");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001104}
1105
Max2253c0b2018-11-06 19:28:05 +01001106function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001107 if (BSCVTY.checkstate("Mapped")) {
1108 /* skip initialization if already executed once */
1109 return;
1110 }
Harald Weltebc03c762018-02-12 18:09:38 +01001111 map(self:BSCVTY, system:BSCVTY);
1112 f_vty_set_prompts(BSCVTY);
1113 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001114 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1115 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001116}
1117
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001118friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001119{
1120 // log on TTCN3 log output
1121 log(log_msg);
1122 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001123 if (pt.checkstate("Mapped")) {
1124 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1125 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001126}
1127
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001128private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1129{
1130 if (rsl_idx >= lengthof(g_system_information)) {
1131 g_system_information[rsl_idx] := SystemInformationConfig_omit
1132 }
1133 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1134}
1135
1136altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1137 var ASP_RSL_Unitdata rx_rsl_ud;
1138
1139 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001140 [] 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 +02001141 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1142 repeat;
1143 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001144 [] 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 +02001145 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1146 repeat;
1147 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001148 [] 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 +02001149 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1150 repeat;
1151 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001152 [] 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 +02001153 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1154 repeat;
1155 }
1156
1157 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1158 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1159 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1160 repeat;
1161 }
1162 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1163 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1164 repeat;
1165 }
1166 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1167 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1168 repeat;
1169 }
1170 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1171 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1172 repeat;
1173 }
1174}
1175
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001176/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1177private type record of boolean my_BooleanList;
1178
1179private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1180{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001181 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1182
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001183 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001184 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1185 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1186 * stepping into that config node. */
1187 log("msc ", msc_nr, " is not configured, skipping");
1188 continue;
1189 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001190 f_vty_enter_cfg_msc(pt, msc_nr);
1191 if (allow_attach_list[msc_nr]) {
1192 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1193 f_vty_transceive(pt, "allow-attach", strict := false);
1194 } else {
1195 f_vty_transceive(pt, "no allow-attach", strict := false);
1196 }
1197 f_vty_transceive(pt, "exit");
1198 f_vty_transceive(pt, "exit");
1199 }
1200}
1201
Harald Welte21b46bd2017-12-17 19:46:32 +01001202/* global initialization function
1203 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001204 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1205 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1206 */
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001207function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001208 integer nr_msc := 1, integer nr_mgw := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001209 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001210
Harald Welteae026692017-12-09 01:03:01 +01001211 if (g_initialized) {
1212 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001213 }
Harald Welteae026692017-12-09 01:03:01 +01001214 g_initialized := true;
1215
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001216 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001217 activate(as_Tguard());
1218
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001219 f_init_vty("VirtMSC");
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001220 f_vty_allow_osmux_cn(g_osmux_enabled_cn);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001221
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001222 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001223 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1224
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001225 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1226 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1227 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1228 }
1229
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001230 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001231 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001232 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1233 * MSC-side BSSAP emulation */
1234 if (handler_mode) {
1235 var RanOps ranops := MSC_RanOps;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001236 ranops.use_osmux := g_osmux_enabled_cn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001237 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1238 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1239 f_ran_adapter_start(g_bssap[bssap_idx]);
1240 } else {
1241 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1242 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1243 f_ran_adapter_start(g_bssap[bssap_idx]);
1244 f_legacy_bssap_reset();
1245 }
Harald Welte67089ee2018-01-17 22:19:03 +01001246 }
Harald Welted5833a82018-05-27 16:52:56 +02001247
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001248 if (mp_enable_lcs_tests) {
1249 if (handler_mode) {
1250 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1251 } else {
1252 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1253 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1254 }
1255 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001256 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001257
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001258 /* start the test with exactly all enabled MSCs allowed to attach */
1259 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1260
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001261 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001262
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001263 g_nr_mgw := nr_mgw;
1264 for (var integer i := 0; i < g_nr_mgw; i := i+1) {
1265 f_init_mgcp(i, "VirtMGW");
1266 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01001267
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001268 for (var integer i := 0; i < nr_bts; i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001269 f_init_bts(i, c_BtsParams[i].trx_num, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001270 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001271
1272 /* Emit a marker to appear in the SUT's own logging output */
1273 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001274}
Harald Welte696ddb62017-12-08 14:01:43 +01001275
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001276function f_init_bts(integer bts_idx := 0,
1277 integer trx_num := NUM_TRX_CFG,
1278 boolean handler_mode := false)
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001279runs on test_CT {
1280 /* wait until osmo-bts-omldummy has respawned */
1281 f_wait_oml(bts_idx, "degraded", 5.0);
1282
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001283 /* start RSL connection(s) */
1284 for (var integer trx_idx := 0; trx_idx < trx_num; trx_idx := trx_idx + 1) {
1285 f_ipa_rsl_start(bts[bts_idx][trx_idx].rsl,
1286 mp_bsc_ip, mp_bsc_rsl_port,
1287 {bts_idx, trx_idx}, handler_mode);
1288 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001289 /* wait until BSC tells us "connected" */
1290 f_wait_oml(bts_idx, "connected", 5.0);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001291
1292 /* Set up BTS with VTY commands: */
Vadim Yanitskiy4d852082022-09-14 14:07:20 +07001293 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
1294 f_vty_enter_cfg_bts(BSCVTY, bts_idx);
1295 if (g_osmux_enabled_bts) {
1296 f_vty_transceive(BSCVTY, "osmux on");
1297 } else {
1298 f_vty_transceive(BSCVTY, "osmux off");
1299 }
1300 f_vty_transceive(BSCVTY, "end");
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001301 }
Harald Welte28d943e2017-11-25 15:00:50 +01001302}
1303
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001304function f_init_bts_and_check_sysinfo(integer bts_idx := 0,
1305 integer trx_num := NUM_TRX_CFG,
1306 boolean handler_mode := false,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001307 template SystemInformationConfig expect_si)
1308runs on test_CT {
1309 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1310
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001311 f_init_bts(bts_idx, trx_num, handler_mode);
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001312
1313 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1314 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1315 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1316 */
1317 f_sleep(5.0);
1318 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1319
1320 deactivate(sysinfo);
1321
1322 if (match(g_system_information[bts_idx], expect_si)) {
1323 setverdict(pass);
1324 } else {
1325 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1326 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1327 setverdict(fail, "received SI does not match expectations");
1328 return;
1329 }
1330}
1331
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001332/* expect to receive a RSL message matching a specified template on a given BTS / TRX */
1333function f_exp_ipa_rx(template (present) RSL_Message t_rx,
1334 BtsTrxIdx idx := {0, 0},
1335 float Tval := 2.0)
Harald Welteae026692017-12-09 01:03:01 +01001336runs on test_CT return RSL_Message {
1337 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001338 timer T := Tval;
Harald Welteae026692017-12-09 01:03:01 +01001339
1340 T.start;
1341 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001342 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001343 T.stop;
1344 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001345 [] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001346 [] T.timeout {
1347 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001348 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001349 }
Harald Welteae026692017-12-09 01:03:01 +01001350 }
1351 return rx_rsl_ud.rsl;
1352}
1353
Harald Welte21b46bd2017-12-17 19:46:32 +01001354/* helper function to transmit RSL on a given BTS/stream */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001355function f_ipa_tx(template (value) RSL_Message t_tx,
1356 BtsTrxIdx idx := {0, 0},
1357 IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001358runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001359 IPA_RSL[idx.bts][idx.trx].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001360}
1361
1362
Harald Welte4003d112017-12-09 22:35:39 +01001363/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001364testcase TC_chan_act_noreply() runs on test_CT {
1365 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001366 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001367
Harald Welte89d42e82017-12-17 16:42:41 +01001368 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001369
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001370 f_ipa_tx(ts_RSL_CHAN_RQD('23'O, 23));
1371 rsl_unused := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001372 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001373}
1374
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001375const CounterNameVals counternames_bts_chreq := {
1376 { "chreq:total", 0 },
1377 { "chreq:attempted_emerg", 0 },
1378 { "chreq:attempted_call", 0 },
1379 { "chreq:attempted_location_upd", 0 },
1380 { "chreq:attempted_pag", 0 },
1381 { "chreq:attempted_pdch", 0 },
1382 { "chreq:attempted_other", 0 },
1383 { "chreq:attempted_unknown", 0 },
1384 { "chreq:successful", 0 },
1385 { "chreq:successful_emerg", 0 },
1386 { "chreq:successful_call", 0 },
1387 { "chreq:successful_location_upd", 0 },
1388 { "chreq:successful_pag", 0 },
1389 { "chreq:successful_pdch", 0 },
1390 { "chreq:successful_other", 0 },
1391 { "chreq:successful_unknown", 0 },
1392 { "chreq:no_channel", 0 },
1393 { "chreq:max_delay_exceeded", 0 }
1394};
1395
1396/* verify the "chreq:*" counters */
1397private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1398{
1399 var GsmFrameNumber fn := 23;
1400
1401 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1402
1403 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001404 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn));
1405 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001406 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1407
1408 f_ctrs_bts_add(0, "chreq:total");
1409 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1410 f_ctrs_bts_verify();
1411
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001412 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1413 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001414
1415 f_ctrs_bts_add(0, "chreq:successful");
1416 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1417 f_ctrs_bts_verify();
1418
1419 /* test is done, release RSL Conn Fail Ind to clean up */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001420 f_ipa_tx(ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1421 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
1422 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001423 f_sleep(1.0);
1424}
1425
Harald Welte4003d112017-12-09 22:35:39 +01001426testcase TC_chan_act_counter() runs on test_CT {
1427 var BSSAP_N_UNITDATA_ind ud_ind;
1428 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001429 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001430
Harald Welte89d42e82017-12-17 16:42:41 +01001431 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001432
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001433 f_vty_allow_emerg_bts(true, 0);
1434
1435 f_ctrs_bts_init(1, counternames_bts_chreq);
1436
1437 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1438 f_chan_act_counter('a3'O, "emerg");
1439
1440 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1441 f_chan_act_counter('43'O, "call");
1442
1443 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1444 f_chan_act_counter('03'O, "location_upd");
1445
1446 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1447 f_chan_act_counter('23'O, "pag");
1448 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1449 f_chan_act_counter('33'O, "pag");
1450
1451 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1452 /* no PCU, so PDCH not allowed. Skip this test for now. */
1453 /* f_chan_act_counter('7b'O, "pdch"); */
1454
1455 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1456 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001457
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001458 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001459}
1460
Harald Welteae026692017-12-09 01:03:01 +01001461/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001462private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001463 var RSL_Message rx_rsl;
1464
Harald Welteae026692017-12-09 01:03:01 +01001465 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001466 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001467
1468 /* expect BSC to disable the channel again if there's no RLL EST IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001469 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := T3101_MAX);
Harald Welteae026692017-12-09 01:03:01 +01001470
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001471 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001472}
1473
Philipp Maier9c60a622020-07-09 15:08:46 +02001474/* Normal variant */
1475testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001476 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001477 f_TC_chan_act_ack_noest();
1478}
1479
1480/* Emergency call variant */
1481testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1482 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001483 f_init(1);
1484 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001485 f_TC_chan_act_ack_noest(ra := 'A5'O);
1486}
1487
Philipp Maier606f07d2020-08-12 17:21:58 +02001488/* Emergency call variant, but emergency calls are not allowed */
1489testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1490 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1491
1492 var RSL_Message rx_rsl;
1493 var GsmRrMessage rr;
1494
1495 f_init(1);
1496 f_vty_allow_emerg_bts(false, 0);
1497
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001498 IPA_RSL[0][0].clear;
1499 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier606f07d2020-08-12 17:21:58 +02001500
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001501 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Philipp Maier606f07d2020-08-12 17:21:58 +02001502 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1503 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1504 setverdict(pass);
1505 } else {
1506 setverdict(fail, "immediate assignment not rejected");
1507 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001508
1509 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001510}
1511
Harald Welteae026692017-12-09 01:03:01 +01001512/* Test behavior if MSC never answers to CR */
1513testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001514 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1515 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001516 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001517 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001518
Harald Welte89d42e82017-12-17 16:42:41 +01001519 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001520
1521 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001522 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001523
1524 var octetstring l3 := '00010203040506'O
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001525 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welteae026692017-12-09 01:03:01 +01001526
1527 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1528
1529 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001530 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001531 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001532 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001533}
1534
1535/* Test behavior if MSC answers with CREF to CR */
1536testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1537 var BSSAP_N_CONNECT_ind rx_c_ind;
1538 var RSL_Message rx_rsl;
1539
Harald Welte89d42e82017-12-17 16:42:41 +01001540 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001541
1542 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001543 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001544
1545 var octetstring l3 := '00010203040506'O
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001546 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welteae026692017-12-09 01:03:01 +01001547
1548 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1549 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1550
1551 /* expect BSC to disable the channel */
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
Harald Welte618ef642017-12-14 14:58:20 +01001556/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1557testcase TC_chan_act_nack() runs on test_CT {
1558 var RSL_Message rx_rsl;
1559 var integer chact_nack;
1560
Harald Welte89d42e82017-12-17 16:42:41 +01001561 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001562
1563 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1564
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001565 f_ipa_tx(ts_RSL_CHAN_RQD('33'O, 33));
1566 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte618ef642017-12-14 14:58:20 +01001567 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1568
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001569 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte618ef642017-12-14 14:58:20 +01001570
1571 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1572 f_sleep(0.5);
1573
1574 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1575
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001576 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001577}
1578
Harald Welte799c97b2017-12-14 17:50:30 +01001579/* Test for channel exhaustion due to RACH overload */
1580testcase TC_chan_exhaustion() runs on test_CT {
1581 var ASP_RSL_Unitdata rsl_ud;
1582 var integer i;
1583 var integer chreq_total, chreq_nochan;
1584
Harald Welte89d42e82017-12-17 16:42:41 +01001585 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001586
1587 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1588 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1589
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001590 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001591 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1592 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001593 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 +01001594 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001595 }
1596
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001597 IPA_RSL[0][0].clear;
Harald Welte799c97b2017-12-14 17:50:30 +01001598
Harald Weltedd8cbf32018-01-28 12:07:52 +01001599 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001600 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001601
1602 /* now expect additional channel activations to fail */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001603 f_ipa_tx(ts_RSL_CHAN_RQD('42'O, 42));
Harald Welte799c97b2017-12-14 17:50:30 +01001604
1605 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001606 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001607 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1608 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001609 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001610 var GsmRrMessage rr;
1611 /* match on IMM ASS REJ */
1612 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1613 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1614 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001615 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001616 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1617 chreq_nochan+1);
1618 setverdict(pass);
1619 } else {
1620 repeat;
1621 }
1622 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001623 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte799c97b2017-12-14 17:50:30 +01001624 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001625 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001626}
1627
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001628/* Test channel deactivation due to silence from MS */
1629testcase TC_chan_deact_silence() runs on test_CT {
1630 var RslChannelNr chan_nr;
1631
1632 f_init(1);
1633
1634 /* Request for a dedicated channel */
1635 chan_nr := f_chreq_act_ack('23'O);
1636
1637 /* Wait some time until the channel is released */
1638 f_sleep(2.0);
1639
1640 /* Expect CHANnel RELease */
1641 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001642 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001643 log("Received CHANnel RELease");
1644 setverdict(pass);
1645 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001646 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001647 /* See OS#3709, OsmoBSC should not send Immediate
1648 * Assignment Reject since a dedicated channel was
1649 * already allocated, and Immediate Assignment was
1650 * already sent. */
1651 setverdict(fail, "Unexpected Immediate Assignment!");
1652 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001653 [] IPA_RSL[0][0].receive {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001654 setverdict(fail, "Unexpected RSL message!");
1655 }
1656 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001657 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001658}
1659
Harald Weltecfe2c962017-12-15 12:09:32 +01001660/***********************************************************************
1661 * Assignment Testing
1662 ***********************************************************************/
1663
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001664/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1665 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001666testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001667 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001668
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001669 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1670 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001671 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001672 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001673}
1674
Harald Welte16a4adf2017-12-14 18:54:01 +01001675/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001676testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001677 var BSSAP_N_CONNECT_ind rx_c_ind;
1678 var RSL_Message rx_rsl;
1679 var DchanTuple dt;
1680
Harald Welte89d42e82017-12-17 16:42:41 +01001681 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001682
1683 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001684 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001685 /* send assignment without AoIP IEs */
1686 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1687 } else {
1688 /* Send assignmetn without CIC in IPA case */
1689 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1690 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1691 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1692 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001693 alt {
1694 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1695 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1696 }
Harald Welte235ebf12017-12-15 14:18:16 +01001697 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001698 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1699 setverdict(pass);
1700 }
1701 [] BSSAP.receive { repeat; }
1702 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001703 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001704 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001705}
1706
Harald Welteed848512018-05-24 22:27:58 +02001707/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001708function 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 +02001709 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001710 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001711 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001712 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001713 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001714 if (osmux_enabled) {
1715 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1716 } else {
1717 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1718 }
Harald Welteed848512018-05-24 22:27:58 +02001719 } else {
1720 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001721 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001722 }
1723 return ass_cmd;
1724}
1725
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001726function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001727 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001728 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1729 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001730 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001731
1732 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1733 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001734 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1735 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001736 if (ispresent(enc)) {
1737 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001738 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1739 if (ispresent(v_enc.enc_alg_chosen)) {
1740 chosenEncryptionAlgorithm := valueof(
1741 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1742 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1743 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001744 if (ispresent(v_enc.enc_kc128)) {
1745 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1746 }
1747 }
1748
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001749 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001750 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001751 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001752 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1753 cell_id_source := cell_id_source,
1754 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001755 encryptionInformation := encryptionInformation,
1756 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001757 kC128 := kc128,
1758 /* on AoIP, allow "all" codecs (until we add more concise
1759 * tests) */
1760 codecList := ts_BSSMAP_IE_CodecList(
1761 {ts_CodecAMR_F, ts_CodecAMR_H,
1762 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001763 } else {
1764 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001765 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1766 cell_id_source := cell_id_source,
1767 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001768 encryptionInformation := encryptionInformation,
1769 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1770 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001771 }
1772 return ho_req;
1773}
1774
Harald Welteed848512018-05-24 22:27:58 +02001775/* generate an assignment complete template for either AoIP or SCCPlite */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001776function f_gen_exp_compl(integer bssap_idx := 0)
1777runs on MSC_ConnHdlr return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001778 var template PDU_BSSAP exp_compl;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001779 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001780 var template BSSMAP_IE_Osmo_OsmuxCID exp_osmux_cid := omit;
1781 if (g_pars.use_osmux_cn) {
1782 var template (present) INT1 exp_cid := ?;
1783 if (isbound(g_media.mgcp_conn[0].local_osmux_cid) and isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1784 exp_cid := (g_media.mgcp_conn[0].local_osmux_cid, g_media.mgcp_conn[1].local_osmux_cid);
1785 } else if (isbound(g_media.mgcp_conn[0].local_osmux_cid)) {
1786 exp_cid := g_media.mgcp_conn[0].local_osmux_cid;
1787 } else if (isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1788 exp_cid := g_media.mgcp_conn[1].local_osmux_cid;
1789 }
1790 exp_osmux_cid := tr_OsmuxCID(exp_cid);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001791 }
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001792 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, exp_osmux_cid);
Harald Welteed848512018-05-24 22:27:58 +02001793 } else {
1794 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001795 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit, omit);
Harald Welteed848512018-05-24 22:27:58 +02001796 }
1797 return exp_compl;
1798}
1799
Harald Welte235ebf12017-12-15 14:18:16 +01001800/* Run everything required up to sending a caller-specified assignment command and expect response */
1801function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001802runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001803 var BSSAP_N_CONNECT_ind rx_c_ind;
1804 var RSL_Message rx_rsl;
1805 var DchanTuple dt;
1806
Harald Welte89d42e82017-12-17 16:42:41 +01001807 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001808
1809 dt := f_est_dchan('23'O, 23, '00000000'O);
1810 /* send assignment without AoIP IEs */
1811 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1812 alt {
1813 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1814 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1815 setverdict(pass);
1816 } else {
1817 setverdict(fail, fail_text);
1818 }
1819 }
1820 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1821 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1822 setverdict(pass);
1823 } else {
1824 setverdict(fail, fail_text);
1825 }
1826 }
1827 [] BSSAP.receive { repeat; }
1828 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001829 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001830}
1831testcase TC_assignment_csd() runs on test_CT {
1832 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001833 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001834 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1835 //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 +01001836 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1837 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001838 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001839}
1840
1841testcase TC_assignment_ctm() runs on test_CT {
1842 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001843 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001844 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1845 //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 +01001846 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1847 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001848 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001849}
1850
Harald Welte4003d112017-12-09 22:35:39 +01001851type record DchanTuple {
1852 integer sccp_conn_id,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001853 RslChannelNr rsl_chan_nr,
1854 BtsTrxIdx idx
Harald Weltea5d2ab22017-12-09 14:21:42 +01001855}
1856
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001857type record of DchanTuple DchanTuples;
1858
Harald Welted6939652017-12-13 21:02:46 +01001859/* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001860private function f_chreq_act_ack(OCT1 ra := '23'O,
1861 GsmFrameNumber fn := 23,
1862 BtsTrxIdx idx := {0, 0})
Harald Welted6939652017-12-13 21:02:46 +01001863runs on test_CT return RslChannelNr {
1864 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001865 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
1866 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Harald Welted6939652017-12-13 21:02:46 +01001867 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001868 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10), idx);
1869 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Harald Welted6939652017-12-13 21:02:46 +01001870 return chan_nr;
1871}
1872
Harald Welte4003d112017-12-09 22:35:39 +01001873/* helper function to establish a dedicated channel via BTS and MSC */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001874function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1875 BtsTrxIdx idx := {0, 0})
Harald Welte4003d112017-12-09 22:35:39 +01001876runs on test_CT return DchanTuple {
1877 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001878 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001879
Harald Welte4003d112017-12-09 22:35:39 +01001880 /* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001881 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn, idx);
Harald Welte4003d112017-12-09 22:35:39 +01001882
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001883 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 +01001884
1885 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1886 dt.sccp_conn_id := rx_c_ind.connectionId;
1887 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1888
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001889 dt.idx := idx;
Harald Welte4003d112017-12-09 22:35:39 +01001890 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001891}
1892
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001893/* 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 +06001894function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1895 BtsTrxIdx idx := {0, 0})
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001896runs on test_CT return DchanTuple {
1897 var BSSAP_N_CONNECT_ind rx_c_ind;
1898 var DchanTuple dt;
1899
1900 /* Send CHAN RQD */
1901 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001902 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001903
1904 /* The dyn TS first deactivates PDCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001905 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 +02001906 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001907 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001908
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001909 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001910 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1911
1912 /* Now activates the signalling channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001913 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10), idx);
1914 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001915
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001916 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 +02001917
1918 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1919 dt.sccp_conn_id := rx_c_ind.connectionId;
1920 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1921
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001922 dt.idx := idx;
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001923 return dt;
1924}
1925
Harald Welte641fcbe2018-06-14 10:58:35 +02001926/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001927private function f_exp_chan_rel_and_clear(DchanTuple dt)
1928runs on test_CT {
Harald Welte641fcbe2018-06-14 10:58:35 +02001929 var RSL_Message rx_rsl;
1930 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001931 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 +02001932 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001933 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), dt.idx);
Harald Welte641fcbe2018-06-14 10:58:35 +02001934
1935 /* expect Clear Complete from BSC */
1936 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1937
1938 /* MSC disconnects as instructed. */
1939 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1940}
1941
Harald Welte4003d112017-12-09 22:35:39 +01001942/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1943testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001944 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001945 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001946
Harald Welte89d42e82017-12-17 16:42:41 +01001947 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001948
Harald Welte4003d112017-12-09 22:35:39 +01001949 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1950
1951 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001952 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Harald Welte4003d112017-12-09 22:35:39 +01001953
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001954 /* expect Clear Request on MSC side */
1955 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1956
1957 /* Instruct BSC to clear channel */
1958 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1959 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1960
Harald Welte4003d112017-12-09 22:35:39 +01001961 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001962 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001963
1964 /* wait for SCCP emulation to do its job */
1965 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001966
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001967 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001968}
1969
1970/* Test behavior of channel release after CONN FAIL IND from BTS */
1971testcase TC_chan_rel_conn_fail() runs on test_CT {
1972 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001973 var DchanTuple dt;
1974
Harald Welte89d42e82017-12-17 16:42:41 +01001975 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001976
1977 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1978
1979 /* simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001980 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001981 /* TODO: different cause values? */
1982
Harald Welte4003d112017-12-09 22:35:39 +01001983 /* expect Clear Request from BSC */
1984 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1985
1986 /* Instruct BSC to clear channel */
1987 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1988 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1989
Harald Welte6ff76ea2018-01-28 13:08:01 +01001990 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001991 f_exp_chan_rel_and_clear(dt);
Harald Welte4003d112017-12-09 22:35:39 +01001992
1993 /* wait for SCCP emulation to do its job */
1994 f_sleep(1.0);
1995
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001996 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001997}
1998
Harald Welte99f3ca02018-06-14 13:40:29 +02001999/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
2000/* See also https://www.osmocom.org/issues/3182 */
2001testcase TC_early_conn_fail() runs on test_CT {
2002 var RSL_Message rx_rsl;
2003 var DchanTuple dt;
2004
2005 f_init(1);
2006
2007 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02002008 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02002009
2010 /* BTS->BSC: simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002011 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002012
2013 /* BTS->BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002014 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002015
2016 /* BTS<-BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002017 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002018
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002019 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002020}
2021
2022/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
2023/* See also https://www.osmocom.org/issues/3182 */
2024testcase TC_late_conn_fail() runs on test_CT {
2025 var RSL_Message rx_rsl;
2026 var DchanTuple dt;
2027
2028 f_init(1);
2029
2030 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2031
2032 /* BSC<-MSC: Instruct BSC to clear connection */
2033 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
2034
2035 /* BTS->BSC: expect BSC to deactivate SACCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002036 rx_rsl := f_exp_ipa_rx(tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002037
2038 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002039 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002040
2041 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002042 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002043 /* BTS->BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002044 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002045
2046 /* BSC->MSC: expect Clear Complete from BSC */
2047 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2048
2049 /* BSC<-MSC: MSC disconnects as requested. */
2050 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2051
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002052 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002053}
2054
Oliver Smithaf03bef2021-08-24 15:34:51 +02002055private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
2056 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
2057 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2058
2059 f_statsd_reset();
2060
2061 /* Establish SDCCH */
2062 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
2063 f_establish_fully(ass_cmd, exp_fail);
2064
2065 /* Expect stats to be 0 */
2066 var StatsDExpects expect := {
2067 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
2068 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
2069 };
2070 f_statsd_expect(expect);
2071
2072 /* Simulate CONN FAIL IND on SDCCH */
2073 RSL.send(ts_ASP_RSL_UD(
2074 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2075 IPAC_PROTO_RSL_TRX0));
2076
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002077 f_sleep(1.0);
2078
Oliver Smithaf03bef2021-08-24 15:34:51 +02002079 /* Expect stats to be 1 */
2080 expect := {
2081 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2082 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2083 };
2084 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002085 BSSAP.receive(tr_BSSMAP_ClearRequest);
2086 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002087}
2088testcase TC_stats_conn_fail() runs on test_CT {
2089 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2090 var MSC_ConnHdlr vc_conn;
2091
2092 f_init(1, true);
2093 f_sleep(1.0);
2094
2095 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2096 vc_conn.done;
2097
2098 f_shutdown_helper();
2099}
2100
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002101function f_expect_chan_rel(RslChannelNr rsl_chan_nr,
2102 BtsTrxIdx idx := {0, 0},
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002103 boolean expect_deact_sacch := true,
2104 boolean expect_rr_chan_rel := true,
2105 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002106 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002107 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002108 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002109 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002110
2111 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002112 var boolean got_deact_sacch := false;
2113 var boolean got_rr_chan_rel := false;
2114 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002115 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002116 var RSL_IE_Body l3_ie;
2117 var PDU_ML3_NW_MS l3;
2118 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002119 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2120 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002121 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002122 [] 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 +01002123 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002124 repeat;
2125 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002126 [] 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 +01002127 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002128
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002129 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2130 setverdict(fail, "cannot find L3");
2131 mtc.stop;
2132 }
2133 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2134
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002135 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002136 var CellSelIndValue cells := dec_CellSelIndValue(
2137 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2138
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002139 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2140 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002141 setverdict(pass);
2142 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002143 log("EXPECTED CELLS: ", expect_cells);
2144 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002145 }
2146 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002147
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002148 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2149 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2150 if (match(got_cause, expect_rr_cause)) {
2151 setverdict(pass);
2152 } else {
2153 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2154 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002155 }
Harald Welte99787102019-02-04 10:41:36 +01002156 repeat;
2157 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002158 [] 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 +01002159 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002160 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002161 if (handle_rll_rel) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002162 f_ipa_tx(ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002163 }
Harald Welte91d54a52018-01-28 15:35:07 +01002164 repeat;
2165 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002166 [] 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 +01002167 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002168 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
Harald Welte91d54a52018-01-28 15:35:07 +01002169 }
2170 /* ignore any user data */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002171 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002172 repeat;
2173 }
2174 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002175
2176 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2177 " got_rll_rel_req=", got_rll_rel_req);
2178
2179 if (expect_deact_sacch != got_deact_sacch) {
2180 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2181 }
2182 if (expect_rr_chan_rel != got_rr_chan_rel) {
2183 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2184 }
2185 if (expect_rll_rel_req != got_rll_rel_req) {
2186 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2187 }
Harald Welte91d54a52018-01-28 15:35:07 +01002188}
2189
Harald Welte4003d112017-12-09 22:35:39 +01002190/* Test behavior of channel release after hard Clear Command from MSC */
2191testcase TC_chan_rel_hard_clear() runs on test_CT {
2192 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002193 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002194
Harald Welte89d42e82017-12-17 16:42:41 +01002195 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002196
2197 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2198
2199 /* Instruct BSC to clear channel */
2200 var BssmapCause cause := 0;
2201 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2202
2203 /* expect Clear Complete from BSC on A */
2204 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2205 /* release the SCCP connection */
2206 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2207 }
2208
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002209 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002210 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002211}
2212
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002213function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2214 var BSSAP_N_DATA_ind rx_di;
2215 var DchanTuple dt;
2216
2217 f_init(1);
2218
2219 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2220 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2221 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2222 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2223
2224 /* Instruct BSC to clear channel */
2225 var BssmapCause cause := 0;
2226 if (tx_csfb_ind) {
2227 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2228 } else {
2229 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2230 }
2231
2232 /* expect Clear Complete from BSC on A */
2233 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2234 /* release the SCCP connection */
2235 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2236 }
2237
2238 /* 1 neighbor is added by default in osmo-bts.cfg and
2239 SystemInformationConfig_default, use that: */
2240 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2241
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002242 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 +02002243 f_shutdown_helper();
2244}
2245
2246/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2247 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2248 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2249 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2250 Indicator or not shouldn't matter at all. */
2251testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2252 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2253}
2254
2255/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2256 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2257 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2258 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2259testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2260 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2261}
2262
2263/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2264 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2265 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2266 CSFB Indicator should not be used anymore, and hence, there should be no
2267 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2268 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002269testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2270 var BSSAP_N_DATA_ind rx_di;
2271 var DchanTuple dt;
2272
2273 f_init(1);
2274
2275 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2276
2277 /* Instruct BSC to clear channel */
2278 var BssmapCause cause := 0;
2279 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2280
2281 /* expect Clear Complete from BSC on A */
2282 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2283 /* release the SCCP connection */
2284 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2285 }
2286
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002287 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002288 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002289}
2290
Harald Welted8c36cd2017-12-09 23:05:31 +01002291/* Test behavior of channel release after hard RLSD from MSC */
2292testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002293 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002294
Harald Welte89d42e82017-12-17 16:42:41 +01002295 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002296
2297 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2298
2299 /* release the SCCP connection */
2300 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2301
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002302 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002303 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002304}
2305
Harald Welte550daf92018-06-11 19:22:13 +02002306/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2307testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2308 var DchanTuple dt;
2309
2310 f_init(1);
2311
2312 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2313
2314 /* release the SCCP connection */
2315 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2316
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002317 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002318 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002319}
2320
Harald Welte85804d42017-12-10 14:11:58 +01002321/* Test behavior of channel release after BSSMAP RESET from MSC */
2322testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002323 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002324
Harald Welte89d42e82017-12-17 16:42:41 +01002325 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002326
2327 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2328
2329 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002330 IPA_RSL[0][0].clear;
Harald Welte85804d42017-12-10 14:11:58 +01002331
2332 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002333 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 +01002334 interleave {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002335 [] 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 +01002336 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2337 }
2338
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002339 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002340 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002341}
2342
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002343/* Verify T(iar) triggers and releases the channel */
2344testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2345 var DchanTuple dt;
2346
2347 /* Set T(iar) in BSC low enough that it will trigger before other side
2348 has time to keep alive with a T(ias). Keep recommended ratio of
2349 T(iar) >= T(ias)*2 */
2350 g_bsc_sccp_timer_ias := 2;
2351 g_bsc_sccp_timer_iar := 5;
2352
2353 f_init(1);
2354
2355 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002356 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002357 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002358}
2359
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002360private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2361 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002362runs on test_CT
2363{
2364 var DchanTuple dt;
2365
2366 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2367 var BssmapCause cause := 0;
2368 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2369 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2370 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2371 }
2372
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002373 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 +02002374}
2375
2376/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2377testcase TC_chan_rel_rr_cause() runs on test_CT {
2378 f_init(1);
2379
2380 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2381 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2382 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2383 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2384 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2385 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002386
2387 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002388}
2389
Harald Welte5cd20ed2017-12-13 21:03:20 +01002390/* Test behavior if RSL EST IND for non-active channel */
2391testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2392 timer T := 2.0;
2393
Harald Welte89d42e82017-12-17 16:42:41 +01002394 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002395
2396 var octetstring l3 := '00010203040506'O;
2397 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002398 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002399
2400 T.start;
2401 alt {
2402 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2403 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2404 }
2405 [] BSSAP.receive {}
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002406 [] IPA_RSL[0][0].receive {}
Harald Welte5cd20ed2017-12-13 21:03:20 +01002407 [] T.timeout {}
2408 }
2409
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002410 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002411}
2412
2413/* Test behavior if RSL EST IND for invalid SAPI */
2414testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2415 var RslChannelNr chan_nr;
2416
Harald Welte89d42e82017-12-17 16:42:41 +01002417 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002418
2419 chan_nr := f_chreq_act_ack()
2420
2421 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002422 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002423
2424 timer T := 2.0;
2425 T.start;
2426 alt {
2427 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2428 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2429 }
2430 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002431 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002432 [] T.timeout {}
2433 }
2434
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002435 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002436}
2437
2438/* Test behavior if RSL EST IND for invalid SAPI */
2439testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2440 timer T := 2.0;
2441
Harald Welte89d42e82017-12-17 16:42:41 +01002442 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002443
2444 var RslChannelNr chan_nr := f_chreq_act_ack();
2445
2446 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002447 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002448
2449 T.start;
2450 alt {
2451 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2452 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2453 }
2454 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002455 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002456 [] T.timeout {}
2457 }
2458
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002459 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002460}
2461
2462/* Test behavior if RSL EST IND for invalid SACCH */
2463testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2464 timer T := 2.0;
2465
Harald Welte89d42e82017-12-17 16:42:41 +01002466 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002467
2468 var RslChannelNr chan_nr := f_chreq_act_ack();
2469
2470 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002471 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002472
2473 T.start;
2474 alt {
2475 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2476 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2477 }
2478 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002479 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002480 [] T.timeout {}
2481 }
2482
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002483 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002484}
2485
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002486/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2487private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2488 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2489 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2490
2491 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2492 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2493
2494 f_establish_fully(ass_cmd, exp_compl);
2495
2496 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2497 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2498 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2499 BSSAP.receive(PDU_BSSAP:{
2500 discriminator := '1'B,
2501 spare := '0000000'B,
2502 dlci := 'C3'O,
2503 lengthIndicator := ?,
2504 pdu := { dtap := '0904'O }
2505 });
2506
2507 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2508 for (var integer i := 0; i < 32; i := i + 1) {
2509 var octetstring l3 := '09'O & f_rnd_octstring(14);
2510 var template (value) RslLinkId link_id;
2511 var template (value) OCT1 dlci;
2512
2513 if (i mod 2 == 0) {
2514 /* SAPI0 on FACCH or SDCCH */
2515 link_id := ts_RslLinkID_DCCH(0);
2516 dlci := '80'O;
2517 } else {
2518 /* SAPI3 on SACCH */
2519 link_id := ts_RslLinkID_SACCH(3);
2520 dlci := 'C3'O;
2521 }
2522
2523 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002524 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002525 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002526 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002527 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002528 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002529}
2530testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2531 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2532 var MSC_ConnHdlr vc_conn;
2533
2534 f_init(1, true);
2535 f_sleep(1.0);
2536
2537 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2538 vc_conn.done;
2539
2540 f_shutdown_helper();
2541}
2542
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002543private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002544 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002545 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002546 float T_val := 2.0)
2547runs on test_CT {
2548 var BSSAP_N_DATA_ind rx_di;
2549 timer T;
2550
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002551 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2552 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002553
2554 T.start(T_val);
2555 alt {
2556 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2557 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2558 if (not match(rx_cause, tr_cause)) {
2559 setverdict(fail, "Rx unexpected Cause IE: ",
2560 rx_cause, " vs expected ", tr_cause);
2561 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002562
2563 /* Who ever on the earth decided to define this field as two separate bits?!? */
2564 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2565 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2566 if (not match(rx_cc, cc)) {
2567 setverdict(fail, "Rx unexpected Control Channel type: ",
2568 rx_cc, " vs expected ", cc);
2569 }
2570
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002571 setverdict(pass);
2572 }
2573 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2574 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2575 }
2576 [] T.timeout {
2577 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2578 }
2579 }
2580}
2581
2582/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2583testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2584 var octetstring rnd_data := f_rnd_octstring(16);
2585 var RSL_Message rx_rsl;
2586 var DchanTuple dt;
2587
2588 f_init(1);
2589
2590 /* MS establishes a SAPI=0 link on DCCH */
2591 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2592
2593 /* MSC sends some data on (not yet established) SAPI=3 link */
2594 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2595 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002596 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 +07002597
2598 /* MS sends unexpected RELease INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002599 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002600 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2601 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2602
2603 /* Clean up the connection */
2604 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002605 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002606
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002607 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002608}
2609
2610/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2611testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2612 var octetstring rnd_data := f_rnd_octstring(16);
2613 var RSL_Message rx_rsl;
2614 var DchanTuple dt;
2615
2616 f_init(1);
2617
2618 /* MS establishes a SAPI=0 link on DCCH */
2619 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2620
2621 /* MSC sends some data on (not yet established) SAPI=3 link */
2622 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2623 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002624 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 +07002625
2626 /* BTS sends unexpected ERROR INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002627 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002628 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2629 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2630
2631 /* Clean up the connection */
2632 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002633 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002634
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002635 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002636}
2637
2638/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2639testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2640 var octetstring rnd_data := f_rnd_octstring(16);
2641 var RSL_Message rx_rsl;
2642 var DchanTuple dt;
2643
2644 f_init(1);
2645
2646 /* MS establishes a SAPI=0 link on DCCH */
2647 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2648
2649 /* MSC sends some data on (not yet established) SAPI=3 link */
2650 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2651 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002652 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 +07002653
2654 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2655 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2656
2657 /* Clean up the connection */
2658 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002659 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002660
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002661 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002662}
2663
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002664/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2665testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
2666 var octetstring rnd_data := f_rnd_octstring(16);
2667 var RSL_Message rx_rsl;
2668 var DchanTuple dt;
2669
2670 f_init(1);
2671
2672 /* MS establishes a SAPI=0 link on DCCH */
2673 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2674
2675 /* MSC sends some data on (not yet established) SAPI=3 link */
2676 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2677 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002678 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 +07002679
2680 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002681 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002682 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002683
2684 /* Clean up the connection */
2685 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002686 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002687
2688 f_shutdown_helper();
2689}
2690
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002691testcase TC_si_default() runs on test_CT {
2692 f_init(0);
2693 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002694 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002695}
Harald Welte4003d112017-12-09 22:35:39 +01002696
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002697/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2698 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2699private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2700{
2701 select (earfcn_index) {
2702 case (0) {
2703 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2704 return 111;
2705 }
2706 case (1) {
2707 return 1;
2708 }
2709 case (2) {
2710 return 0;
2711 }
2712 case (3) {
2713 return 65535;
2714 }
2715 case else {
2716 return 23 * (earfcn_index - 3);
2717 }
2718 }
2719}
2720
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002721function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2722 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002723
2724 f_init(0);
2725
2726 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2727 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002728 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2729 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002730 }
2731
2732 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2733
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002734 if (not istemplatekind(expect_cells, "omit")) {
2735 /* Also check that RR Channel Release contains these EARFCNs.
2736 * (copied code from TC_chan_rel_hard_clear_csfb) */
2737 var BSSAP_N_DATA_ind rx_di;
2738 var DchanTuple dt;
2739
2740 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002741 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2742 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2743 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002744
2745 /* Instruct BSC to clear channel */
2746 var BssmapCause cause := 0;
2747 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2748
2749 /* expect Clear Complete from BSC on A */
2750 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2751 /* release the SCCP connection */
2752 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2753 }
2754
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002755 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002756 }
2757
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002758 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002759 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 +02002760 }
2761}
2762
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002763private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2764{
2765 var template SI2quaterRestOctetsList si2quater := {};
2766 var integer si2quater_count := (count + 2) / 3;
2767
2768 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002769 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002770 var integer index := i / 3;
2771 var integer earfcn_index := i mod 3;
2772 if (index >= lengthof(si2quater)) {
2773 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2774 }
2775 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);
2776 }
2777
2778 return si2quater;
2779}
2780
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002781private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2782{
2783 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2784
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002785 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002786 for (var integer i := 0; i < count; i := i + 1) {
2787 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002788 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002789 }
2790
2791 return tr_CellSelIndValue_EUTRAN(cells);
2792}
2793
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002794private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2795{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002796 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002797 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002798 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2799 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002800}
2801
2802testcase TC_si2quater_2_earfcns() runs on test_CT {
2803 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002804 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002805}
2806
2807testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002808 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002809 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002810}
2811
2812testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002813 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002814 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002815}
2816
2817testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002818 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002819 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002820}
2821
2822testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002823 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002824 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002825}
2826
2827testcase TC_si2quater_12_earfcns() runs on test_CT {
2828 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002829 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002830}
2831
2832testcase TC_si2quater_23_earfcns() runs on test_CT {
2833 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002834 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002835}
2836
2837testcase TC_si2quater_32_earfcns() runs on test_CT {
2838 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002839 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002840}
2841
2842testcase TC_si2quater_33_earfcns() runs on test_CT {
2843 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002844 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002845}
2846
2847testcase TC_si2quater_42_earfcns() runs on test_CT {
2848 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002849 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002850}
2851
2852testcase TC_si2quater_48_earfcns() runs on test_CT {
2853 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002854 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002855}
2856
2857/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2858 * 48 EARFCNs. */
2859testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002860 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002861 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2862 f_init(0);
2863
2864 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002865 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2866 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002867 }
2868
2869 /* The 49th EARFCN no longer fits, expect VTY error */
2870 f_vty_enter_cfg_bts(BSCVTY, 0);
2871 var charstring vty_error;
2872 vty_error := f_vty_transceive_ret(BSCVTY,
2873 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2874 f_vty_transceive(BSCVTY, "end");
2875
2876 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2877 log("Got expected VTY error: ", vty_error);
2878 setverdict(pass);
2879 } else {
2880 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2881 }
2882
2883 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2884
2885 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002886 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 +02002887 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002888 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002889}
2890
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002891private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2892{
2893 var uint8_t count := 0;
2894 for (var integer i := 5; i < 16; i := i + 1) {
2895 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2896 count := count + 1;
2897 }
2898 }
2899 return count;
2900}
2901
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002902private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2903{
2904 var ASP_RSL_Unitdata rx_rsl_ud;
2905 var SystemInformationType1 last_si1;
2906
2907 timer T := 30.0;
2908 T.start;
2909 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002910 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2911 tr_RSL_BCCH_INFO,
2912 tr_RSL_NO_SACCH_FILL,
2913 tr_RSL_SACCH_FILL))) -> value rx_rsl_ud {
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002914 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2915 if (g_system_information[rsl_idx].si1 == omit) {
2916 repeat;
2917 }
2918 last_si1 := g_system_information[rsl_idx].si1;
2919 g_system_information[rsl_idx].si1 := omit;
2920 T.stop;
2921 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002922 [] IPA_RSL[rsl_idx][0].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002923 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2924 }
2925 return last_si1;
2926}
2927
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002928/* verify ACC rotate feature */
2929testcase TC_si_acc_rotate() runs on test_CT {
2930 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002931 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002932 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002933 var uint8_t count;
2934 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2935
2936 f_init(0, guard_timeout := 60.0);
2937
2938 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2939 "access-control-class-rotate 3",
2940 "access-control-class-rotate-quantum 1"});
2941
2942 /* Init and get first sysinfo */
2943 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2944
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002945 for (var integer i:= 0; i < 20; i := i + 1) {
2946 last_si1 := f_recv_next_si1(0);
2947 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002948 count := f_acc09_count_allowed(acc);
2949 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2950
2951 if (count != 3) {
2952 log("RSL: EXPECTED SI ACC len=3");
2953 setverdict(fail, "received SI does not match expectations");
2954 break;
2955 }
2956
2957 for (var integer j := 0; j < 10; j := j + 1) {
2958 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2959 times_allowed[j] := times_allowed[j] + 1;
2960 }
2961 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002962 }
2963
2964 for (var integer j := 0; j < 10; j := j + 1) {
2965 log("ACC", j, " allowed ", times_allowed[j], " times" );
2966 if (j != 5 and times_allowed[j] < 3) {
2967 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2968 } else if (j == 5 and times_allowed[j] > 0) {
2969 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2970 }
2971 }
2972
2973 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2974 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002975 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002976}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002977
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002978/* verify ACC startup ramp+rotate feature */
2979testcase TC_si_acc_ramp_rotate() runs on test_CT {
2980 var template SystemInformationConfig sic := SystemInformationConfig_default;
2981 var SystemInformationType1 last_si1;
2982 var AccessControlClass acc;
2983 var ASP_RSL_Unitdata rx_rsl_ud;
2984 var uint8_t count;
2985 var uint8_t prev_count;
2986 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2987
2988 f_init(0, guard_timeout := 80.0);
2989
2990 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2991 "access-control-class-rotate 0",
2992 "access-control-class-rotate-quantum 1",
2993 "access-control-class-ramping",
2994 "access-control-class-ramping-step-interval 5",
2995 "access-control-class-ramping-step-size 5"});
2996
2997 /* Init and get first sysinfo */
2998 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2999 last_si1 := g_system_information[0].si1;
3000 acc := last_si1.rach_control.acc;
3001 count := f_acc09_count_allowed(acc);
3002 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
3003 while (count > 0) {
3004 last_si1 := f_recv_next_si1(0);
3005 acc := last_si1.rach_control.acc;
3006 count := f_acc09_count_allowed(acc);
3007 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
3008 }
3009
3010 /* Increase adm subset size, we should see ramping start up */
3011 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
3012 prev_count := 0;
3013 while (true) {
3014 last_si1 := f_recv_next_si1(0);
3015 acc := last_si1.rach_control.acc;
3016 count := f_acc09_count_allowed(acc);
3017 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
3018
3019 if (prev_count > count) {
3020 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
3021 break;
3022 }
3023
3024 if (count == 9) {
3025 break; /* Maximum reached (10 - 1 perm barred), done here */
3026 }
3027
3028 prev_count := count;
3029 }
3030
3031 setverdict(pass);
3032
3033 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
3034 "rach access-control-class 4 allowed",
3035 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003036 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003037}
3038
Harald Welte4003d112017-12-09 22:35:39 +01003039testcase TC_ctrl_msc_connection_status() runs on test_CT {
3040 var charstring ctrl_resp;
3041
Harald Welte89d42e82017-12-17 16:42:41 +01003042 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003043
3044 /* See https://osmocom.org/issues/2729 */
3045 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003046 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01003047}
3048
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003049testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3050 var charstring ctrl_resp;
3051
3052 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003053
3054 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003055 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003056}
3057
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003058/* Verify correct stats on the number of configured and connected MSCs */
3059private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3060 g_pars := f_gen_test_hdlr_pars();
3061 var StatsDExpects expect := {
3062 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3063 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3064 };
3065 f_statsd_expect(expect);
3066}
3067
3068private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3069{
3070 var MSC_ConnHdlr vc_conn;
3071
3072 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3073 f_sleep(1.0);
3074 vc_conn := f_start_handler(tc_fn);
3075 vc_conn.done;
3076
3077 /* Also verify stat exposed on CTRL interface */
3078 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3079 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3080
3081 f_shutdown_helper();
3082}
3083
3084/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3085private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3086 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3087}
3088testcase TC_stat_num_msc_connected_1() runs on test_CT {
3089 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3090}
3091
3092/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3093private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3094 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3095}
3096testcase TC_stat_num_msc_connected_2() runs on test_CT {
3097 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3098}
3099
3100/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3101private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3102 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3103}
3104testcase TC_stat_num_msc_connected_3() runs on test_CT {
3105 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3106}
3107
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003108/* Verify correct stats on the number of configured and connected MSCs */
3109private 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 +06003110 var integer num_trx_connected := 0;
3111 var integer num_trx_total := 0;
3112
3113 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3114 var integer trx_num := c_BtsParams[i].trx_num;
3115 num_trx_total := num_trx_total + trx_num;
3116 if (i < expect_num_bts_connected) {
3117 num_trx_connected := num_trx_connected + trx_num;
3118 }
3119 }
3120
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003121 var StatsDExpects expect := {
3122 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3123 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3124 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003125 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := num_trx_connected, max := num_trx_connected },
3126 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := num_trx_total, max := num_trx_total }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003127 };
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003128
3129 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003130 f_statsd_expect(expect);
3131}
3132
3133private 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 +06003134 var integer num_trx_connected := 0;
3135 var integer num_trx_total := 0;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003136 var MSC_ConnHdlr vc_conn;
3137
3138 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3139 f_sleep(1.0);
3140 vc_conn := f_start_handler(tc_fn);
3141 vc_conn.done;
3142
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003143 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3144 var integer trx_num := c_BtsParams[i].trx_num;
3145 num_trx_total := num_trx_total + trx_num;
3146 if (i < nr_bts) {
3147 num_trx_connected := num_trx_connected + trx_num;
3148 }
3149 }
3150
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003151 /* Also verify stat exposed on CTRL interface */
3152 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3153 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 +06003154 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(num_trx_connected));
3155 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 +02003156
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003157 /* Verify rf_states exposed on CTRL interface */
3158 var charstring expect_net_rf_states := "";
3159 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003160 var charstring expect_bts_rf_states := "";
3161
3162 for (var integer j := 0; j < c_BtsParams[i].trx_num; j := j + 1) {
3163 expect_bts_rf_states := expect_bts_rf_states &
3164 int2str(i) & "," & int2str(j) & ",";
3165 if (i < NUM_BTS) {
3166 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3167 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3168 } else {
3169 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3170 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3171 }
3172 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3173 expect_bts_rf_states := expect_bts_rf_states & "on,";
3174 if (i < nr_bts) {
3175 /* For BTS where RSL is connected, the RSL state will be "up" */
3176 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3177 } else {
3178 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3179 }
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003180 }
3181
3182 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3183 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3184 }
3185 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3186
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003187 f_shutdown_helper();
3188}
3189
3190/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3191private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3192 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3193}
3194testcase TC_stat_num_bts_connected_1() runs on test_CT {
3195 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3196}
3197
3198/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3199private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3200 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3201}
3202testcase TC_stat_num_bts_connected_2() runs on test_CT {
3203 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3204}
3205
3206/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3207private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3208 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3209}
3210testcase TC_stat_num_bts_connected_3() runs on test_CT {
3211 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3212}
3213
Harald Welte4003d112017-12-09 22:35:39 +01003214testcase TC_ctrl() runs on test_CT {
3215 var charstring ctrl_resp;
3216
Harald Welte89d42e82017-12-17 16:42:41 +01003217 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003218
3219 /* all below values must match the osmo-bsc.cfg config file used */
3220
Harald Welte6a129692018-03-17 17:30:14 +01003221 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3222 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003223 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003224
3225 var integer bts_nr := 0;
3226 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3227 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3228 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3229 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3230 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3231 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3232 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3233
3234 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3235 f_sleep(2.0);
3236 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3237 setverdict(fail, "oml-uptime not incrementing as expected");
3238 }
3239 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3240
3241 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3242
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003243 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003244}
3245
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003246/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3247 "location-state" over the SCCPlite IPA conn */
3248testcase TC_ctrl_location() runs on test_CT {
3249 var MSC_ConnHdlr vc_conn;
3250 var integer bts_nr := 0;
3251
3252 f_init(1, true);
3253 f_sleep(1.0);
3254
3255 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3256 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3257 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3258
3259 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3260 f_sleep(2.0);
3261
3262 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3263 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3264 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3265
3266 /* should match the one from config */
3267 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3268
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003269 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003270}
3271
Harald Welte6f521d82017-12-11 19:52:02 +01003272
3273/***********************************************************************
3274 * Paging Testing
3275 ***********************************************************************/
3276
3277type record Cell_Identity {
3278 GsmMcc mcc,
3279 GsmMnc mnc,
3280 GsmLac lac,
3281 GsmCellId ci
3282};
Harald Welte24135bd2018-03-17 19:27:53 +01003283private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003284private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003285
Harald Welte5d1a2202017-12-13 19:51:29 +01003286type set of integer BtsIdList;
3287
3288private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3289 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3290 if (bts_id == bts_ids[j]) {
3291 return true;
3292 }
3293 }
3294 return false;
3295}
Harald Welte6f521d82017-12-11 19:52:02 +01003296
3297/* core paging test helper function; used by most paging test cases */
3298private function f_pageing_helper(hexstring imsi,
3299 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003300 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003301 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003302 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003303{
3304 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003305 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003306 var RSL_Message rx_rsl;
3307 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003308 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003309
3310 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003311
3312 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003313 for (i := 0; i < NUM_BTS; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003314 IPA_RSL[i][0].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003315 }
Harald Welte6f521d82017-12-11 19:52:02 +01003316
3317 if (isvalue(rsl_chneed)) {
3318 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3319 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3320 } else {
3321 bssmap_chneed := omit;
3322 }
3323
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003324 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3325 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003326
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003327 if (not istemplatekind(tmsi, "omit")) {
3328 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003329 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003330 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003331 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003332
Harald Welte5d1a2202017-12-13 19:51:29 +01003333 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003334 rx_rsl := f_exp_ipa_rx(tr_RSL_PAGING_CMD(mi), idx := {bts_ids[i], 0});
Harald Welte5d1a2202017-12-13 19:51:29 +01003335 /* check channel type, paging group */
3336 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3337 setverdict(fail, "Paging for wrong paging group");
3338 }
3339 if (ispresent(rsl_chneed) and
3340 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3341 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3342 }
Harald Welte6f521d82017-12-11 19:52:02 +01003343 }
Harald Welte2fccd982018-01-31 15:48:19 +01003344 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003345 /* do a quick check on all not-included BTSs if they received paging */
3346 for (i := 0; i < NUM_BTS; i := i + 1) {
3347 timer T := 0.1;
3348 if (f_bts_in_list(i, bts_ids)) {
3349 continue;
3350 }
3351 T.start;
3352 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003353 [] IPA_RSL[i][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003354 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3355 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003356 [] IPA_RSL[i][0].receive { repeat; }
Harald Welte5d1a2202017-12-13 19:51:29 +01003357 [] T.timeout { }
3358 }
Harald Welte6f521d82017-12-11 19:52:02 +01003359 }
3360
3361 setverdict(pass);
3362}
3363
Harald Welte5d1a2202017-12-13 19:51:29 +01003364const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003365const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003366const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3367const BtsIdList c_BtsId_LAC2 := { 2 };
3368
Harald Welte6f521d82017-12-11 19:52:02 +01003369/* PAGING by IMSI + TMSI */
3370testcase TC_paging_imsi_nochan() runs on test_CT {
3371 var BSSMAP_FIELD_CellIdentificationList cid_list;
3372 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003373 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003374 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003375}
3376
3377/* PAGING by IMSI + TMSI */
3378testcase TC_paging_tmsi_nochan() runs on test_CT {
3379 var BSSMAP_FIELD_CellIdentificationList cid_list;
3380 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003381 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003382 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003383}
3384
3385/* Paging with different "channel needed' values */
3386testcase TC_paging_tmsi_any() runs on test_CT {
3387 var BSSMAP_FIELD_CellIdentificationList cid_list;
3388 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003389 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003390 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003391}
3392testcase TC_paging_tmsi_sdcch() runs on test_CT {
3393 var BSSMAP_FIELD_CellIdentificationList cid_list;
3394 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003395 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003396 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003397}
3398testcase TC_paging_tmsi_tch_f() runs on test_CT {
3399 var BSSMAP_FIELD_CellIdentificationList cid_list;
3400 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003401 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003402 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003403}
3404testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3405 var BSSMAP_FIELD_CellIdentificationList cid_list;
3406 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003407 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003408 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003409}
3410
3411/* Paging by CGI */
3412testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3413 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3414 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003415 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003416 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003417}
3418
3419/* Paging by LAC+CI */
3420testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3421 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3422 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003423 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003424 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003425}
3426
3427/* Paging by CI */
3428testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3429 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3430 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003431 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003432 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003433}
3434
3435/* Paging by LAI */
3436testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3437 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3438 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003439 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003440 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003441}
3442
3443/* Paging by LAC */
3444testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3445 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3446 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003447 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003448 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003449}
3450
3451/* Paging by "all in BSS" */
3452testcase TC_paging_imsi_nochan_all() runs on test_CT {
3453 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3454 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003455 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003456 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003457}
3458
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003459/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003460testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3461 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3462 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 +01003463 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003464 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003465}
Harald Welte6f521d82017-12-11 19:52:02 +01003466
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003467/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003468testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3469 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3470 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003471 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003472 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003473}
3474
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003475/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003476testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3477 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3478 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003479 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003480 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003481}
3482
Harald Welte6f521d82017-12-11 19:52:02 +01003483/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003484testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3485 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3486 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3487 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003488 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003489}
3490
3491/* Paging on empty list: Verify none of them page */
3492testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3493 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3494 cid_list := { cIl_LAC := { } };
3495 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003496 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003497}
3498
Stefan Sperling049a86e2018-03-20 15:51:00 +01003499/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3500testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3501 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3502 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3503 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3504 f_shutdown_helper();
3505}
3506
Harald Welte6f521d82017-12-11 19:52:02 +01003507/* Verify paging retransmission interval + count */
3508/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003509/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003510
Harald Weltee65d40e2017-12-13 00:09:06 +01003511/* Verify PCH load */
3512testcase TC_paging_imsi_load() runs on test_CT {
3513 var BSSMAP_FIELD_CellIdentificationList cid_list;
3514 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003515 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003516 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003517 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003518
3519 /* tell BSC there is no paging space anymore */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003520 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003521 f_sleep(0.2);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003522 IPA_RSL[0][0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003523
3524 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3525 * there would be 8 retransmissions during 4 seconds */
3526 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003527 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003528 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003529 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003530 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003531 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003532 }
Harald Welte2caa1062018-03-17 18:19:05 +01003533 [] T_retrans.timeout {
3534 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003535 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte2caa1062018-03-17 18:19:05 +01003536 T_retrans.start;
3537 repeat;
3538 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003539 [] T.timeout {
3540 setverdict(pass);
3541 }
3542 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003543
3544 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003545}
3546
Harald Welte235ebf12017-12-15 14:18:16 +01003547/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003548testcase TC_paging_counter() runs on test_CT {
3549 var BSSMAP_FIELD_CellIdentificationList cid_list;
3550 timer T := 4.0;
3551 var integer i;
3552 var integer paging_attempted_bsc;
3553 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003554 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003555 var integer paging_expired_bts[NUM_BTS];
3556 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3557
3558 f_init();
3559
3560 /* read counters before paging */
3561 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003562 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3563 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3564 }
Harald Welte1ff69992017-12-14 12:31:17 +01003565 for (i := 0; i < NUM_BTS; i := i+1) {
3566 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3567 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3568 }
3569
3570 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3571
3572 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3573 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3574 for (i := 0; i < NUM_BTS; i := i+1) {
3575 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3576 paging_attempted_bts[i]+1);
3577 }
3578
3579 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3580 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003581 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3582 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3583 }
Harald Welte1ff69992017-12-14 12:31:17 +01003584 for (i := 0; i < NUM_BTS; i := i+1) {
3585 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3586 paging_expired_bts[i]+1);
3587 }
Harald Welte1ff69992017-12-14 12:31:17 +01003588
Philipp Maier282ca4b2018-02-27 17:17:00 +01003589 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003590}
3591
3592
Harald Welte10985002017-12-12 09:29:15 +01003593/* Verify paging stops after A-RESET */
3594testcase TC_paging_imsi_a_reset() runs on test_CT {
3595 var BSSMAP_FIELD_CellIdentificationList cid_list;
3596 timer T := 3.0;
3597 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003598 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003599
3600 /* Perform a BSSMAP Reset and wait for ACK */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003601 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 +01003602 alt {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003603 [] 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 +01003604 [] BSSAP.receive { repeat; }
3605 }
3606
Daniel Willmanncbef3982018-07-30 09:22:40 +02003607 /* Wait to avoid a possible race condition if a paging message is
3608 * received right before the reset ACK. */
3609 f_sleep(0.2);
3610
Harald Welte10985002017-12-12 09:29:15 +01003611 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003612 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003613 IPA_RSL[i][0].clear;
Philipp Maier1e6b4422018-02-23 14:02:13 +01003614 }
Harald Welte10985002017-12-12 09:29:15 +01003615
3616 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3617 T.start;
3618 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003619 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003620 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003621 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003622 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003623 [] IPA_RSL[1][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003624 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003625 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003626 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003627 [] IPA_RSL[2][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003628 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003629 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003630 }
Harald Welte10985002017-12-12 09:29:15 +01003631 [] T.timeout {
3632 setverdict(pass);
3633 }
3634 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003635
3636 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003637}
Harald Welteae026692017-12-09 01:03:01 +01003638
Philipp Maierf45824a2019-08-14 14:44:10 +02003639/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3640 * paging response we can not know which MSC is in charge, so we will blindly
3641 * pick the first configured MSC. This behavior is required in order to make
3642 * MT-CSFB calls working because in those cases the BSC can not know that the
3643 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3644 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003645 */
3646testcase TC_paging_resp_unsol() runs on test_CT {
3647
3648 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003649 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003650
3651 var BSSAP_N_CONNECT_ind rx_c_ind;
3652 var DchanTuple dt;
3653 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003654 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003655
3656 /* Send CHAN RQD and wait for allocation; acknowledge it */
3657 dt.rsl_chan_nr := f_chreq_act_ack();
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003658 dt.idx := {0, 0};
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003659
3660 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003661 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003662
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003663
Philipp Maierf45824a2019-08-14 14:44:10 +02003664 /* Expevct a CR with a matching Paging response on the A-Interface */
3665 T.start;
3666 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003667 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003668 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003669 dt.sccp_conn_id := rx_c_ind.connectionId;
3670 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003671 }
3672 [] BSSAP.receive {
3673 setverdict(fail, "Received unexpected message on A-Interface!");
3674 }
3675 [] T.timeout {
3676 setverdict(fail, "Received nothing on A-Interface!");
3677 }
3678 }
3679
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003680 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003681 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003682}
3683
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003684/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3685function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003686 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003687 var Hexstrings imsis := {};
3688 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003689 var integer rx_paging_num := 0;
3690 var integer i;
3691 timer T_rx := 60.0;
3692 timer T_load_ind := 1.0;
3693
3694 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003695 imsis := imsis & {f_gen_imsi(i)};
3696 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003697 }
3698
3699 f_init(1, guard_timeout := 100.0);
3700
3701 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003702 IPA_RSL[0][0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003703 if (send_pag_load_ind) {
3704 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003705 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(65535));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003706 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003707
3708 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003709 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003710 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 +02003711 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3712 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003713 }
3714
3715 T_rx.start;
3716 T_load_ind.start;
3717 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003718 [] 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 +02003719 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3720 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3721 var charstring imsi_str := hex2str(imsi_suffix);
3722 var integer imsi_idx := str2int(imsi_str);
3723 if (rx_paging_done[imsi_idx] == false) {
3724 rx_paging_done[imsi_idx] := true;
3725 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003726 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003727 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 +02003728 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003729 }
3730 if (rx_paging_num < num_subscribers) {
3731 repeat;
3732 }
3733 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003734 [] IPA_RSL[0][0].receive { repeat; }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003735 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003736 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3737 if (send_pag_load_ind) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003738 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(40));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003739 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003740 T_load_ind.start;
3741 repeat;
3742 }
3743 [] T_rx.timeout {
3744 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3745 mtc.stop;
3746 }
3747 }
3748
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003749 /* Drop OML connection to have all paging requests flushed: */
3750 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3751
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003752 f_shutdown_helper();
3753}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003754/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3755testcase TC_paging_500req() runs on test_CT {
3756 f_TC_paging_Nreq(500, true);
3757}
3758/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3759 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3760 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3761 * for current config yields ~8req/sec, so 480req/min maximum. */
3762testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3763 f_TC_paging_Nreq(450, false);
3764}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003765
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003766/* Test RSL link drop causes counter increment */
3767testcase TC_rsl_drop_counter() runs on test_CT {
3768 var integer rsl_fail;
3769
Harald Welte89d42e82017-12-17 16:42:41 +01003770 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003771
3772 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3773
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003774 f_ipa_rsl_stop(bts[0][0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003775
3776 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3777
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003778 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003779}
3780
3781/* TODO: Test OML link drop causes counter increment */
3782
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003783/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3784function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003785 var IPA_Client client;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003786 timer T := 10.0;
3787
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003788 client.id := "IPA-BTS0-TRX0-RSL";
3789 client.vc_IPA := IPA_Emulation_CT.create(client.id & "-IPA") alive;
3790 client.ccm_pars := c_IPA_default_ccm_pars;
3791 client.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
3792 client.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003793
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003794 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003795
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003796 f_init_mgcp(0, "VirtMGW");
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003797
3798 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003799 map(client.vc_IPA:IPA_PORT, system:IPA);
3800 connect(client.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0][0]);
3801 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 +01003802
3803 /* wait for IPA OML link to connect and then disconnect */
3804 T.start;
3805 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003806 [] IPA_RSL[0][0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003807 T.stop;
3808 return true;
3809 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003810 [] IPA_RSL[0][0].receive { repeat }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003811 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003812 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003813 }
3814 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003815 return false;
3816}
3817
3818/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3819testcase TC_rsl_unknown_unit_id() runs on test_CT {
3820 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3821 setverdict(pass);
3822 } else {
3823 setverdict(fail, "Timeout RSL waiting for connection to close");
3824 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003825 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003826}
3827
3828
3829/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3830testcase TC_oml_unknown_unit_id() runs on test_CT {
3831 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3832 setverdict(pass);
3833 } else {
3834 setverdict(fail, "Timeout OML waiting for connection to close");
3835 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003836 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003837}
3838
3839
Harald Weltec1a2fff2017-12-17 11:06:19 +01003840/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003841 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003842 ***********************************************************************/
3843
Harald Welte6811d102019-04-14 22:23:14 +02003844import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003845import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003846import from RSL_Emulation all;
3847import from MSC_ConnectionHandler all;
3848
3849type function void_fn(charstring id) runs on MSC_ConnHdlr;
3850
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003851/* helper function to create and connect a MSC_ConnHdlr component
3852 * TODO: allow connecting to TRX1..N, not only TRX0 */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003853private 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 +02003854 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003855 connect(vc_conn:RSL, bts[0][0].rsl.vc_RSL:CLIENT_PT);
3856 connect(vc_conn:RSL_PROC, bts[0][0].rsl.vc_RSL:RSL_PROC);
3857 if (isvalue(bts[1][0])) {
3858 connect(vc_conn:RSL1, bts[1][0].rsl.vc_RSL:CLIENT_PT);
3859 connect(vc_conn:RSL1_PROC, bts[1][0].rsl.vc_RSL:RSL_PROC);
Philipp Maier956a92f2018-02-16 10:58:07 +01003860 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003861 if (isvalue(bts[2][0])) {
3862 connect(vc_conn:RSL2, bts[2][0].rsl.vc_RSL:CLIENT_PT);
3863 connect(vc_conn:RSL2_PROC, bts[2][0].rsl.vc_RSL:RSL_PROC);
Neels Hofmeyr91401012019-07-11 00:42:35 +02003864 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003865 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003866 if (mp_enable_lcs_tests) {
3867 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3868 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3869 }
Daniel Willmannebdecc02020-08-12 15:30:17 +02003870 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003871 connect(vc_conn:MGCP_PROC, vc_MGCP[mgwpool_idx]:MGCP_PROC);
3872 connect(vc_conn:MGCP, vc_MGCP[mgwpool_idx]:MGCP_CLIENT);
3873 connect(vc_conn:MGCP_MULTI, vc_MGCP[mgwpool_idx]:MGCP_CLIENT_MULTI);
Harald Welte336820c2018-05-31 20:34:52 +02003874}
3875
Neels Hofmeyrda436782021-07-20 22:09:06 +02003876function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003877runs on test_CT return MSC_ConnHdlr {
3878 var charstring id := testcasename();
3879 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003880 var integer bssap_idx := 0;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003881 var integer mgwpool_idx := 0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003882 if (isvalue(pars)) {
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003883 var TestHdlrParams pars_val := valueof(pars);
3884 bssap_idx := pars_val.mscpool.bssap_idx;
3885 mgwpool_idx := pars_val.mgwpool_idx;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003886 }
Harald Welte336820c2018-05-31 20:34:52 +02003887 vc_conn := MSC_ConnHdlr.create(id);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003888 f_connect_handler(vc_conn, bssap_idx, mgwpool_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003889 return vc_conn;
3890}
3891
3892function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3893runs on test_CT return MSC_ConnHdlr {
3894 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003895 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003896 return vc_conn;
3897}
3898
Neels Hofmeyrda436782021-07-20 22:09:06 +02003899function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3900runs on test_CT return MSC_ConnHdlr {
3901 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3902}
3903
Harald Weltea0630032018-03-20 21:09:55 +01003904/* first function inside ConnHdlr component; sets g_pars + starts function */
3905private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3906runs on MSC_ConnHdlr {
3907 if (isvalue(pars)) {
3908 g_pars := valueof(pars);
3909 }
3910 fn.apply(id);
3911}
3912
Oliver Smith26a3db72021-07-09 13:51:29 +02003913private function f_vty_encryption_a5(charstring options) runs on test_CT {
3914 f_vty_transceive(BSCVTY, "configure terminal");
3915 f_vty_transceive(BSCVTY, "network");
3916 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3917 f_vty_transceive(BSCVTY, "exit");
3918 f_vty_transceive(BSCVTY, "exit");
3919}
3920
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003921const charstring VTY_A5_DEFAULT := "0 1 3";
3922
Oliver Smith26a3db72021-07-09 13:51:29 +02003923private function f_vty_encryption_a5_reset() runs on test_CT {
3924 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003925 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003926}
3927
Harald Welte3c86ea02018-05-10 22:28:05 +02003928/* Establish signalling channel (non-assignment case) followed by cipher mode */
3929private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003930 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3931 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003932 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003933 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3934 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3935 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3936 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003937
Philipp Maier23000732018-05-18 11:25:37 +02003938 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003939 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003940}
3941testcase TC_ciph_mode_a5_0() runs on test_CT {
3942 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003943 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003944 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3945
3946 f_init(1, true);
3947 f_sleep(1.0);
3948 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3949 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003950 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003951}
3952testcase TC_ciph_mode_a5_1() runs on test_CT {
3953 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003954 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003955 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3956
3957 f_init(1, true);
3958 f_sleep(1.0);
3959 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3960 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003961 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003962}
Oliver Smith50b98122021-07-09 15:00:28 +02003963/* OS#4975: verify that A5/2 is preferred over A5/0 */
3964testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3965 var MSC_ConnHdlr vc_conn;
3966 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3967
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003968 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003969
3970 f_init(1, true);
3971 f_vty_encryption_a5("0 1 2 3");
3972 f_sleep(1.0);
3973 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3974 vc_conn.done;
3975 f_vty_encryption_a5_reset();
3976 f_shutdown_helper();
3977}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003978/* OS#4975: verify that A5/1 is preferred over A5/2 */
3979testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3980 var MSC_ConnHdlr vc_conn;
3981 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3982
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003983 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003984
3985 f_init(1, true);
3986 f_vty_encryption_a5("1 2");
3987 f_sleep(1.0);
3988 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3989 vc_conn.done;
3990 f_vty_encryption_a5_reset();
3991 f_shutdown_helper();
3992}
Harald Welte3c86ea02018-05-10 22:28:05 +02003993testcase TC_ciph_mode_a5_3() runs on test_CT {
3994 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003995 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003996 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3997
3998 f_init(1, true);
3999 f_sleep(1.0);
4000 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4001 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004002 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004003}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004004/* Establish a Signalling channel with A5/4 encryption. */
4005testcase TC_ciph_mode_a5_4() runs on test_CT {
4006 var MSC_ConnHdlr vc_conn;
4007 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4008 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02004009
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004010 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02004011 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004012 f_sleep(1.0);
4013 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4014 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02004015 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004016 f_shutdown_helper();
4017}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004018/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
4019private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
4020 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4021 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
4022 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4023 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4024
4025 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004026 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004027}
4028testcase TC_assignment_aoip_tla_v6() runs on test_CT {
4029 var MSC_ConnHdlr vc_conn;
4030 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4031
4032 f_init(1, true);
4033 f_sleep(1.0);
4034 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
4035 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004036 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004037}
4038
Harald Welte3c86ea02018-05-10 22:28:05 +02004039
4040/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02004041private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004042 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4043 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004044
Harald Welte552620d2017-12-16 23:21:36 +01004045 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4046 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01004047
Harald Weltea0630032018-03-20 21:09:55 +01004048 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004049 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004050}
Harald Welte552620d2017-12-16 23:21:36 +01004051testcase TC_assignment_fr_a5_0() runs on test_CT {
4052 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004053 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004054 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01004055
Harald Welte89d42e82017-12-17 16:42:41 +01004056 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004057 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004058 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004059 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004060 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004061}
Harald Welte552620d2017-12-16 23:21:36 +01004062testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01004063 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004064 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004065 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004066
Harald Welte89d42e82017-12-17 16:42:41 +01004067 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004068 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004069 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4070 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004071 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02004072}
4073testcase TC_assignment_fr_a5_3() runs on test_CT {
4074 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004075 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004076 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004077
Harald Welte651fcdc2018-05-10 20:23:16 +02004078 f_init(1, true);
4079 f_sleep(1.0);
4080 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004081 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004082 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004083}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004084/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
4085testcase TC_assignment_fr_a5_4() runs on test_CT {
4086 var MSC_ConnHdlr vc_conn;
4087 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4088 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
4089
4090 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004091 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004092 f_sleep(1.0);
4093 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4094 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02004095 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004096 f_shutdown_helper();
4097}
Harald Weltec1a2fff2017-12-17 11:06:19 +01004098
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02004099/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
4100testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
4101 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4102 var MSC_ConnHdlr vc_conn;
4103
4104 f_init(1, true);
4105 f_sleep(1.0);
4106
4107 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4108 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4109 vc_conn.done;
4110 f_shutdown_helper();
4111}
4112
Harald Welte552620d2017-12-16 23:21:36 +01004113/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4114private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004115 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004116 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004117 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004118
4119 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004120 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4121
Harald Weltea0630032018-03-20 21:09:55 +01004122 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004123 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004124}
Harald Welte552620d2017-12-16 23:21:36 +01004125testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4126 var MSC_ConnHdlr vc_conn;
4127
Harald Welte89d42e82017-12-17 16:42:41 +01004128 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004129 f_sleep(1.0);
4130
Harald Welte8863fa12018-05-10 20:15:27 +02004131 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004132 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004133 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004134}
4135
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004136private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4137 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4138 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004139
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004140 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4141 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4142
4143 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4144
4145 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004146
4147 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4148 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4149
4150 f_create_chan_and_exp();
4151 /* we should now have a COMPL_L3 at the MSC */
4152
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004153 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004154 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004155 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004156}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004157testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4158 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004159 var MSC_ConnHdlr vc_conn;
4160
Harald Welte89d42e82017-12-17 16:42:41 +01004161 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004162 f_sleep(1.0);
4163
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004164 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004165 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004166 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004167 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004168}
4169
4170
Harald Welte4532e0a2017-12-23 02:05:44 +01004171private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004172 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004173 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004174 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004175 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004176
4177 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004178 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004179
4180 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004181 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4182 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004183 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4184 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4185 };
4186 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004187 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004188}
4189
4190testcase TC_assignment_sign() runs on test_CT {
4191 var MSC_ConnHdlr vc_conn;
4192
4193 f_init(1, true);
4194 f_sleep(1.0);
4195
Harald Welte8863fa12018-05-10 20:15:27 +02004196 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004197 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004198 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004199}
4200
Harald Welte60aa5762018-03-21 19:33:13 +01004201/***********************************************************************
4202 * Codec (list) testing
4203 ***********************************************************************/
4204
4205/* check if the given rsl_mode is compatible with the a_elem */
4206private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4207return boolean {
4208 select (a_elem.codecType) {
4209 case (GSM_FR) {
4210 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4211 return true;
4212 }
4213 }
4214 case (GSM_HR) {
4215 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4216 return true;
4217 }
4218 }
4219 case (GSM_EFR) {
4220 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4221 return true;
4222 }
4223 }
4224 case (FR_AMR) {
4225 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4226 return true;
4227 }
4228 }
4229 case (HR_AMR) {
4230 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4231 return true;
4232 }
4233 }
4234 case else { }
4235 }
4236 return false;
4237}
4238
4239/* check if the given rsl_mode is compatible with the a_list */
4240private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4241return boolean {
4242 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4243 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4244 return true;
4245 }
4246 }
4247 return false;
4248}
4249
4250/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004251function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004252return BSSMAP_IE_ChannelType {
4253 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4254 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4255 select (a_elem.codecType) {
4256 case (GSM_FR) {
4257 ret.channelRateAndType := ChRate_TCHF;
4258 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4259 }
4260 case (GSM_HR) {
4261 ret.channelRateAndType := ChRate_TCHH;
4262 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4263 }
4264 case (GSM_EFR) {
4265 ret.channelRateAndType := ChRate_TCHF;
4266 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4267 }
4268 case (FR_AMR) {
4269 ret.channelRateAndType := ChRate_TCHF;
4270 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4271 }
4272 case (HR_AMR) {
4273 ret.channelRateAndType := ChRate_TCHH;
4274 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4275 }
4276 case else {
4277 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004278 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004279 }
4280 }
4281 return ret;
4282}
4283
Harald Weltea63b9102018-03-22 20:36:16 +01004284private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4285return template RSL_IE_Body {
4286 var template RSL_IE_Body mode_ie := {
4287 chan_mode := {
4288 len := ?,
4289 reserved := ?,
4290 dtx_d := ?,
4291 dtx_u := ?,
4292 spd_ind := RSL_SPDI_SPEECH,
4293 ch_rate_type := -,
4294 coding_alg_rate := -
4295 }
4296 }
4297
4298 select (a_elem.codecType) {
4299 case (GSM_FR) {
4300 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4301 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4302 }
4303 case (GSM_HR) {
4304 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4305 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4306 }
4307 case (GSM_EFR) {
4308 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4309 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4310 }
4311 case (FR_AMR) {
4312 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4313 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4314 }
4315 case (HR_AMR) {
4316 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4317 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4318 }
4319 }
4320 return mode_ie;
4321}
4322
Harald Welte60aa5762018-03-21 19:33:13 +01004323type record CodecListTest {
4324 BSSMAP_IE_SpeechCodecList codec_list,
4325 charstring id
4326}
4327type record of CodecListTest CodecListTests
4328
4329private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004330 f_assignment_codec(id);
4331}
4332
4333private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02004334 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02004335 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Harald Welte60aa5762018-03-21 19:33:13 +01004336
4337 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004338 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004339 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4340 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4341 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004342 if (isvalue(g_pars.expect_mr_s0_s7)) {
4343 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4344 g_pars.expect_mr_s0_s7;
4345 }
Harald Welte79f3f542018-05-25 20:02:37 +02004346 }
Harald Welte60aa5762018-03-21 19:33:13 +01004347 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4348 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004349 log("expecting ASS COMPL like this: ", exp_compl);
4350
4351 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004352
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004353 if (not g_pars.expect_channel_mode_modify) {
4354 /* Verify that the RSL-side activation actually matches our expectations */
4355 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004356
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004357 var RSL_IE_Body mode_ie;
4358 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4359 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004360 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004361 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004362 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4363 if (not match(mode_ie, t_mode_ie)) {
4364 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4365 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004366 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004367
4368 var RSL_IE_Body mr_conf;
4369 if (g_pars.expect_mr_conf_ie != omit) {
4370 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4371 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4372 mtc.stop;
4373 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004374 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004375
4376 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
Vadim Yanitskiy8b189372022-09-14 17:31:17 +07004377 setverdict(fail, "RSL MR CONFIG IE does not match expectation. ",
4378 "Expected: ", g_pars.expect_mr_conf_ie, ", got: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004379 }
4380 } else {
4381 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4382 log("found RSL MR CONFIG IE: ", mr_conf);
4383 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4384 mtc.stop;
4385 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004386 }
4387 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004388
4389 if (do_perform_clear) {
4390 f_perform_clear();
4391 }
Harald Welte60aa5762018-03-21 19:33:13 +01004392}
4393
Philipp Maierd0e64b02019-03-13 14:15:23 +01004394private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4395
4396 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4397 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4398
4399 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004400 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004401 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4402 }
4403 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4404 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4405 log("expecting ASS FAIL like this: ", exp_fail);
4406
4407 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004408 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004409}
4410
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004411const CounterNameVals counternames_bsc_bts_assignment := {
4412 { "assignment:attempted", 0 },
4413 { "assignment:completed", 0 },
4414 { "assignment:stopped", 0 },
4415 { "assignment:no_channel", 0 },
4416 { "assignment:timeout", 0 },
4417 { "assignment:failed", 0 },
4418 { "assignment:error", 0 }
4419};
4420
4421const CounterNameVals counternames_bts_assignment := {
4422 { "assignment:attempted_sign", 0 },
4423 { "assignment:attempted_speech", 0 },
4424 { "assignment:completed_sign", 0 },
4425 { "assignment:completed_speech", 0 },
4426 { "assignment:stopped_sign", 0 },
4427 { "assignment:stopped_speech", 0 },
4428 { "assignment:no_channel_sign", 0 },
4429 { "assignment:no_channel_speech", 0 },
4430 { "assignment:timeout_sign", 0 },
4431 { "assignment:timeout_speech", 0 },
4432 { "assignment:failed_sign", 0 },
4433 { "assignment:failed_speech", 0 },
4434 { "assignment:error_sign", 0 },
4435 { "assignment:error_speech", 0 }
4436};
4437
4438function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4439 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4440 f_ctrs_bts_init(bts_count, bts_names);
4441 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4442}
4443
Harald Welte60aa5762018-03-21 19:33:13 +01004444testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004445 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004446 var MSC_ConnHdlr vc_conn;
4447
4448 f_init(1, true);
4449 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004450 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004451
4452 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004453 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004454 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004455
4456 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4457 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4458 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4459 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4460 f_ctrs_bts_verify();
4461
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004462 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004463}
4464
4465testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004466 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004467 var MSC_ConnHdlr vc_conn;
4468
4469 f_init(1, true);
4470 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004471 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004472
4473 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004474 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004475 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004476
4477 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4478 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4479 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4480 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4481 f_ctrs_bts_verify();
4482
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004483 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004484}
4485
4486testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004487 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004488 var MSC_ConnHdlr vc_conn;
4489
4490 f_init(1, true);
4491 f_sleep(1.0);
4492
4493 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004494 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004495 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004496 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004497}
4498
Philipp Maierd0e64b02019-03-13 14:15:23 +01004499/* Allow 5,90k only (current default config) */
4500private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004501 f_vty_cfg_msc(BSCVTY, 0, {
4502 "amr-config 12_2k forbidden",
4503 "amr-config 10_2k forbidden",
4504 "amr-config 7_95k forbidden",
4505 "amr-config 7_40k forbidden",
4506 "amr-config 6_70k forbidden",
4507 "amr-config 5_90k allowed",
4508 "amr-config 5_15k forbidden",
4509 "amr-config 4_75k forbidden"
4510 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004511}
4512
4513/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4514 * ("Config-NB-Code = 1") */
4515private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004516 f_vty_cfg_msc(BSCVTY, 0, {
4517 "amr-config 12_2k allowed",
4518 "amr-config 10_2k forbidden",
4519 "amr-config 7_95k forbidden",
4520 "amr-config 7_40k allowed",
4521 "amr-config 6_70k forbidden",
4522 "amr-config 5_90k allowed",
4523 "amr-config 5_15k forbidden",
4524 "amr-config 4_75k allowed"
4525 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004526}
4527
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004528private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4529 var charstring tch;
4530 if (fr) {
4531 tch := "tch-f";
4532 } else {
4533 tch := "tch-h";
4534 }
4535 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4536}
4537
4538/* Set the AMR start-mode for this TCH back to the default configuration. */
4539private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4540 f_vty_amr_start_mode_set(fr, "auto");
4541}
4542
Harald Welte60aa5762018-03-21 19:33:13 +01004543testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004544 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004545 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004546
4547 /* Note: This setups the codec configuration. The parameter payload in
4548 * mr_conf must be consistant with the parameter codecElements in pars
4549 * and also must match the amr-config in osmo-bsc.cfg! */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004550 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004551 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004552 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004553 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004554
Harald Welte60aa5762018-03-21 19:33:13 +01004555 f_init(1, true);
4556 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004557 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004558 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004559
Harald Welte8863fa12018-05-10 20:15:27 +02004560 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004561 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004562
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004563 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4564 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4565 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4566 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4567 f_ctrs_bts_verify();
4568
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004569 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004570 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004571}
4572
4573testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004574 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004575 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004576
4577 /* See note above */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004578 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004579 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004580 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004581 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004582
Harald Welte60aa5762018-03-21 19:33:13 +01004583 f_init(1, true);
4584 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004585 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004586 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004587
Harald Welte8863fa12018-05-10 20:15:27 +02004588 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004589 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004590
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004591 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4592 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4593 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4594 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4595 f_ctrs_bts_verify();
4596
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004597 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004598 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004599}
4600
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004601/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4602testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4603 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4604 var MSC_ConnHdlr vc_conn;
4605
4606 f_init(1, true);
4607 f_sleep(1.0);
4608
4609 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4610 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4611 * expecting a Channel Mode Modify if the channel type is compatible. */
4612 f_disable_all_sdcch();
4613 f_disable_all_tch_h();
4614
4615 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4616 pars.expect_channel_mode_modify := true;
4617 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4618 vc_conn.done;
4619
4620 f_enable_all_sdcch();
4621 f_enable_all_tch();
4622 f_shutdown_helper();
4623}
4624
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004625/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4626testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4627 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4628 var MSC_ConnHdlr vc_conn;
4629
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004630 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4631 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4632 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy36fe9582022-09-14 15:25:04 +07004633 pars.expect_mr_conf_ie := c_mr_conf_5_90;
4634 pars.expect_mr_conf_ie.multirate_cfg.icmi := false; /* expect ICMI=0, smod=00: */
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004635
4636 f_init(1, true);
4637 f_sleep(1.0);
4638
4639 /* First set nonzero start mode bits */
4640 f_vty_amr_start_mode_set(true, "4");
4641 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4642 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4643 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4644 f_vty_amr_start_mode_set(true, "auto");
4645
4646 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4647 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004648
4649 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4650 f_vty_amr_start_mode_set(true, "1");
4651 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004652 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004653}
4654
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004655function f_TC_assignment_codec_amr(boolean fr, RSL_IE_MultirateCfg mr_cfg,
4656 bitstring s8_s0, bitstring exp_s8_s0,
4657 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004658runs on test_CT {
4659
4660 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4661 var MSC_ConnHdlr vc_conn;
4662
Philipp Maierd0e64b02019-03-13 14:15:23 +01004663 if (fr) {
4664 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4665 } else {
4666 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4667 }
4668 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4669 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004670 pars.expect_mr_conf_ie := { multirate_cfg := mr_cfg };
Philipp Maierd0e64b02019-03-13 14:15:23 +01004671 pars.expect_mr_s0_s7 := exp_s8_s0;
4672
4673 f_init(1, true);
4674 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004675 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004676 f_sleep(1.0);
4677
4678 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4679 vc_conn.done;
4680 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004681 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004682}
4683
4684function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4685runs on test_CT {
4686
4687 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4688 var MSC_ConnHdlr vc_conn;
4689
4690 if (fr) {
4691 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4692 } else {
4693 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4694 }
4695 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4696 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4697
4698 f_init(1, true);
4699 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004700 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004701 f_sleep(1.0);
4702
4703 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4704 vc_conn.done;
4705 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004706 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004707}
4708
Philipp Maierd0e64b02019-03-13 14:15:23 +01004709/* Set S1, we expect an AMR multirate configuration IE with all four rates
4710 * set. */
4711testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004712 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4713 params := '20882208'O));
4714 f_TC_assignment_codec_amr(true, mr_cfg, '00000011'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004715 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004716}
4717
4718/* Set S1, we expect an AMR multirate configuration IE with the lower three
4719 * rates set. */
4720testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004721 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4722 params := '208820'O));
4723 f_TC_assignment_codec_amr(false, mr_cfg, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004724 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004725}
4726
4727/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4728 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4729testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004730 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4731 params := '20882208'O));
4732 f_TC_assignment_codec_amr(true, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004733 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004734}
4735
4736/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4737 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4738testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004739 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4740 params := '208820'O));
4741 f_TC_assignment_codec_amr(false, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004742 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004743}
4744
4745/* The following block of tests selects more and more rates until all four
4746 * possible rates are in the active set (full rate) */
4747testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004748 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4749 f_TC_assignment_codec_amr(true, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004750 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004751}
4752
4753testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004754 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4755 params := '2080'O));
4756 f_TC_assignment_codec_amr(true, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004757 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004758}
4759
4760testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004761 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4762 params := '208820'O));
4763 f_TC_assignment_codec_amr(true, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004764 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004765}
4766
4767testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004768 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4769 params := '20882208'O));
4770 f_TC_assignment_codec_amr(true, mr_cfg, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004771 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004772}
4773
4774/* The following block of tests selects more and more rates until all three
4775 * possible rates are in the active set (half rate) */
4776testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004777 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4778 f_TC_assignment_codec_amr(false, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004779 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004780}
4781
4782testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004783 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4784 params := '2080'O));
4785 f_TC_assignment_codec_amr(false, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004786 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004787}
4788
4789testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004790 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4791 params := '208820'O));
4792 f_TC_assignment_codec_amr(false, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004793 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004794}
4795
4796/* The following block tests what happens when the MSC does offer rate
4797 * configurations that are not supported by the BSC. Normally such situations
4798 * should not happen because the MSC gets informed by the BSC in advance via
4799 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4800 * to offer rates that are not applicable anyway. */
4801
4802testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004803 /* Try to include 12,2k in into the active set even though the channel
4804 * is half rate only. The BSC is expected to remove the 12,0k */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004805 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4806 params := '208820'O));
4807 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004808 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004809}
4810
4811testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004812 /* See what happens when all rates are selected at once. Since then
4813 * Also S1 is selected, this setting will be prefered and we should
4814 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004815 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4816 params := '20882208'O));
4817 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004818 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004819}
4820
4821testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004822 /* Same as above, but with S1 missing, the MSC is then expected to
4823 * select the currently supported rates, which are also 12.2k, 7,40k,
4824 * 5,90k, and 4,75k, into the active set. */
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, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004828 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004829}
4830
4831testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004832 /* Try to select no rates at all */
4833 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004834 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004835}
4836
4837testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004838 /* Try to select only unsupported rates */
4839 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004840 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004841}
4842
4843testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004844 /* Try to select 12,2k for half rate */
4845 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004846 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004847}
4848
Neels Hofmeyr21863562020-11-26 00:34:33 +00004849testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004850 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4851 codec_modes := '10010101'B,
4852 params := '20882208'O));
4853 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004854 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004855}
4856
4857testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004858 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4859 codec_modes := '00010101'B,
4860 params := '208820'O));
4861 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B,
Neels Hofmeyr21863562020-11-26 00:34:33 +00004862 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004863 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004864}
4865
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004866testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004867 /* "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 +07004868 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 3,
4869 codec_modes := '10010101'B,
4870 params := '20882208'O));
4871 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004872 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004873}
4874
4875testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004876 /* "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 +07004877 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 2,
4878 codec_modes := '00010101'B,
4879 params := '208820'O));
4880 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004881 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004882}
4883
Philipp Maierac09bfc2019-01-08 13:41:39 +01004884private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004885 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4886 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4887 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4888 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004889}
4890
4891private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004892 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4893 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004894}
4895
4896private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004897 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4898 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4899 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4900 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4901 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4902 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004903}
4904
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004905private function f_disable_all_sdcch() runs on test_CT {
4906 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4907 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4908 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4909 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4910}
4911
4912private function f_enable_all_sdcch() runs on test_CT {
4913 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4914 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4915 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4916 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4917}
4918
Philipp Maierac09bfc2019-01-08 13:41:39 +01004919/* Allow HR only */
4920private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4921 g_pars := f_gen_test_hdlr_pars();
4922 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4923 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4924 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4925 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4926 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4927 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4928 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004929 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004930}
4931
4932/* Allow FR only */
4933private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4934 g_pars := f_gen_test_hdlr_pars();
4935 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4936 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4937 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4938 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4939 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4940 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4941 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004942 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004943}
4944
4945/* Allow HR only (expect assignment failure) */
4946private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4947 g_pars := f_gen_test_hdlr_pars();
4948 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4949 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4950 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4951 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4952 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4953 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4954 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004955 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004956}
4957
4958/* Allow FR only (expect assignment failure) */
4959private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4960 g_pars := f_gen_test_hdlr_pars();
4961 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4962 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4963 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4964 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4965 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4966 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4967 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004968 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004969}
4970
4971/* Allow FR and HR, but prefer FR */
4972private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4973 g_pars := f_gen_test_hdlr_pars();
4974 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4975 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4976 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4977 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4978 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4979 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4980 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4981 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004982 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004983}
4984
4985/* Allow FR and HR, but prefer HR */
4986private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4987 g_pars := f_gen_test_hdlr_pars();
4988 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4989 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4990 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4991 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4992 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4993 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4994 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4995 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004996 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004997}
4998
4999/* Allow FR and HR, but prefer FR */
5000private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5001 g_pars := f_gen_test_hdlr_pars();
5002 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5003 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5004 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5005 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5006 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5007 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5008 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5009 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005010 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005011}
5012
5013/* Allow FR and HR, but prefer HR */
5014private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5015 g_pars := f_gen_test_hdlr_pars();
5016 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5017 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5018 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5019 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5020 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5021 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5022 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5023 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005024 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005025}
5026
5027/* Request a HR channel while all FR channels are exhausted, this is expected
5028 * to work without conflicts */
5029testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
5030 var MSC_ConnHdlr vc_conn;
5031 f_init(1, true);
5032 f_sleep(1.0);
5033 f_enable_all_tch();
5034 f_disable_all_tch_f();
5035 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
5036 vc_conn.done;
5037 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005038 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005039}
5040
5041/* Request a FR channel while all FR channels are exhausted, this is expected
5042 * to fail. */
5043testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
5044 var MSC_ConnHdlr vc_conn;
5045 f_init(1, true);
5046 f_sleep(1.0);
5047 f_enable_all_tch();
5048 f_disable_all_tch_f();
5049 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
5050 vc_conn.done;
5051 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005052 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005053}
5054
5055/* Request a FR (prefered) or alternatively a HR channel while all FR channels
5056 * are exhausted, this is expected to be resolved by selecting a HR channel. */
5057testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
5058 var MSC_ConnHdlr vc_conn;
5059 f_init(1, true);
5060 f_sleep(1.0);
5061 f_enable_all_tch();
5062 f_disable_all_tch_f();
5063 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
5064 vc_conn.done;
5065 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005066 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005067}
5068
5069/* Request a HR (prefered) or alternatively a FR channel while all FR channels
5070 * are exhausted, this is expected to work without conflicts. */
5071testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
5072 var MSC_ConnHdlr vc_conn;
5073 f_init(1, true);
5074 f_sleep(1.0);
5075 f_enable_all_tch();
5076 f_disable_all_tch_f();
5077 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
5078 vc_conn.done;
5079 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005080 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005081}
5082
5083/* Request a FR channel while all HR channels are exhausted, this is expected
5084 * to work without conflicts */
5085testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
5086 var MSC_ConnHdlr vc_conn;
5087 f_init(1, true);
5088 f_sleep(1.0);
5089 f_enable_all_tch();
5090 f_disable_all_tch_h();
5091 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
5092 vc_conn.done;
5093 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005094 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005095}
5096
5097/* Request a HR channel while all HR channels are exhausted, this is expected
5098 * to fail. */
5099testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
5100 var MSC_ConnHdlr vc_conn;
5101 f_init(1, true);
5102 f_sleep(1.0);
5103 f_enable_all_tch();
5104 f_disable_all_tch_h();
5105 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
5106 vc_conn.done;
5107 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005108 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005109}
5110
5111/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5112 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5113testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5114 var MSC_ConnHdlr vc_conn;
5115 f_init(1, true);
5116 f_sleep(1.0);
5117 f_enable_all_tch();
5118 f_disable_all_tch_h();
5119 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5120 vc_conn.done;
5121 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005122 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005123}
5124
5125/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5126 * are exhausted, this is expected to work without conflicts. */
5127testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5128 var MSC_ConnHdlr vc_conn;
5129 f_init(1, true);
5130 f_sleep(1.0);
5131 f_enable_all_tch();
5132 f_disable_all_tch_h();
5133 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5134 vc_conn.done;
5135 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005136 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005137}
5138
5139/* Allow FR and HR, but prefer HR */
5140private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5141 g_pars := f_gen_test_hdlr_pars();
5142 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5143 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5144 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5145 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5146 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5147 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5148 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5149 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005150 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005151}
5152
5153/* Allow FR and HR, but prefer FR */
5154private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5155 g_pars := f_gen_test_hdlr_pars();
5156 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5157 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5158 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5159 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5160 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5161 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5162 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5163 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005164 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005165}
5166
5167/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5168 * HR, which is the prefered type, is selected. */
5169testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5170 var MSC_ConnHdlr vc_conn;
5171 f_init(1, true);
5172 f_sleep(1.0);
5173 f_enable_all_tch();
5174 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5175 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005176 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005177}
5178
5179/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5180 * FR, which is the prefered type, is selected. */
5181testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5182 var MSC_ConnHdlr vc_conn;
5183 f_init(1, true);
5184 f_sleep(1.0);
5185 f_enable_all_tch();
5186 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5187 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005188 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005189}
5190
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005191/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5192private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5193 g_pars := f_gen_test_hdlr_pars();
5194 g_pars.ra := '02'O; /* RA containing reason=LU */
5195
5196 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5197 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5198 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5199 var template uint3_t tsc := ?;
5200
5201 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5202 f_create_bssmap_exp(l3_enc);
5203 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5204 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5205
5206 /* we should now have a COMPL_L3 at the MSC */
5207 timer T := 10.0;
5208 T.start;
5209 alt {
5210 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5211 [] T.timeout {
5212 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5213 }
5214 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005215
5216 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005217}
5218testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5219 var MSC_ConnHdlr vc_conn;
5220 f_init(1, true);
5221 f_sleep(1.0);
5222 f_disable_all_sdcch();
5223 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5224 vc_conn.done;
5225 f_enable_all_sdcch();
5226 f_shutdown_helper();
5227}
5228
5229/* Request a signalling channel with all SDCCH exhausted, it is
5230 expected that no TCH will be selected for signalling and assigment will fail
5231 because it's dictated by VTY config */
5232testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5233 var RSL_Message rsl_unused, rsl_msg;
5234 var GsmRrMessage rr;
5235 f_init(1, false);
5236 f_sleep(1.0);
5237 f_vty_allow_tch_for_signalling(false, 0);
5238 f_disable_all_sdcch();
5239
5240 /* RA containing reason=LU */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005241 f_ipa_tx(ts_RSL_CHAN_RQD('02'O, 2342));
5242 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005243 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5244 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5245 setverdict(fail, "Expected reject");
5246 }
5247
5248 f_vty_allow_tch_for_signalling(true, 0);
5249 f_enable_all_sdcch();
5250 f_shutdown_helper();
5251}
5252
5253/* Request a voice channel with all SDCCH exhausted, it is
5254 * expected that TCH channel will be allocated since the VTY option is only
5255 * aimed at signalling requests */
5256private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5257 g_pars := f_gen_test_hdlr_pars();
5258 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5259
5260 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5261 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5262 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5263 var template uint3_t tsc := ?;
5264
5265 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5266 f_create_bssmap_exp(l3_enc);
5267 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5268 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5269
5270 /* we should now have a COMPL_L3 at the MSC */
5271 timer T := 10.0;
5272 T.start;
5273 alt {
5274 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5275 [] T.timeout {
5276 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5277 }
5278 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005279 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005280}
5281testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5282 var MSC_ConnHdlr vc_conn;
5283 f_init(1, true);
5284 f_sleep(1.0);
5285 f_vty_allow_tch_for_signalling(false, 0);
5286 f_disable_all_sdcch();
5287
5288 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5289 vc_conn.done;
5290
5291 f_vty_allow_tch_for_signalling(true, 0);
5292 f_enable_all_sdcch();
5293 f_shutdown_helper();
5294}
5295
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005296/* Test Osmux setup BSC<->MSC */
5297testcase TC_assignment_osmux_cn() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005298 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5299 var MSC_ConnHdlr vc_conn;
5300
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005301 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5302 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5303 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiyb9bf00f2022-09-14 15:35:37 +07005304 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02005305 pars.use_osmux_cn := true;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005306
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02005307 g_osmux_enabled_cn := true;
5308 f_init(1, true);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005309 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005310 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005311
5312 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5313 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005314
5315 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005316 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005317}
5318
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005319/* Test Osmux setup BTS<->BSC */
5320testcase TC_assignment_osmux_bts() runs on test_CT {
5321 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5322 var MSC_ConnHdlr vc_conn;
5323
5324 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5325 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5326 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005327 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005328 pars.use_osmux_bts := true;
5329
5330 g_osmux_enabled_bts := true;
5331 f_init(1, true);
5332 f_sleep(1.0);
5333 f_vty_amr_start_mode_set(false, "1");
5334
5335 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5336 vc_conn.done;
5337
5338 f_vty_amr_start_mode_restore(false);
5339 f_shutdown_helper();
5340}
5341
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +02005342/* Test non-AMR codecs still work fine as RTP when Osmux is enabled BTS<->BSC<->MSC */
5343testcase TC_assignment_codec_hr_osmux_on() runs on test_CT {
5344 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5345 var MSC_ConnHdlr vc_conn;
5346
5347 g_osmux_enabled_cn := true;
5348 g_osmux_enabled_bts := true;
5349 f_init(1, true);
5350 f_sleep(1.0);
5351 f_ctrs_bsc_and_bts_assignment_init(1);
5352
5353 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5354 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5355 vc_conn.done;
5356
5357 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
5358 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
5359 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
5360 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
5361 f_ctrs_bts_verify();
5362
5363 f_shutdown_helper();
5364}
5365
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005366/* Test Osmux setup BTS<->BSC<->MSC */
5367testcase TC_assignment_osmux() runs on test_CT {
5368 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5369 var MSC_ConnHdlr vc_conn;
5370
5371 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5372 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5373 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005374 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005375 pars.use_osmux_cn := true;
5376 pars.use_osmux_bts := true;
5377
5378 g_osmux_enabled_cn := true;
5379 g_osmux_enabled_bts := true;
5380 f_init(1, true);
5381 f_sleep(1.0);
5382 f_vty_amr_start_mode_set(false, "1");
5383
5384 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5385 vc_conn.done;
5386
5387 f_vty_amr_start_mode_restore(false);
5388 f_shutdown_helper();
5389}
5390
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005391/* test the procedure of the MSC requesting a Classmark Update:
5392 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5393 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005394private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005395 g_pars := f_gen_test_hdlr_pars();
5396
Harald Weltea0630032018-03-20 21:09:55 +01005397 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005398 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005399
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005400 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5401 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5402
Harald Welte898113b2018-01-31 18:32:21 +01005403 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5404 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5405 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005406
5407 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005408}
5409testcase TC_classmark() runs on test_CT {
5410 var MSC_ConnHdlr vc_conn;
5411 f_init(1, true);
5412 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005413 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005414 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005415 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005416}
5417
Harald Welteeddf0e92020-06-21 19:42:15 +02005418/* Send a CommonID from the simulated MSC and verify that the information is used to
5419 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5420private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5421 g_pars := f_gen_test_hdlr_pars();
5422 f_MscConnHdlr_init_vty();
5423
5424 f_create_chan_and_exp();
5425 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005426
5427 /* Send CommonID */
5428 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5429
5430 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5431 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5432 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5433
5434 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005435
5436 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005437}
5438testcase TC_common_id() runs on test_CT {
5439 var MSC_ConnHdlr vc_conn;
5440 f_init(1, true);
5441 f_sleep(1.0);
5442 vc_conn := f_start_handler(refers(f_tc_common_id));
5443 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005444 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005445}
5446
Harald Weltee3bd6582018-01-31 22:51:25 +01005447private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005448 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005449 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005450 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005451
Harald Weltee3bd6582018-01-31 22:51:25 +01005452 /* send the single message we want to send */
5453 f_rsl_send_l3(l3);
5454}
5455
5456private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5457 timer T := sec;
5458 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005459 T.start;
5460 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005461 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5462 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005463 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005464 }
5465 [] T.timeout {
5466 setverdict(pass);
5467 }
5468 }
5469}
5470
Harald Weltee3bd6582018-01-31 22:51:25 +01005471/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5472private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5473 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5474 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005475 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005476}
Harald Welte898113b2018-01-31 18:32:21 +01005477testcase TC_unsol_ass_fail() runs on test_CT {
5478 var MSC_ConnHdlr vc_conn;
5479 f_init(1, true);
5480 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005481 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005482 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005483 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005484}
Harald Welte552620d2017-12-16 23:21:36 +01005485
Harald Welteea99a002018-01-31 20:46:43 +01005486
5487/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5488private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005489 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5490 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005491 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005492}
5493testcase TC_unsol_ass_compl() runs on test_CT {
5494 var MSC_ConnHdlr vc_conn;
5495 f_init(1, true);
5496 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005497 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005498 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005499 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005500}
5501
5502
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005503/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5504private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005505 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5506 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005507 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005508}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005509testcase TC_unsol_ho_fail() runs on test_CT {
5510 var MSC_ConnHdlr vc_conn;
5511 f_init(1, true);
5512 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005513 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005514 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005515 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005516}
5517
5518
Harald Weltee3bd6582018-01-31 22:51:25 +01005519/* short message from MS should be ignored */
5520private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005521 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005522 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005523 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005524
5525 /* send short message */
5526 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5527 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005528 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005529}
5530testcase TC_err_82_short_msg() runs on test_CT {
5531 var MSC_ConnHdlr vc_conn;
5532 f_init(1, true);
5533 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005534 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005535 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005536 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005537}
5538
5539
Harald Weltee9e02e42018-01-31 23:36:25 +01005540/* 24.008 8.4 Unknown message must trigger RR STATUS */
5541private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5542 f_est_single_l3(ts_RRM_UL_REL('00'O));
5543 timer T := 3.0
5544 alt {
5545 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5546 setverdict(pass);
5547 }
5548 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005549 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005550 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005551 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005552}
5553testcase TC_err_84_unknown_msg() runs on test_CT {
5554 var MSC_ConnHdlr vc_conn;
5555 f_init(1, true);
5556 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005557 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005558 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005559 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005560}
5561
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005562/***********************************************************************
5563 * Handover
5564 ***********************************************************************/
5565
Harald Welte94e0c342018-04-07 11:33:23 +02005566/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5567private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5568runs on test_CT {
5569 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5570 " timeslot "&int2str(ts_nr)&" ";
5571 f_vty_transceive(BSCVTY, cmd & suffix);
5572}
5573
Harald Welte261af4b2018-02-12 21:20:39 +01005574/* 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 +07005575private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5576 uint8_t bts_nr, uint8_t trx_nr,
5577 in RslChannelNr chan_nr)
5578{
Harald Welte261af4b2018-02-12 21:20:39 +01005579 /* FIXME: resolve those from component-global state */
5580 var integer ts_nr := chan_nr.tn;
5581 var integer ss_nr;
5582 if (ischosen(chan_nr.u.ch0)) {
5583 ss_nr := 0;
5584 } else if (ischosen(chan_nr.u.lm)) {
5585 ss_nr := chan_nr.u.lm.sub_chan;
5586 } else if (ischosen(chan_nr.u.sdcch4)) {
5587 ss_nr := chan_nr.u.sdcch4.sub_chan;
5588 } else if (ischosen(chan_nr.u.sdcch8)) {
5589 ss_nr := chan_nr.u.sdcch8.sub_chan;
5590 } else {
5591 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005592 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005593 }
5594
5595 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5596 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005597 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005598}
5599
Neels Hofmeyr91401012019-07-11 00:42:35 +02005600/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5601 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5602 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5603 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5604 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005605private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5606 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5607{
5608 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005609}
5610
5611/* intra-BSC hand-over between BTS0 and BTS1 */
5612private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005613 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5614 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005615
5616 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5617 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5618
Harald Weltea0630032018-03-20 21:09:55 +01005619 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005620 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005621
5622 var HandoverState hs := {
5623 rr_ho_cmpl_seen := false,
5624 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005625 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005626 expect_target_tsc := c_BtsParams[1].tsc
Harald Welte261af4b2018-02-12 21:20:39 +01005627 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005628 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005629 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005630 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5631 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005632
5633 /* From the MGW perspective, a handover is is characterized by
5634 * performing one MDCX operation with the MGW. So we expect to see
5635 * one more MDCX during handover. */
5636 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5637
Harald Welte261af4b2018-02-12 21:20:39 +01005638 alt {
5639 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005640 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005641
Philipp Maier4dae0652018-11-12 12:03:26 +01005642 /* Since this is an internal handover we expect the BSC to inform the
5643 * MSC about the event */
5644 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5645
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005646 /* Check the amount of MGCP transactions is still consistant with the
5647 * test expectation */
5648 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005649
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005650 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5651
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005652 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5653 * 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 +02005654 f_verify_encr_info(chan_act);
5655
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005656 f_chan_act_verify_tsc(chan_act, c_BtsParams[1].tsc);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005657
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005658 f_perform_clear(RSL1, RSL1_PROC);
5659
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005660 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005661}
5662
5663testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005664 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005665 var MSC_ConnHdlr vc_conn;
5666 f_init(2, true);
5667 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005668
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005669 pars.expect_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005670
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005671 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005672
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005673 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005674 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005675
5676 /* from f_establish_fully() */
5677 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5678 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5679 /* from handover */
5680 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5681 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5682 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5683 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005684 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5685 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005686 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005687 f_shutdown_helper(ho := true);
Harald Welte261af4b2018-02-12 21:20:39 +01005688}
Harald Weltee9e02e42018-01-31 23:36:25 +01005689
Oliver Smith7eabd312021-07-12 14:18:56 +02005690function 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 +02005691 var MSC_ConnHdlr vc_conn;
5692 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5693 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5694
5695 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005696 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005697 f_sleep(1.0);
5698
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005699 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005700
5701 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5702 vc_conn.done;
5703
5704 /* from f_establish_fully() */
5705 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5706 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5707 /* from handover */
5708 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5709 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5710 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5711 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005712 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5713 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005714 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005715 f_vty_encryption_a5_reset();
Oliver Smith39f53072022-10-27 14:44:04 +02005716 f_shutdown_helper(ho := true);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005717}
5718
5719testcase TC_ho_int_a5_0() runs on test_CT {
5720 f_tc_ho_int_a5('01'O);
5721}
5722
5723testcase TC_ho_int_a5_1() runs on test_CT {
5724 f_tc_ho_int_a5('02'O);
5725}
5726
5727testcase TC_ho_int_a5_3() runs on test_CT {
5728 f_tc_ho_int_a5('08'O);
5729}
5730
5731testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005732 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005733}
5734
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005735/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5736private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5737 g_pars := f_gen_test_hdlr_pars();
5738 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5739 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005740
5741 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5742 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5743
5744 f_establish_fully(ass_cmd, exp_compl);
5745 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5746
5747 var HandoverState hs := {
5748 rr_ho_cmpl_seen := false,
5749 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005750 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005751 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005752 };
5753 /* issue hand-over command on VTY */
5754 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5755 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5756 f_rslem_suspend(RSL1_PROC);
5757
5758 /* From the MGW perspective, a handover is is characterized by
5759 * performing one MDCX operation with the MGW. So we expect to see
5760 * one more MDCX during handover. */
5761 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5762
5763 var RSL_Message rsl;
5764 var PDU_ML3_NW_MS l3;
5765 var RslChannelNr new_chan_nr;
5766 var GsmArfcn arfcn;
5767 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5768 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5769 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5770 setverdict(fail, "Expected handoverCommand");
5771 mtc.stop;
5772 }
5773 }
5774 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5775 new_chan_nr, arfcn);
5776
5777 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5778
5779 /* resume processing of RSL DChan messages, which was temporarily suspended
5780 * before performing a hand-over */
5781 f_rslem_resume(RSL1_PROC);
5782 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5783
5784 f_sleep(1.0);
5785
5786 /* Handover fails because no HANDO DET appears on the new lchan,
5787 * and the old lchan reports a Radio Link Failure. */
5788 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5789
5790 var PDU_BSSAP rx_clear_request;
5791 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5792 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5793 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5794
5795 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5796
5797 var MgcpCommand mgcp;
5798 interleave {
5799 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5800 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005801 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005802 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005803 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005804 }
5805 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005806 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005807 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005808 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005809 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005810 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5811 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5812 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005813 }
5814
5815 f_sleep(0.5);
5816 setverdict(pass);
5817}
5818testcase TC_ho_int_radio_link_failure() runs on test_CT {
5819 var MSC_ConnHdlr vc_conn;
5820 f_init(2, true);
5821 f_sleep(1.0);
5822
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005823 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005824
5825 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5826 vc_conn.done;
5827
5828 /* from f_establish_fully() */
5829 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5830 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5831 /* from handover */
5832 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5833 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5834 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5835 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005836 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5837 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005838 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005839 f_shutdown_helper(ho := true);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005840}
5841
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005842/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005843private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005844 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005845 var template MgcpResponse mgcp_resp;
5846 var MGCP_RecvFrom mrf;
5847 var template MgcpMessage msg_resp;
5848 var template MgcpMessage msg_dlcx := {
5849 command := tr_DLCX()
5850 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005851
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005852 if (g_pars.aoip) {
5853 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005854 log("Got first DLCX: ", mgcp);
5855 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005856 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005857
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005858 MGCP.receive(tr_DLCX()) -> value mgcp {
5859 log("Got second DLCX: ", mgcp);
5860 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5861 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005862 } else {
5863 /* For SCCPLite, BSC doesn't handle the MSC-side */
5864 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5865 log("Got first DLCX: ", mrf.msg.command);
5866 msg_resp := {
5867 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5868 }
5869 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5870 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005871 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005872}
5873
Oliver Smithc9a5f532022-10-21 11:32:23 +02005874private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit,
5875 boolean skip_meas_rep := false) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005876
Oliver Smithc9a5f532022-10-21 11:32:23 +02005877 if (not skip_meas_rep) {
5878 var NcellReports neighbor_rep := {
5879 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5880 };
5881 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5882 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5883 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005884
Oliver Smithc9a5f532022-10-21 11:32:23 +02005885 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
5886 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005887
5888 f_sleep(0.5);
5889 /* The MSC negotiates Handover Request and Handover Request Ack with
5890 * the other BSS and comes back with a BSSMAP Handover Command
5891 * containing an RR Handover Command coming from the target BSS... */
5892
5893 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5894 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5895 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5896 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5897 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5898
5899 /* expect the Handover Command to go out on RR */
5900 var RSL_Message rsl_ho_cmd
5901 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5902 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5903 var RSL_IE_Body rsl_ho_cmd_l3;
5904 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5905 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5906 setverdict(fail);
5907 } else {
5908 log("Found L3 Info: ", rsl_ho_cmd_l3);
5909 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5910 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5911 setverdict(fail);
5912 } else {
5913 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5914 setverdict(pass);
5915 }
5916 }
5917
5918 /* When the other BSS has reported a completed handover, this side is
5919 * torn down. */
5920
5921 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5922 var BssmapCause cause := enum2int(cause_val);
5923 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5924
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005925 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005926
5927 interleave {
5928 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5929 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5930 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005931 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5932 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5933 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005934 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005935 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005936}
5937
5938private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5939 g_pars := f_gen_test_hdlr_pars();
5940 var PDU_BSSAP ass_req := f_gen_ass_req();
5941 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5942 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5943 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5944 f_establish_fully(ass_req, exp_compl);
5945
5946 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005947}
5948testcase TC_ho_out_of_this_bsc() runs on test_CT {
5949 var MSC_ConnHdlr vc_conn;
5950
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005951 f_init_vty();
5952 f_bts_0_cfg(BSCVTY,
5953 {"neighbor-list mode automatic",
5954 "handover 1",
5955 "handover algorithm 2",
5956 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005957 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005958 "neighbor lac 99 arfcn 123 bsic any"});
5959 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5960
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005961 f_init(1, true);
5962 f_sleep(1.0);
5963
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005964 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005965
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005966 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5967 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005968
5969 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5970 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5971 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5972 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5973 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5974 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5975 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005976 f_shutdown_helper(ho := true);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005977}
5978
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005979private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5980 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005981 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005982 octetstring l3 := '0123456789'O)
5983runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005984 /* The old lchan and conn should still be active. See that arbitrary L3
5985 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005986 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005987 var template PDU_BSSAP exp_data := {
5988 discriminator := '1'B,
5989 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005990 dlci := dlci,
5991 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005992 pdu := {
5993 dtap := l3
5994 }
5995 };
5996 BSSAP.receive(exp_data);
5997 setverdict(pass);
5998}
5999
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006000private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6001 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006002 template (value) OCT1 dlci := '00'O,
6003 octetstring l3 := '0123456789'O)
6004runs on MSC_ConnHdlr {
6005 BSSAP.send(PDU_BSSAP:{
6006 discriminator := '1'B,
6007 spare := '0000000'B,
6008 dlci := dlci,
6009 lengthIndicator := lengthof(l3),
6010 pdu := {
6011 dtap := l3
6012 }
6013 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006014 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006015 setverdict(pass);
6016}
6017
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006018/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
6019 * simply never sends a BSSMAP Handover Command. */
6020private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006021 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006022
6023 var PDU_BSSAP ass_req := f_gen_ass_req();
6024 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6025 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6026 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6027 f_establish_fully(ass_req, exp_compl);
6028
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006029 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006030 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6031
6032 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6033
6034 /* osmo-bsc should time out 10 seconds after the handover started.
6035 * Let's give it a bit extra. */
6036 f_sleep(15.0);
6037
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006038 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006039 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006040 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006041}
6042testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
6043 var MSC_ConnHdlr vc_conn;
6044
6045 f_init(1, true);
6046 f_sleep(1.0);
6047
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006048 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006049
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006050 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
6051 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006052
6053 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6054 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6055 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6056 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6057 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6058 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6059 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006060 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006061}
6062
6063/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
6064 * RR Handover Failure. */
6065private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006066 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006067
6068 var PDU_BSSAP ass_req := f_gen_ass_req();
6069 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6070 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6071 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6072 f_establish_fully(ass_req, exp_compl);
6073
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006074 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006075 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6076
6077 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6078
6079 f_sleep(0.5);
6080 /* The MSC negotiates Handover Request and Handover Request Ack with
6081 * the other BSS and comes back with a BSSMAP Handover Command
6082 * containing an RR Handover Command coming from the target BSS... */
6083
6084 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6085 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6086 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6087 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6088 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6089
6090 /* expect the Handover Command to go out on RR */
6091 var RSL_Message rsl_ho_cmd
6092 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6093 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6094 var RSL_IE_Body rsl_ho_cmd_l3;
6095 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6096 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6097 setverdict(fail);
6098 } else {
6099 log("Found L3 Info: ", rsl_ho_cmd_l3);
6100 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6101 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6102 setverdict(fail);
6103 } else {
6104 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6105 setverdict(pass);
6106 }
6107 }
6108
6109 f_sleep(0.2);
6110 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6111
6112 /* Should tell the MSC about the failure */
6113 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6114
6115 f_sleep(1.0);
6116
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006117 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006118 f_sleep(1.0);
6119
6120 setverdict(pass);
6121 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006122 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006123}
6124testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
6125 var MSC_ConnHdlr vc_conn;
6126
6127 f_init(1, true);
6128 f_sleep(1.0);
6129
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006130 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006131
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006132 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
6133 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006134
6135 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6136 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6137 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6138 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6139 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6140 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
6141 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006142 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006143}
6144
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006145/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
6146 * (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 +02006147 * and the lchan is released. */
6148private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006149 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006150
6151 var PDU_BSSAP ass_req := f_gen_ass_req();
6152 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6153 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6154 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6155 f_establish_fully(ass_req, exp_compl);
6156
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006157 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006158 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6159
6160 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6161
6162 f_sleep(0.5);
6163 /* The MSC negotiates Handover Request and Handover Request Ack with
6164 * the other BSS and comes back with a BSSMAP Handover Command
6165 * containing an RR Handover Command coming from the target BSS... */
6166
6167 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6168 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6169 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6170 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6171 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6172
6173 /* expect the Handover Command to go out on RR */
6174 var RSL_Message rsl_ho_cmd
6175 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6176 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6177 var RSL_IE_Body rsl_ho_cmd_l3;
6178 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6179 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6180 setverdict(fail);
6181 } else {
6182 log("Found L3 Info: ", rsl_ho_cmd_l3);
6183 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6184 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6185 setverdict(fail);
6186 } else {
6187 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6188 setverdict(pass);
6189 }
6190 }
6191
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006192 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6193 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6194 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006195
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006196 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006197 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6198 log("Got BSSMAP Clear Request");
6199 /* Instruct BSC to clear channel */
6200 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6201 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6202
6203 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006204 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006205 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6206 log("Got Deact SACCH");
6207 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006208 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006209 log("Got RR Release");
6210 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006211 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006212 log("Got RF Chan Rel");
6213 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006214 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006215 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006216 }
6217
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006218 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006219 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006220 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006221
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006222 setverdict(pass);
6223 f_sleep(1.0);
6224}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006225testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006226 var MSC_ConnHdlr vc_conn;
6227
6228 f_init(1, true);
6229 f_sleep(1.0);
6230
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006231 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006232
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006233 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006234 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006235
6236 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6237 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6238 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6239 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6240 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6241 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6242 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006243 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006244}
6245
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006246private 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 +01006247 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006248 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6249 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6250 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6251 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6252 * before we get started. */
6253 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6254 f_rslem_register(0, new_chan_nr);
6255 g_chan_nr := new_chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06006256 var uint3_t expect_target_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006257 f_sleep(1.0);
6258
6259 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6260 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006261 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006262
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006263 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6264 cell_id_source := g_pars.cell_id_source,
6265 oldToNewBSSIEs := oldToNewBSSIEs,
6266 enc := g_pars.encr);
6267 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6268 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6269 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6270 } else {
6271 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6272 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6273 BSSAP.send(ho_req);
6274 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006275
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006276 alt {
6277 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6278 if (g_pars.expect_ho_fail) {
6279 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6280 "Expected Handover Request to fail, but got Handover Request Ack")
6281 }
6282 }
6283 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6284 if (not g_pars.expect_ho_fail) {
6285 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6286 "Expected Handover Request to succeed, but got Handover Failure")
6287 }
6288 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6289 // For now just accept any cause.
6290 BSSAP.receive(tr_BSSMAP_ClearRequest);
6291 setverdict(pass);
6292 return;
6293 }
6294 }
6295
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006296 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6297
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006298 /* we're sure that the channel activation is done now, verify the parameters in it */
6299 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6300 f_verify_encr_info(chan_act);
6301 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006302
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006303 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6304 if (not g_pars.aoip) {
6305 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6306 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6307 }
6308 /* TODO: check actual codecs? */
6309 } else {
6310 if (g_pars.aoip) {
6311 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6312 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6313 }
6314 }
6315
6316 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6317 if (not g_pars.aoip) {
6318 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6319 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6320 }
6321 /* TODO: check actual codec? */
6322 } else {
6323 if (g_pars.aoip) {
6324 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6325 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6326 }
6327 }
6328
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006329 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006330 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6331 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6332 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6333 log("L3 Info in HO Request Ack is ", ho_command);
6334
6335 var GsmArfcn arfcn;
6336 var RslChannelNr actual_new_chan_nr;
6337 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6338 actual_new_chan_nr, arfcn);
6339
6340 if (actual_new_chan_nr != new_chan_nr) {
6341 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6342 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6343 setverdict(fail);
6344 return;
6345 }
6346 log("Handover Command chan_nr is", actual_new_chan_nr);
6347
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006348 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6349 if (not match(got_tsc, expect_target_tsc)) {
6350 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6351 expect_target_tsc, " got ", got_tsc);
6352 mtc.stop;
6353 } else {
6354 log("handoverCommand: verified TSC = ", got_tsc);
6355 }
6356
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006357 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6358 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6359 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6360 var template (present) CipherModeSetting_TV tr_cms := {
6361 sC := '0'B, /* no ciphering by default */
6362 algorithmIdentifier := '000'B,
6363 elementIdentifier := ?
6364 };
6365 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6366 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6367 tr_cms.sC := '1'B;
6368 }
6369 if (not match(cms, tr_cms)) {
6370 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6371 cms, ", expected: ", tr_cms);
6372 }
6373 } else {
6374 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6375 }
6376
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006377 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6378 * tells the MS to handover to the new lchan. Here comes the new MS on
6379 * the new lchan with a Handover RACH: */
6380
6381 /* send handover detect */
6382
6383 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6384
6385 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6386
6387 /* send handover complete over the new channel */
6388
6389 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6390 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6391 enc_PDU_ML3_MS_NW(l3_tx)));
6392
6393 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006394 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006395 setverdict(pass);
6396}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006397
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006398private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006399 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006400 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6401 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6402 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006403 }
6404 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006405 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006406 } else {
6407 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006408 }
6409 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006410 if (g_pars.expect_ho_fail) {
6411 f_perform_clear_no_lchan();
6412 } else {
6413 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6414 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006415 setverdict(pass);
6416}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006417function 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 +01006418 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006419
6420 f_init(1, true);
6421 f_sleep(1.0);
6422
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006423 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006424 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006425
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006426 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6427 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006428
6429 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6430 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006431
6432 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006433 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006434 if (pars.expect_ho_fail) {
6435 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6436 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6437 } else {
6438 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6439 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6440 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006441 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006442
6443 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006444}
6445
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006446testcase TC_ho_into_this_bsc() runs on test_CT {
6447 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6448 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006449 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006450}
6451
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006452function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6453 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006454 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006455 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006456 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006457 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Oliver Smith39f53072022-10-27 14:44:04 +02006458 f_shutdown_helper(ho := true);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006459}
6460
6461testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006462 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006463}
6464
6465testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006466 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006467}
6468
6469testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006470 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006471}
6472
6473testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006474 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006475}
6476
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006477/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6478 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6479 *
6480 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6481 * omitted.
6482 *
6483 * Related: SYS#5839
6484 */
6485testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6486 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6487}
6488
6489testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6490 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6491}
6492
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006493/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6494testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6495 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6496 expect_fail := true); // 0x18 = A5/3 and A5/4
6497}
6498
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006499testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6500 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6501 pars.host_aoip_tla := "::6";
6502 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006503 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006504}
6505
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006506/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006507 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006508 channel is later released (RR CHannel Release), should trigger inclusion of
6509 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6510 neighbors. */
6511testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6512 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6513 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006514 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006515 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006516
6517 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6518 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6519 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006520 f_shutdown_helper(ho := true);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006521}
6522
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006523/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6524testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6525 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6526 pars.encr := f_encr_params('08'O); /* only A5/3 */
6527 pars.last_used_eutran_plmn := '323454'O;
6528 pars.exp_fast_return := true;
6529 f_tc_ho_into_this_bsc_main(pars);
6530
6531 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6532 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6533 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006534 f_shutdown_helper(ho := true);
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006535}
6536
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006537/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6538 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6539 list when the channel is released. */
6540testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6541 f_init_vty();
6542 f_vty_allow_srvcc_fast_return(true, 0)
6543
6544 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6545 pars.last_used_eutran_plmn := '323454'O;
6546 pars.exp_fast_return := false;
6547 f_tc_ho_into_this_bsc_main(pars);
6548 f_vty_allow_srvcc_fast_return(false, 0);
6549 f_shutdown_helper();
6550}
6551
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006552/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6553testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6554 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6555 pars.last_used_eutran_plmn := '323454'O;
6556 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6557 f_tc_ho_into_this_bsc_main(pars);
6558
6559 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6560 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6561 f_ctrs_bsc_and_bts_verify();
6562 f_shutdown_helper();
6563}
6564
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006565private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6566 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6567 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6568 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6569 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6570 setverdict(pass);
6571}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006572
6573private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6574 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006575 var MSC_ConnHdlr vc_conn;
6576 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6577
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006578 f_init_vty();
6579 f_bts_0_cfg(BSCVTY,
6580 {"neighbor-list mode automatic",
6581 "handover 1",
6582 "handover algorithm 2",
6583 "handover2 window rxlev averaging 1",
6584 "no neighbors",
6585 "neighbor lac 99 arfcn 123 bsic any"});
6586 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6587
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006588 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006589 if (disable_fast_return) {
6590 f_vty_allow_srvcc_fast_return(true, 0);
6591 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006592 f_sleep(1.0);
6593
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006594 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006595
6596 pars.last_used_eutran_plmn := '323454'O;
6597 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6598 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6599
6600 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6601 vc_conn.done;
6602
6603 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6604 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6605 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6606 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6607 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6608 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006609
6610 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6611 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006612 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006613
6614 if (disable_fast_return) {
6615 f_vty_allow_srvcc_fast_return(false, 0);
6616 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006617 f_shutdown_helper();
6618}
6619
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006620/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6621 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6622 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6623 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6624testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6625 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6626}
6627/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6628 * independently of fast-reture allowed/forbidden in local BTS */
6629testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6630 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6631}
6632
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006633private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6634 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6635 f_rslem_register(0, new_chan_nr);
6636 g_chan_nr := new_chan_nr;
6637 f_sleep(1.0);
6638
6639 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6640 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6641 activate(as_Media());
6642
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006643 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006644 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006645 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006646
6647 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6648
6649 var PDU_BSSAP rx_bssap;
6650 var octetstring ho_command_str;
6651
6652 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6653
6654 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6655 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6656 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6657 log("L3 Info in HO Request Ack is ", ho_command);
6658
6659 var GsmArfcn arfcn;
6660 var RslChannelNr actual_new_chan_nr;
6661 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6662 actual_new_chan_nr, arfcn);
6663
6664 if (actual_new_chan_nr != new_chan_nr) {
6665 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6666 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6667 setverdict(fail);
6668 return;
6669 }
6670 log("Handover Command chan_nr is", actual_new_chan_nr);
6671
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006672 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6673 f_sleep(1.0);
6674
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006675 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6676 * tells the MS to handover to the new lchan. In this case, the MS
6677 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6678 * Handover Failure to the MSC. The procedure according to 3GPP TS
6679 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6680 * BSSMAP Clear Command: */
6681
6682 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6683 var BssmapCause cause := enum2int(cause_val);
6684 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6685
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006686 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006687 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006688 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006689
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006690 setverdict(pass);
6691 f_sleep(1.0);
6692
6693 setverdict(pass);
6694}
6695testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6696 var MSC_ConnHdlr vc_conn;
6697 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6698
6699 f_init(1, true);
6700 f_sleep(1.0);
6701
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006702 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006703
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006704 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6705 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006706
6707 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6708 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006709
6710 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6711 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6712 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6713 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6714 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006715 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006716}
6717
6718private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6719 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6720 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6721 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6722 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6723 * before we get started. */
6724 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6725 f_rslem_register(0, new_chan_nr);
6726 g_chan_nr := new_chan_nr;
6727 f_sleep(1.0);
6728
6729 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6730 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6731 activate(as_Media());
6732
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006733 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006734 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006735 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006736
6737 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6738
6739 var PDU_BSSAP rx_bssap;
6740 var octetstring ho_command_str;
6741
6742 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6743
6744 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6745 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6746 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6747 log("L3 Info in HO Request Ack is ", ho_command);
6748
6749 var GsmArfcn arfcn;
6750 var RslChannelNr actual_new_chan_nr;
6751 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6752 actual_new_chan_nr, arfcn);
6753
6754 if (actual_new_chan_nr != new_chan_nr) {
6755 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6756 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6757 setverdict(fail);
6758 return;
6759 }
6760 log("Handover Command chan_nr is", actual_new_chan_nr);
6761
6762 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6763 * tells the MS to handover to the new lchan. Here comes the new MS on
6764 * the new lchan with a Handover RACH: */
6765
6766 /* send handover detect */
6767
6768 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6769
6770 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6771
6772 /* The MSC chooses to clear the connection now, maybe we got the
6773 * Handover RACH on the new cell but the MS still signaled Handover
6774 * Failure to the old BSS? */
6775
6776 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6777 var BssmapCause cause := enum2int(cause_val);
6778 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6779
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006780 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006781 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006782 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006783
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006784 f_sleep(1.0);
6785}
6786testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6787 var MSC_ConnHdlr vc_conn;
6788 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6789
6790 f_init(1, true);
6791 f_sleep(1.0);
6792
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006793 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006794
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006795 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6796 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006797
6798 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6799 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006800
6801 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6802 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6803 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6804 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6805 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006806 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006807}
6808
6809/* The new BSS's lchan times out before the MSC decides that handover failed. */
6810private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6811 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6812 f_rslem_register(0, new_chan_nr);
6813 g_chan_nr := new_chan_nr;
6814 f_sleep(1.0);
6815
6816 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6817 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006818 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006819
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006820 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006821 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006822 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006823
6824 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6825
6826 var PDU_BSSAP rx_bssap;
6827 var octetstring ho_command_str;
6828
6829 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6830
6831 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6832 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6833 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6834 log("L3 Info in HO Request Ack is ", ho_command);
6835
6836 var GsmArfcn arfcn;
6837 var RslChannelNr actual_new_chan_nr;
6838 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6839 actual_new_chan_nr, arfcn);
6840
6841 if (actual_new_chan_nr != new_chan_nr) {
6842 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6843 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6844 setverdict(fail);
6845 return;
6846 }
6847 log("Handover Command chan_nr is", actual_new_chan_nr);
6848
6849 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6850 * tells the MS to handover to the new lchan. But the MS never shows up
6851 * on the new lchan. */
6852
6853 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6854
6855 /* Did osmo-bsc also send a Clear Request? */
6856 timer T := 0.5;
6857 T.start;
6858 alt {
6859 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6860 [] T.timeout { }
6861 }
6862
6863 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6864 * asked for it, this is a Handover Failure after all). */
6865
6866 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6867 var BssmapCause cause := enum2int(cause_val);
6868 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6869
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006870 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006871 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006872 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006873
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006874 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006875}
6876testcase TC_ho_in_fail_no_detect() runs on test_CT {
6877 var MSC_ConnHdlr vc_conn;
6878 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6879
6880 f_init(1, true);
6881 f_sleep(1.0);
6882
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006883 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006884
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006885 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6886 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006887
6888 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6889 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006890
6891 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6892 f_ctrs_bsc_and_bts_add(0, "handover:error");
6893 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6894 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6895 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006896 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006897}
6898
6899/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6900private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6901 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6902 f_rslem_register(0, new_chan_nr);
6903 g_chan_nr := new_chan_nr;
6904 f_sleep(1.0);
6905
6906 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6907 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006908 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006909
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006910 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006911 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006912 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006913
6914 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6915
6916 var PDU_BSSAP rx_bssap;
6917 var octetstring ho_command_str;
6918
6919 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6920
6921 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6922 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6923 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6924 log("L3 Info in HO Request Ack is ", ho_command);
6925
6926 var GsmArfcn arfcn;
6927 var RslChannelNr actual_new_chan_nr;
6928 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6929 actual_new_chan_nr, arfcn);
6930
6931 if (actual_new_chan_nr != new_chan_nr) {
6932 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6933 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6934 setverdict(fail);
6935 return;
6936 }
6937 log("Handover Command chan_nr is", actual_new_chan_nr);
6938
6939 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6940 * tells the MS to handover to the new lchan. But the MS never shows up
6941 * on the new lchan. */
6942
6943 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6944
6945 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006946 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006947
6948 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006949 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6950 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6951 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006952 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006953 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006954 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006955
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006956 f_sleep(1.0);
6957}
6958testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6959 var MSC_ConnHdlr vc_conn;
6960 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6961
6962 f_init(1, true);
6963 f_sleep(1.0);
6964
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006965 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006966
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006967 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6968 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006969
6970 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6971 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006972
6973 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6974 f_ctrs_bsc_and_bts_add(0, "handover:error");
6975 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6976 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6977 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006978 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006979}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006980
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006981/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6982 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6983 * empty N-Connect case. */
6984testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6985 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6986 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6987 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006988 f_shutdown_helper(ho := true);
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006989}
6990
Neels Hofmeyr91401012019-07-11 00:42:35 +02006991type record of charstring Commands;
6992
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006993private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006994{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006995 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006996 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006997 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006998 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006999 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02007000}
7001
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01007002private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
7003{
7004 f_vty_enter_cfg_cs7_inst(pt, 0);
7005 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
7006 f_vty_transceive(pt, cmds[i]);
7007 }
7008 f_vty_transceive(pt, "end");
7009}
7010
Neels Hofmeyr91401012019-07-11 00:42:35 +02007011private function f_probe_for_handover(charstring log_label,
7012 charstring log_descr,
7013 charstring handover_vty_cmd,
7014 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007015 boolean is_inter_bsc_handover := false,
7016 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02007017runs on MSC_ConnHdlr
7018{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02007019 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
7020 * lchans to be established on bts 1 or bts 2. */
7021 f_rslem_suspend(RSL1_PROC);
7022 f_rslem_suspend(RSL2_PROC);
7023
Neels Hofmeyr91401012019-07-11 00:42:35 +02007024 var RSL_Message rsl;
7025
7026 var charstring log_msg := " (expecting handover)"
7027 if (not expect_handover) {
7028 log_msg := " (expecting NO handover)";
7029 }
7030 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
7031 f_vty_transceive(BSCVTY, handover_vty_cmd);
7032
Neels Hofmeyr91401012019-07-11 00:42:35 +02007033 timer T := 2.0;
7034 T.start;
7035
7036 alt {
7037 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
7038 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
7039 log("Rx L3 from net: ", l3);
7040 if (ischosen(l3.msgs.rrm.handoverCommand)) {
7041 var RslChannelNr new_chan_nr;
7042 var GsmArfcn arfcn;
7043 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
7044 new_chan_nr, arfcn);
7045 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
7046 log(l3.msgs.rrm.handoverCommand);
7047
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007048 /* Verify correct TSC in handoverCommand */
7049 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
7050 if (not match(got_tsc, expect_target_tsc)) {
7051 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
7052 expect_target_tsc, " got ", got_tsc);
7053 mtc.stop;
7054 } else {
7055 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
7056 expect_target_tsc, ")");
7057 }
7058
Neels Hofmeyr91401012019-07-11 00:42:35 +02007059 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
7060 * matter on which BTS it really is, we're not going to follow through an entire handover
7061 * anyway. */
7062 f_rslem_register(0, new_chan_nr, RSL1_PROC);
7063 f_rslem_resume(RSL1_PROC);
7064 f_rslem_register(0, new_chan_nr, RSL2_PROC);
7065 f_rslem_resume(RSL2_PROC);
7066
7067 if (expect_handover and not is_inter_bsc_handover) {
7068 setverdict(pass);
7069 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
7070 } else {
7071 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
7072 & log_label & ": " & log_descr);
7073 }
7074
7075 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
7076 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
7077 * Handover Failure. */
7078 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
7079
7080 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
7081 f_sleep(0.5);
7082 RSL1.clear;
7083 RSL2.clear;
7084 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
7085 break;
7086 } else {
7087 repeat;
7088 }
7089 }
7090 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
7091 if (expect_handover and is_inter_bsc_handover) {
7092 setverdict(pass);
7093 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
7094 } else {
7095 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
7096 & log_label & ": " & log_descr);
7097 }
7098
7099 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
7100
7101 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
7102 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
7103 * setting a short timeout and waiting is the only way. */
7104 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
7105 f_sleep(1.5);
7106 log("f_probe_for_handover(" & log_label & "): ...done");
7107
7108 break;
7109 }
7110 [] T.timeout {
7111 if (expect_handover) {
7112 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
7113 & log_label & ": " & log_descr);
7114 } else {
7115 setverdict(pass);
7116 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
7117 }
7118 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
7119 break;
7120 }
7121 }
7122
7123 f_rslem_resume(RSL1_PROC);
7124 f_rslem_resume(RSL2_PROC);
7125 f_sleep(3.0);
7126 RSL.clear;
7127
7128 log("f_probe_for_handover(" & log_label & "): done clearing");
7129}
7130
7131/* Test the effect of various neighbor configuration scenarios:
7132 *
7133 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
7134 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
7135 */
7136private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
7137 g_pars := f_gen_test_hdlr_pars();
7138 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
7139 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007140
7141 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
7142 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
7143
7144 /* Establish lchan at bts 0 */
7145 f_establish_fully(ass_cmd, exp_compl);
7146
7147 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
7148 f_vty_enter_cfg_network(BSCVTY);
7149 f_vty_transceive(BSCVTY, "timer T7 1");
7150 f_vty_transceive(BSCVTY, "end");
7151}
7152
7153private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
7154 f_tc_ho_neighbor_config_start();
7155
7156 /*
7157 * bts 0 ARFCN 871 BSIC 10
7158 * bts 1 ARFCN 871 BSIC 11
7159 * bts 2 ARFCN 871 BSIC 12
7160 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7161 */
7162
7163 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007164 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007165 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
7166 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007167 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007168
7169 f_probe_for_handover("1.b", "HO to unknown cell does not start",
7170 "handover any to arfcn 13 bsic 39",
7171 false);
7172
7173 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
7174 "handover any to arfcn 871 bsic 12",
7175 false);
7176
7177 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
7178 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007179 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007180
7181 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007182}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007183testcase TC_ho_neighbor_config_1() runs on test_CT {
7184 var MSC_ConnHdlr vc_conn;
7185 f_init(3, true, guard_timeout := 60.0);
7186 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007187 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007188 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7189 vc_conn.done;
7190
7191 /* f_tc_ho_neighbor_config_start() */
7192 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7193 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7194
7195 /* 1.a */
7196 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7197 * handover quickly by sending a Handover Failure message. */
7198 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7199 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7200 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7201 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007202 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7203 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007204
7205 /* 1.b */
7206 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7207 f_ctrs_bsc_and_bts_add(0, "handover:error");
7208
7209 /* 1.c */
7210 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7211 f_ctrs_bsc_and_bts_add(0, "handover:error");
7212
7213 /* 1.d */
7214 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7215 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7216 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7217 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007218 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7219 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007220
7221 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007222 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007223}
7224
Neels Hofmeyr91401012019-07-11 00:42:35 +02007225private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7226 f_tc_ho_neighbor_config_start();
7227
7228 /*
7229 * bts 0 ARFCN 871 BSIC 10
7230 * bts 1 ARFCN 871 BSIC 11
7231 * bts 2 ARFCN 871 BSIC 12
7232 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7233 */
7234
7235 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007236 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007237 f_sleep(0.5);
7238
7239 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7240 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007241 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007242
7243 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7244 "handover any to arfcn 871 bsic 12",
7245 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007246 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007247}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007248testcase TC_ho_neighbor_config_2() runs on test_CT {
7249 var MSC_ConnHdlr vc_conn;
7250 f_init(3, true, guard_timeout := 50.0);
7251 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007252 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007253 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7254 vc_conn.done;
7255
7256 /* f_tc_ho_neighbor_config_start() */
7257 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7258 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7259
7260 /* 2.a */
7261 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7262 * handover quickly by sending a Handover Failure message. */
7263 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7264 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7265 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7266 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007267 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7268 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007269
7270 /* 2.b */
7271 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7272 f_ctrs_bsc_and_bts_add(0, "handover:error");
7273
7274 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007275 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007276}
7277
Neels Hofmeyr91401012019-07-11 00:42:35 +02007278private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7279 f_tc_ho_neighbor_config_start();
7280
7281 /*
7282 * bts 0 ARFCN 871 BSIC 10
7283 * bts 1 ARFCN 871 BSIC 11
7284 * bts 2 ARFCN 871 BSIC 12
7285 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7286 */
7287
7288 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007289 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007290 f_sleep(0.5);
7291
7292 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7293 "handover any to arfcn 871 bsic 11",
7294 false);
7295 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",
7296 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007297 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007298 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007299}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007300testcase TC_ho_neighbor_config_3() runs on test_CT {
7301 var MSC_ConnHdlr vc_conn;
7302 f_init(3, true, guard_timeout := 50.0);
7303 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007304 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007305 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7306 vc_conn.done;
7307
7308 /* f_tc_ho_neighbor_config_start() */
7309 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7310 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7311
7312 /* 3.a */
7313 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7314 f_ctrs_bsc_and_bts_add(0, "handover:error");
7315
7316 /* 3.b */
7317 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7318 * handover quickly by sending a Handover Failure message. */
7319 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7320 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7321 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7322 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007323 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7324 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007325
7326 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007327 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007328}
7329
Neels Hofmeyr91401012019-07-11 00:42:35 +02007330private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7331 f_tc_ho_neighbor_config_start();
7332
7333 /*
7334 * bts 0 ARFCN 871 BSIC 10
7335 * bts 1 ARFCN 871 BSIC 11
7336 * bts 2 ARFCN 871 BSIC 12
7337 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7338 */
7339
7340 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007341 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007342 f_sleep(0.5);
7343
7344 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7345 "handover any to arfcn 871 bsic 11",
7346 false);
7347 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7348 "handover any to arfcn 871 bsic 12",
7349 false);
7350 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7351 "handover any to arfcn 123 bsic 45",
7352 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007353 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007354}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007355testcase TC_ho_neighbor_config_4() runs on test_CT {
7356 var MSC_ConnHdlr vc_conn;
7357 f_init(3, true, guard_timeout := 50.0);
7358 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007359 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007360 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7361 vc_conn.done;
7362
7363 /* f_tc_ho_neighbor_config_start() */
7364 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7365 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7366
7367 /* 4.a */
7368 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7369 f_ctrs_bsc_and_bts_add(0, "handover:error");
7370
7371 /* 4.b */
7372 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7373 f_ctrs_bsc_and_bts_add(0, "handover:error");
7374
7375 /* 4.c */
7376 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7377 * handover quickly by timing out after the Handover Required message */
7378 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7379 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7380 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7381 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7382
7383 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007384 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007385}
7386
Neels Hofmeyr91401012019-07-11 00:42:35 +02007387private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7388 f_tc_ho_neighbor_config_start();
7389
7390 /*
7391 * bts 0 ARFCN 871 BSIC 10
7392 * bts 1 ARFCN 871 BSIC 11
7393 * bts 2 ARFCN 871 BSIC 12
7394 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7395 */
7396
7397 log("f_tc_ho_neighbor_config: 5. explicit remote neighbor re-using ARFCN+BSIC: 'neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007398 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007399 f_sleep(0.5);
7400
7401 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7402 "handover any to arfcn 871 bsic 12",
7403 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007404 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007405}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007406testcase TC_ho_neighbor_config_5() runs on test_CT {
7407 var MSC_ConnHdlr vc_conn;
7408 f_init(3, true);
7409 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007410 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007411 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7412 vc_conn.done;
7413
7414 /* f_tc_ho_neighbor_config_start() */
7415 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7416 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7417
7418 /* 5 */
7419 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7420 * handover quickly by timing out after the Handover Required message */
7421 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7422 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7423 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7424 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7425
7426 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007427 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007428}
7429
Neels Hofmeyr91401012019-07-11 00:42:35 +02007430private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7431 f_tc_ho_neighbor_config_start();
7432
7433 /*
7434 * bts 0 ARFCN 871 BSIC 10
7435 * bts 1 ARFCN 871 BSIC 11
7436 * bts 2 ARFCN 871 BSIC 12
7437 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7438 */
7439
7440 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7441 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007442 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007443 f_sleep(0.5);
7444
7445 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7446 "handover any to arfcn 871 bsic 12",
7447 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007448 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007449}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007450testcase TC_ho_neighbor_config_6() runs on test_CT {
7451 var MSC_ConnHdlr vc_conn;
7452 f_init(3, true);
7453 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007454 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007455 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7456 vc_conn.done;
7457
7458 /* f_tc_ho_neighbor_config_start() */
7459 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7460 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7461
7462 /* 6.a */
7463 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7464 * handover quickly by timing out after the Handover Required message */
7465 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7466 f_ctrs_bsc_and_bts_add(0, "handover:error");
7467
7468 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007469 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007470}
7471
Neels Hofmeyr91401012019-07-11 00:42:35 +02007472private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7473 f_tc_ho_neighbor_config_start();
7474
7475 /*
7476 * bts 0 ARFCN 871 BSIC 10
7477 * bts 1 ARFCN 871 BSIC 11
7478 * bts 2 ARFCN 871 BSIC 12
7479 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7480 */
7481
7482 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7483 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007484 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007485 f_sleep(0.5);
7486
7487 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7488 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007489 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007490 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7491 "handover any to arfcn 123 bsic 45",
7492 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007493 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007494}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007495testcase TC_ho_neighbor_config_7() runs on test_CT {
7496 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007497 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007498 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007499 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007500 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7501 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007502
7503 /* f_tc_ho_neighbor_config_start() */
7504 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7505 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7506
7507 /* 7.a */
7508 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7509 * handover quickly by sending a Handover Failure message. */
7510 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7511 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7512 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7513 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007514 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7515 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007516
7517 /* 7.b */
7518 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7519 * handover quickly by timing out after the Handover Required message */
7520 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7521 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7522 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7523 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7524
7525 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007526 f_shutdown_helper(ho := true);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007527}
7528
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007529/* OS#3041: Open and close N connections in a normal fashion, and expect no
7530 * BSSMAP Reset just because of that. */
7531testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7532 var default d;
7533 var integer i;
7534 var DchanTuple dt;
7535
7536 f_init();
7537
7538 /* Wait for initial BSSMAP Reset to pass */
7539 f_sleep(4.0);
7540
7541 d := activate(no_bssmap_reset());
7542
7543 /* Setup up a number of connections and RLSD them again from the MSC
7544 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7545 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007546 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007547 /* Since we're doing a lot of runs, give each one a fresh
7548 * T_guard from the top. */
7549 T_guard.start;
7550
7551 /* Setup a BSSAP connection and clear it right away. This is
7552 * the MSC telling the BSC about a planned release, it's not an
7553 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007554 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007555
7556 /* MSC disconnects (RLSD). */
7557 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7558 }
7559
7560 /* In the buggy behavior, a timeout of 2 seconds happens between above
7561 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7562 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7563 f_sleep(4.0);
7564
7565 deactivate(d);
7566 f_shutdown_helper();
7567}
Harald Welte552620d2017-12-16 23:21:36 +01007568
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007569/* OS#3041: Open and close N connections in a normal fashion, and expect no
7570 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7571 * the MSC. */
7572testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7573 var default d;
7574 var integer i;
7575 var DchanTuple dt;
7576 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007577 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7578 var BssmapCause cause := enum2int(cause_val);
7579
7580 f_init();
7581
7582 /* Wait for initial BSSMAP Reset to pass */
7583 f_sleep(4.0);
7584
7585 d := activate(no_bssmap_reset());
7586
7587 /* Setup up a number of connections and RLSD them again from the MSC
7588 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7589 * Let's do it some more times for good measure. */
7590 for (i := 0; i < 8; i := i+1) {
7591 /* Since we're doing a lot of runs, give each one a fresh
7592 * T_guard from the top. */
7593 T_guard.start;
7594
7595 /* Setup a BSSAP connection and clear it right away. This is
7596 * the MSC telling the BSC about a planned release, it's not an
7597 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007598 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007599
7600 /* Instruct BSC to clear channel */
7601 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7602
7603 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007604 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007605 }
7606
7607 /* In the buggy behavior, a timeout of 2 seconds happens between above
7608 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7609 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7610 f_sleep(4.0);
7611
7612 deactivate(d);
7613 f_shutdown_helper();
7614}
7615
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007616/* OS#3041: Open and close N connections in a normal fashion, and expect no
7617 * BSSMAP Reset just because of that. Close connections from the MS side with a
7618 * Release Ind on RSL. */
7619testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7620 var default d;
7621 var integer i;
7622 var DchanTuple dt;
7623 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007624 var integer j;
7625
7626 f_init();
7627
7628 /* Wait for initial BSSMAP Reset to pass */
7629 f_sleep(4.0);
7630
7631 d := activate(no_bssmap_reset());
7632
7633 /* Setup up a number of connections and RLSD them again from the MSC
7634 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7635 * Let's do it some more times for good measure. */
7636 for (i := 0; i < 8; i := i+1) {
7637 /* Since we're doing a lot of runs, give each one a fresh
7638 * T_guard from the top. */
7639 T_guard.start;
7640
7641 /* Setup a BSSAP connection and clear it right away. This is
7642 * the MSC telling the BSC about a planned release, it's not an
7643 * erratic loss of a connection. */
7644 dt := f_est_dchan('23'O, 23, '00010203040506'O);
7645
7646 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007647 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007648
7649 /* expect Clear Request on MSC side */
7650 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7651
7652 /* Instruct BSC to clear channel */
7653 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7654 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7655
7656 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007657 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007658 }
7659
7660 /* In the buggy behavior, a timeout of 2 seconds happens between above
7661 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7662 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7663 f_sleep(4.0);
7664
7665 deactivate(d);
7666 f_shutdown_helper();
7667}
7668
Harald Welte94e0c342018-04-07 11:33:23 +02007669/***********************************************************************
7670 * IPA style dynamic PDCH
7671 ***********************************************************************/
7672
7673private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7674 template (omit) RSL_Cause nack := omit)
7675runs on test_CT {
7676 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7677 var RSL_Message rsl_unused;
7678 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7679 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7680 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007681 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007682 if (istemplatekind(nack, "omit")) {
7683 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007684 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007685 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007686 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007687 }
7688}
7689
7690private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7691 template (omit) RSL_Cause nack := omit)
7692runs on test_CT {
7693 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7694 var RSL_Message rsl_unused;
7695 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7696 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7697 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007698 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_DEACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007699 if (istemplatekind(nack, "omit")) {
7700 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007701 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007702 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007703 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007704 }
7705}
7706
7707private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7708runs on test_CT return charstring {
7709 var charstring cmd, resp;
7710 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007711 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007712}
7713
7714private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7715 template charstring exp)
7716runs on test_CT {
7717 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7718 if (not match(mode, exp)) {
7719 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007720 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007721 }
7722}
7723
7724private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7725runs on test_CT {
7726 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7727 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7728 f_vty_transceive(BSCVTY, "end");
7729}
7730
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007731
7732private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7733 var integer i;
7734 for (i := 0; i < 8; i := i + 1) {
7735 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7736 }
7737}
7738
Harald Welte94e0c342018-04-07 11:33:23 +02007739private const charstring TCHF_MODE := "TCH/F mode";
7740private const charstring TCHH_MODE := "TCH/H mode";
7741private const charstring PDCH_MODE := "PDCH mode";
7742private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007743private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007744
7745/* Test IPA PDCH activation / deactivation triggered by VTY */
7746testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7747 var RSL_Message rsl_unused;
7748
7749 /* change Timeslot 6 before f_init() starts RSL */
7750 f_init_vty();
7751 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7752 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7753
7754 f_init(1, false);
7755 f_sleep(1.0);
7756
7757 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7758
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007759 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007760 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7761 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007762 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7763 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007764 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007765 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007766 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7767
7768 /* De-activate it via VTY */
7769 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7770 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007771 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007772 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7773
7774 /* re-activate it via VTY */
7775 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7776 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007777 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007778 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7779
7780 /* and finally de-activate it again */
7781 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7782 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007783 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007784 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7785
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007786 /* clean up config */
7787 f_ts_set_chcomb(0, 0, 6, "PDCH");
7788
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007789 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007790}
7791
7792/* Test IPA PDCH activation NACK */
7793testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7794 var RSL_Message rsl_unused;
7795
7796 /* change Timeslot 6 before f_init() starts RSL */
7797 f_init_vty();
7798 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7799 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7800
7801 f_init(1, false);
7802 f_sleep(1.0);
7803
7804 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7805
7806 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7807 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007808 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7809 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007810 f_sleep(1.0);
7811 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7812
7813 /* De-activate it via VTY */
7814 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7815 f_sleep(1.0);
7816 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7817
7818 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7819 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7820 f_sleep(1.0);
7821 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7822
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007823 /* clean up config */
7824 f_ts_set_chcomb(0, 0, 6, "PDCH");
7825
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007826 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007827}
7828
7829
7830/***********************************************************************
7831 * Osmocom style dynamic PDCH
7832 ***********************************************************************/
7833
7834private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7835 template (omit) RSL_Cause nack := omit)
7836runs on test_CT {
7837 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7838 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007839 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007840 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7841 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007842 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT(chan_nr, ?));
Harald Welte94e0c342018-04-07 11:33:23 +02007843 if (istemplatekind(nack, "omit")) {
7844 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007845 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007846 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007847 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007848 }
7849}
7850
7851private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7852 template (omit) RSL_Cause nack := omit)
7853runs on test_CT {
7854 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7855 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007856 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007857 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7858 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007859 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007860 if (istemplatekind(nack, "omit")) {
7861 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007862 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007863 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007864 //f_ipa_tx(ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007865 }
7866}
7867
7868/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7869testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7870 var RSL_Message rsl_unused;
7871
7872 /* change Timeslot 6 before f_init() starts RSL */
7873 f_init_vty();
7874 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7875 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7876
7877 f_init(1, false);
7878 f_sleep(1.0);
7879
7880 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7881
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007882 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007883 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7884 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007885 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007886
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007887 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007888 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007889 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 +02007890 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7891
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007892 /* clean up config */
7893 f_ts_set_chcomb(0, 0, 6, "PDCH");
7894
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007895 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007896}
7897
7898/* Test Osmocom dyn PDCH activation NACK behavior */
7899testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7900 var RSL_Message rsl_unused;
7901
7902 /* change Timeslot 6 before f_init() starts RSL */
7903 f_init_vty();
7904 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7905 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7906
7907 f_init(1, false);
7908 f_sleep(1.0);
7909
7910 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7911
7912 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7913 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007914 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007915
7916 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007917 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte94e0c342018-04-07 11:33:23 +02007918 f_sleep(1.0);
7919 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7920
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007921 /* clean up config */
7922 f_ts_set_chcomb(0, 0, 6, "PDCH");
7923
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007924 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007925}
7926
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007927/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7928testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7929 var RSL_Message rsl_unused, rsl_msg;
7930 var DchanTuple dt;
7931 var BSSAP_N_CONNECT_ind rx_c_ind;
7932
7933 /* change Timeslot 6 before f_init() starts RSL */
7934 f_init_vty();
7935 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7936 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7937
7938 f_init(1, false);
7939 f_sleep(1.0);
7940
7941 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7942
7943 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7944 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7945 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007946 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007947
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007948 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007949 f_sleep(1.0);
7950 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7951 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7952
7953 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7954 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007955 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007956 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007957 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007958 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007959 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007960 }
7961
7962 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007963 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7964 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7965 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007966
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007967 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007968 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007969 dt.idx := {0, 0};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007970
7971 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007972 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7973 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007974 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7975
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007976 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 +02007977 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7978 dt.sccp_conn_id := rx_c_ind.connectionId;
7979 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7980
7981 /* Instruct BSC to clear channel */
7982 var BssmapCause cause := 0;
7983 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007984 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007985
7986 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007987 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
7988 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007989 f_sleep(1.0);
7990 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7991
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007992 /* Clean up SDCCH lchans */
7993 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
7994 f_perform_clear_test_ct(sdcch_cleanup[i]);
7995 }
7996
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007997 /* clean up config */
7998 f_ts_set_chcomb(0, 0, 6, "PDCH");
7999
8000 f_shutdown_helper();
8001}
8002
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008003/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
8004testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
8005 var ASP_RSL_Unitdata rsl_ud;
8006 var integer i;
8007 var integer chreq_total, chreq_nochan;
8008
8009 f_init_vty();
8010 for (i := 1; i < 8; i := i + 1) {
8011 if (i == 2) {
8012 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8013 } else {
8014 f_ts_set_chcomb(0, 0, i, "PDCH");
8015 }
8016 }
8017 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8018
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008019 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008020
8021 /* The dyn TS want to activate PDCH mode, ACK that. */
8022 var RslChannelNr chan_nr;
8023 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008024 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
8025 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008026
8027 f_sleep(1.0);
8028
8029 /* Exhaust all dedicated SDCCH lchans.
8030 /* GSM 44.018 Table 9.1.8.2:
8031 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
8032 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008033 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008034 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008035 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008036 }
8037
8038 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008039 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008040 /* Also occupy the seven other SDCCH of the dyn TS */
8041 for (i := 0; i < 7; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008042 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
8043 }
8044
8045 /* Clean up SDCCH lchans */
8046 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8047 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008048 }
8049
8050 /* clean up config */
8051 f_ts_reset_chcomb(0);
8052
8053 f_shutdown_helper();
8054}
8055
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008056/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
8057 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
8058 it as TCH directly instead. SYS#5309. */
8059testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
8060 var RSL_Message rsl_unused, rsl_msg;
8061 var DchanTuple dt;
8062 var BSSAP_N_CONNECT_ind rx_c_ind;
8063 var integer i;
8064
8065 /* change Timeslot 6 before f_init() starts RSL */
8066 f_init_vty();
8067 for (i := 1; i < 8; i := i + 1) {
8068 if (i == 6) {
8069 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8070 } else {
8071 f_ts_set_chcomb(0, 0, i, "PDCH");
8072 }
8073 }
8074 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8075
8076 f_init(1, false);
8077 f_sleep(1.0);
8078
8079 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8080
8081 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8082 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8083 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008084 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008085
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008086 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008087 f_sleep(1.0);
8088 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8089 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8090
8091 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8092 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008093 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008094 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008095 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008096 dt := f_est_dchan(ra, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008097 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008098 }
8099
8100 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008101 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
8102 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8103 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008104
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008105 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008106 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008107 dt.idx := {0, 0};
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008108
8109 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008110 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8111 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008112 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
8113
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008114 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 +02008115 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8116 dt.sccp_conn_id := rx_c_ind.connectionId;
8117 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8118
8119 /* Instruct BSC to clear channel */
8120 var BssmapCause cause := 0;
8121 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008122 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008123
8124 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008125 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8126 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008127 f_sleep(1.0);
8128 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8129
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008130 /* Clean up SDCCH lchans */
8131 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8132 f_perform_clear_test_ct(chan_cleanup[i]);
8133 }
8134
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008135 /* clean up config */
8136 f_ts_reset_chcomb(0);
8137 /* TODO: clean up other channels? */
8138
8139 f_shutdown_helper();
8140}
8141
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008142/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
8143testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
8144 var RSL_Message rsl_unused, rsl_msg;
8145 var DchanTuple dt;
8146 var BSSAP_N_CONNECT_ind rx_c_ind;
8147 var GsmRrMessage rr;
8148
8149 /* change Timeslot 6 before f_init() starts RSL */
8150 f_init_vty();
8151 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8152 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8153
8154 f_init(1, false);
8155 f_sleep(1.0);
8156
8157 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8158
8159 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8160 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8161 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008162 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008163
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008164 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008165 f_sleep(1.0);
8166 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8167 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8168
8169 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8170 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008171 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008172 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008173 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008174 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008175 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008176 }
8177
8178 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008179 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8180 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8181 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008182
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008183 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008184 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008185 dt.idx := {0, 0};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008186
8187 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008188 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8189 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008190 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8191 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8192 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8193 }
8194
8195 /* FIXME? Currently the TS stays in state BORKEN: */
8196
8197 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008198 /* rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8199 * f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008200 * f_sleep(1.0);
8201 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8202 */
8203
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008204 /* Clean up SDCCH lchans */
8205 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8206 f_perform_clear_test_ct(chan_cleanup[i]);
8207 }
8208
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008209 /* clean up config */
8210 f_ts_set_chcomb(0, 0, 6, "PDCH");
8211
8212 f_shutdown_helper();
8213}
8214
Stefan Sperling0796a822018-10-05 13:01:39 +02008215testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008216 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008217 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8218 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8219 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008220 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008221}
8222
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008223testcase TC_chopped_ipa_payload() runs on test_CT {
8224 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8225 /* TODO: mp_bsc_ctrl_port does not work yet */};
8226 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8227 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8228 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008229 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008230}
8231
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008232/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8233 the BTS does autonomous MS power control loop */
8234testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8235 var MSC_ConnHdlr vc_conn;
8236 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8237 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8238 pars.exp_ms_power_params := true;
8239
8240 f_init(1, true);
8241 f_sleep(1.0);
8242 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8243 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008244 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008245}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008246
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008247/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8248testcase TC_c0_power_red_mode() runs on test_CT {
8249 f_init(1);
8250
8251 for (var integer red := 6; red >= 0; red := red - 2) {
8252 /* Configure BCCH carrier power reduction mode via the VTY */
8253 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8254
8255 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008256 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008257 chan_nr := t_RslChanNr_BCCH(0),
8258 bs_power := tr_RSL_IE_BS_Power(red / 2));
8259 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008260 var RSL_Message unused := f_exp_ipa_rx(tr_rsl_pdu);
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008261
8262 /* Additionally verify the applied value over the CTRL interface */
8263 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8264 if (cred != int2str(red)) {
8265 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8266 cred, " (expected ", red, ")");
8267 }
8268 }
8269
8270 f_shutdown_helper();
8271}
8272
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008273/***********************************************************************
8274 * MSC Pooling
8275 ***********************************************************************/
8276
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008277template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008278 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 +02008279
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008280private 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 +02008281runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008282 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008283 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008284 f_logp(BSCVTY, "Got RSL RR Release");
8285 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008286 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008287 f_logp(BSCVTY, "Got RSL Deact SACCH");
8288 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008289 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008290 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008291 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8292 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008293 break;
8294 }
8295 }
8296}
8297
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008298private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8299 var MgcpCommand mgcp_cmd;
8300 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8301 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8302 repeat;
8303 }
8304}
8305
8306private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8307 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8308 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8309 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8310 repeat;
8311 }
8312}
8313
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008314friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8315 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008316runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008317 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8318 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008319 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008320 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8321 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008322 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008323 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008324 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008325 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008326 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008327 }
8328 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008329 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008330 /* Also drop the SCCP connection */
8331 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8332 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008333 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008334 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008335 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8336 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008337 }
8338 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008339 deactivate(ack_dlcx);
8340 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008341}
8342
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008343friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8344runs on MSC_ConnHdlr {
8345 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8346 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8347 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8348 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8349 interleave {
8350 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8351 f_logp(BSCVTY, "Got RSL Deact SACCH");
8352 }
8353 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8354 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8355 /* Also drop the SCCP connection */
8356 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8357 }
8358 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8359 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8360 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8361 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8362 }
8363 }
8364 deactivate(ack_dlcx);
8365 deactivate(ack_rel_req);
8366}
8367
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008368friend function f_perform_clear_no_lchan()
8369runs on MSC_ConnHdlr {
8370 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8371 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8372 BSSAP.receive(tr_BSSMAP_ClearComplete);
8373 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8374 /* Also drop the SCCP connection */
8375 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8376}
8377
Vadim Yanitskiy65d879d2022-06-23 18:15:39 +07008378friend function f_perform_clear_test_ct(DchanTuple dt)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008379 runs on test_CT
8380{
8381 /* Instruct BSC to clear channel */
8382 var BssmapCause cause := 0;
8383 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008384 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008385}
8386
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008387private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8388 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008389runs on MSC_ConnHdlr {
8390 timer T := 10.0;
8391 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8392
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008393 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008394 f_create_bssmap_exp(l3_enc);
8395
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008396 /* RSL_Emulation.f_chan_est() on rsl_pt:
8397 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008398 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8399 */
8400 var RSL_Message rx_rsl;
8401 var GsmRrMessage rr;
8402
8403 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008404 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008405 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008406 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008407 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8408 */
8409 timer Tt := 10.0;
8410
8411 /* request a channel to be established */
8412 Tt.start;
8413 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008414 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008415 Tt.stop;
8416 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008417 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008418 setverdict(fail, "Unexpected RSL message on DCHAN");
8419 mtc.stop;
8420 }
8421 [] Tt.timeout {
8422 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8423 mtc.stop;
8424 }
8425 }
8426 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8427 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008428 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008429
8430
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008431 if (expect_bssmap_l3) {
8432 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8433 var template PDU_BSSAP exp_l3_compl;
8434 exp_l3_compl := tr_BSSMAP_ComplL3()
8435 if (g_pars.aoip == false) {
8436 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8437 } else {
8438 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8439 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008440
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008441 var PDU_BSSAP bssap;
8442 T.start;
8443 alt {
8444 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8445 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8446 log("rx exp_l3_compl = ", bssap);
8447 }
8448 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8449 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8450 }
8451 [] T.timeout {
8452 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8453 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008454 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008455
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008456 /* start ciphering, if requested */
8457 if (ispresent(g_pars.encr)) {
8458 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008459 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008460 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008461 }
8462
8463 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008464 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008465 }
8466 setverdict(pass);
8467 f_sleep(1.0);
8468}
8469
8470private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8471 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8472 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008473 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008474 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008475 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008476 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008477 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008478 }
8479}
8480
8481/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8482private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8483 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008484 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8485 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8486 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8487 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 +02008488}
8489testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8490
8491 f_init(1, true);
8492 f_sleep(1.0);
8493 var MSC_ConnHdlr vc_conn;
8494 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008495
8496 f_ctrs_msc_init();
8497
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008498 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8499 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008500
8501 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008502 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008503}
8504
8505/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8506/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8507 * just as well using only RSL. */
8508testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8509
8510 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8511 f_sleep(1.0);
8512
8513 /* Control which MSC gets chosen next by the round-robin, otherwise
8514 * would be randomly affected by which other tests ran before this. */
8515 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8516
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008517 f_ctrs_msc_init();
8518
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008519 var MSC_ConnHdlr vc_conn1;
8520 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8521 pars1.mscpool.rsl_idx := 0;
8522 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8523 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8524 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008525 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008526
8527 var MSC_ConnHdlr vc_conn2;
8528 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8529 pars2.mscpool.rsl_idx := 1;
8530 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8531 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8532 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008533 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008534
8535 /* Test round-robin wrap to the first MSC */
8536 var MSC_ConnHdlr vc_conn3;
8537 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8538 pars3.mscpool.rsl_idx := 2;
8539 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8540 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8541 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008542 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008543 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008544}
8545
8546/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8547 * (configured in osmo-bsc.cfg). */
8548/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8549 * just as well using only RSL. */
8550testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8551
8552 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8553 f_sleep(1.0);
8554
8555 /* Control which MSC gets chosen next by the round-robin, otherwise
8556 * would be randomly affected by which other tests ran before this. */
8557 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8558
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008559 f_ctrs_msc_init();
8560
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008561 var MSC_ConnHdlr vc_conn1;
8562 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8563 pars1.mscpool.rsl_idx := 0;
8564 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8565 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8566 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008567 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008568
8569 var MSC_ConnHdlr vc_conn2;
8570 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8571 pars2.mscpool.rsl_idx := 1;
8572 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8573 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8574 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008575 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008576
8577 /* Test round-robin wrap to the first MSC */
8578 var MSC_ConnHdlr vc_conn3;
8579 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8580 pars3.mscpool.rsl_idx := 2;
8581 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8582 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8583 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008584 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008585 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008586}
8587
8588/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8589 * (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
8590 * NULL-NRI setting is stronger than that. */
8591/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8592 * just as well using only RSL. */
8593testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8594
8595 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8596 f_sleep(1.0);
8597
8598 /* Control which MSC gets chosen next by the round-robin, otherwise
8599 * would be randomly affected by which other tests ran before this. */
8600 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8601
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008602 f_ctrs_msc_init();
8603
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008604 var MSC_ConnHdlr vc_conn1;
8605 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8606 pars1.mscpool.rsl_idx := 0;
8607 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8608 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8609 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008610 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008611
8612 var MSC_ConnHdlr vc_conn2;
8613 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8614 pars2.mscpool.rsl_idx := 1;
8615 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8616 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8617 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008618 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008619
8620 /* Test round-robin wrap to the first MSC */
8621 var MSC_ConnHdlr vc_conn3;
8622 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8623 pars3.mscpool.rsl_idx := 2;
8624 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8625 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8626 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008627 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008628 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008629}
8630
8631/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8632 * assigned to any MSC (configured in osmo-bsc.cfg). */
8633/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8634 * just as well using only RSL. */
8635testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8636
8637 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8638 f_sleep(1.0);
8639
8640 /* Control which MSC gets chosen next by the round-robin, otherwise
8641 * would be randomly affected by which other tests ran before this. */
8642 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8643
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008644 f_ctrs_msc_init();
8645
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008646 var MSC_ConnHdlr vc_conn1;
8647 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8648 pars1.mscpool.rsl_idx := 0;
8649 /* An NRI that is not assigned to any MSC */
8650 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8651 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8652 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008653 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008654
8655 var MSC_ConnHdlr vc_conn2;
8656 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8657 pars2.mscpool.rsl_idx := 1;
8658 /* An NRI that is not assigned to any MSC */
8659 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8660 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8661 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008662 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008663
8664 /* Test round-robin wrap to the first MSC */
8665 var MSC_ConnHdlr vc_conn3;
8666 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8667 pars3.mscpool.rsl_idx := 2;
8668 /* An NRI that is not assigned to any MSC */
8669 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8670 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8671 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008672 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008673 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008674}
8675
8676/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8677 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8678/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8679 * just as well using only RSL. */
8680testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8681
8682 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8683 f_sleep(1.0);
8684
8685 /* Control which MSC gets chosen next by the round-robin, otherwise
8686 * would be randomly affected by which other tests ran before this. */
8687 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8688
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008689 f_ctrs_msc_init();
8690
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008691 var MSC_ConnHdlr vc_conn1;
8692 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8693 pars1.mscpool.rsl_idx := 0;
8694 /* An NRI that is assigned to an unconnected MSC */
8695 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8696 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8697 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008698 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8699 f_ctrs_msc_add(0, "mscpool:subscr:new");
8700 f_ctrs_msc_verify();
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 /* An NRI that is assigned to an unconnected MSC */
8706 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8707 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8708 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008709 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8710 f_ctrs_msc_add(1, "mscpool:subscr:new");
8711 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008712
8713 /* Test round-robin wrap to the first MSC */
8714 var MSC_ConnHdlr vc_conn3;
8715 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8716 pars3.mscpool.rsl_idx := 2;
8717 /* An NRI that is assigned to an unconnected MSC */
8718 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8719 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8720 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008721 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8722 f_ctrs_msc_add(0, "mscpool:subscr:new");
8723 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008724 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008725}
8726
8727/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8728 * osmo-bsc.cfg). */
8729/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8730 * just as well using only RSL. */
8731testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8732
8733 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8734 f_sleep(1.0);
8735
8736 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8737 * this is not using round-robin. */
8738 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8739
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008740 f_ctrs_msc_init();
8741
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008742 var MSC_ConnHdlr vc_conn1;
8743 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8744 pars1.mscpool.rsl_idx := 0;
8745 /* An NRI of the second MSC's range (256-511) */
8746 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8747 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8748 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008749 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008750
8751 var MSC_ConnHdlr vc_conn2;
8752 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8753 pars2.mscpool.rsl_idx := 1;
8754 /* An NRI of the second MSC's range (256-511) */
8755 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8756 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8757 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008758 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008759
8760 var MSC_ConnHdlr vc_conn3;
8761 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8762 pars3.mscpool.rsl_idx := 2;
8763 /* An NRI of the second MSC's range (256-511) */
8764 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8765 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8766 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008767 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008768 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008769}
8770
8771/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8772 * while a round-robin remains unaffected by that. */
8773/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8774 * just as well using only RSL. */
8775testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8776
8777 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8778 f_sleep(1.0);
8779
8780 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8781 * this is not using round-robin. */
8782 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8783
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008784 f_ctrs_msc_init();
8785
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008786 var MSC_ConnHdlr vc_conn1;
8787 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8788 pars1.mscpool.rsl_idx := 0;
8789 /* An NRI of the third MSC's range (512-767) */
8790 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8791 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8792 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008793 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008794
8795 var MSC_ConnHdlr vc_conn2;
8796 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8797 pars2.mscpool.rsl_idx := 1;
8798 /* An NRI of the third MSC's range (512-767) */
8799 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8800 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8801 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008802 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008803
8804 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8805 var MSC_ConnHdlr vc_conn3;
8806 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8807 pars3.mscpool.rsl_idx := 2;
8808 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8809 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8810 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008811 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008812 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008813}
8814
8815/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8816/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8817 * just as well using only RSL. */
8818testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8819
8820 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8821 f_sleep(1.0);
8822
8823 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8824 * instead, and hits msc 0. */
8825 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8826
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008827 f_ctrs_msc_init();
8828
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008829 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8830 var MSC_ConnHdlr vc_conn1;
8831 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8832 pars1.mscpool.rsl_idx := 0;
8833 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8834 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8835 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008836 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008837
8838 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8839 var MSC_ConnHdlr vc_conn2;
8840 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8841 pars2.mscpool.rsl_idx := 1;
8842 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8843 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8844 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008845 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008846 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008847}
8848
8849/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8850 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8851private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8852 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8853 //cid_list := { cIl_allInBSS := ''O };
8854 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8855 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8856 var BSSAP_N_UNITDATA_req paging;
8857 var hexstring imsi := '001010000000123'H;
8858
8859 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8860
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008861 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008862 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8863 BSSAP.send(paging);
8864
8865 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8866 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8867 * channel number is picked here. */
8868 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8869 f_rslem_register(0, new_chan_nr);
8870 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8871 f_rslem_unregister(0, new_chan_nr);
8872
8873 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8874 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008875 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008876 f_sleep(1.0);
8877}
8878testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8879 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8880 f_sleep(1.0);
8881
8882 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8883 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8884 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8885
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008886 f_ctrs_msc_init();
8887
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008888 var MSC_ConnHdlr vc_conn1;
8889 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8890 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008891 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8892 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008893 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8894 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008895 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008896 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008897}
8898
8899/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8900 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8901private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8902 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8903 //cid_list := { cIl_allInBSS := ''O };
8904 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8905 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8906 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008907 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008908 var BSSAP_N_UNITDATA_req paging;
8909
8910 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8911
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008912 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008913 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8914 BSSAP.send(paging);
8915
8916 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8917 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8918 * channel number is picked here. */
8919 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8920 f_rslem_register(0, new_chan_nr);
8921 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8922 f_rslem_unregister(0, new_chan_nr);
8923
8924 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8925 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8926 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008927 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(nri_v))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008928 f_sleep(1.0);
8929}
8930testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8931 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8932 f_sleep(1.0);
8933
8934 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8935 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8936 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8937
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008938 f_ctrs_msc_init();
8939
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008940 var MSC_ConnHdlr vc_conn1;
8941 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8942 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008943 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8944 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008945 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8946 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008947 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008948 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008949}
8950
8951/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8952/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8953 * just as well using only RSL. */
8954testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8955
8956 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8957 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008958 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8959 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008960
8961 /* Control which MSC gets chosen next by the round-robin, otherwise
8962 * would be randomly affected by which other tests ran before this. */
8963 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8964
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008965 f_ctrs_msc_init();
8966
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008967 var MSC_ConnHdlr vc_conn1;
8968 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8969 pars1.mscpool.rsl_idx := 0;
8970 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8971 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8972 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008973 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008974
8975 var MSC_ConnHdlr vc_conn2;
8976 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8977 pars2.mscpool.rsl_idx := 1;
8978 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8979 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8980 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008981 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008982
8983 var MSC_ConnHdlr vc_conn3;
8984 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8985 pars3.mscpool.rsl_idx := 2;
8986 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8987 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8988 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008989 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008990 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008991}
8992
8993/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8994 * TMSI NRI. */
8995testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8996
8997 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8998 f_sleep(1.0);
8999
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009000 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9001 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
9002
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009003 /* Control which MSC gets chosen next by the round-robin, otherwise
9004 * would be randomly affected by which other tests ran before this. */
9005 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9006
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009007 f_ctrs_msc_init();
9008
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009009 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
9010 var MSC_ConnHdlr vc_conn1;
9011 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
9012 pars1.mscpool.rsl_idx := 0;
9013 /* An NRI of the second MSC's range (256-511) */
9014 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
9015 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9016 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009017 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009018
9019 var MSC_ConnHdlr vc_conn2;
9020 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
9021 pars2.mscpool.rsl_idx := 1;
9022 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9023 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9024 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009025 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009026
9027 var MSC_ConnHdlr vc_conn3;
9028 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
9029 pars3.mscpool.rsl_idx := 2;
9030 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
9031 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9032 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009033 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009034 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009035}
9036
Philipp Maier783681c2020-07-16 16:47:06 +02009037/* Allow/Deny emergency calls globally via VTY */
9038private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
9039 f_vty_enter_cfg_msc(BSCVTY, 0);
9040 if (allow) {
9041 f_vty_transceive(BSCVTY, "allow-emergency allow");
9042 } else {
9043 f_vty_transceive(BSCVTY, "allow-emergency deny");
9044 }
9045 f_vty_transceive(BSCVTY, "exit");
9046 f_vty_transceive(BSCVTY, "exit");
9047}
9048
9049/* Allow/Deny emergency calls per BTS via VTY */
9050private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
9051 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9052 if (allow) {
9053 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
9054 } else {
9055 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
9056 }
9057 f_vty_transceive(BSCVTY, "exit");
9058 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00009059 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02009060}
9061
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02009062/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
9063private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
9064 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9065 if (allow) {
9066 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
9067 } else {
9068 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
9069 }
9070 f_vty_transceive(BSCVTY, "exit");
9071 f_vty_transceive(BSCVTY, "exit");
9072 f_vty_transceive(BSCVTY, "exit");
9073}
9074
Pau Espin Pedrol14475352021-07-22 15:48:16 +02009075/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
9076private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
9077 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9078 if (allow) {
9079 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
9080 } else {
9081 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
9082 }
9083 f_vty_transceive(BSCVTY, "exit");
9084 f_vty_transceive(BSCVTY, "exit");
9085 f_vty_transceive(BSCVTY, "exit");
9086}
9087
Philipp Maier783681c2020-07-16 16:47:06 +02009088/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
9089private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
9090 var PDU_ML3_MS_NW emerg_setup;
9091 var octetstring emerg_setup_enc;
9092 var RSL_Message emerg_setup_data_ind;
9093
9094 f_establish_fully(omit, omit);
9095
9096 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
9097 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
9098 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
9099
9100 RSL.send(emerg_setup_data_ind);
9101}
9102
9103/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
9104 * CALLS are permitted by the BSC config. */
9105private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
9106 var PDU_BSSAP emerg_setup_data_ind_bssap;
9107 var PDU_ML3_MS_NW emerg_setup;
9108 timer T := 3.0;
9109
9110 f_assignment_emerg_setup()
9111
9112 T.start;
9113 alt {
9114 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
9115 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
9116 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
9117 setverdict(fail, "no emergency setup");
9118 }
9119 }
9120 [] BSSAP.receive {
9121 setverdict(fail, "unexpected BSSAP message!");
9122 }
9123 [] T.timeout {
9124 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
9125 }
9126 }
9127
9128 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009129 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02009130}
9131
9132/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
9133 * forbidden by the BSC config. */
9134private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
9135 var PDU_BSSAP emerg_setup_data_ind_bssap;
9136 timer T := 3.0;
9137
9138 f_assignment_emerg_setup()
9139
9140 T.start;
9141 alt {
9142 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9143 setverdict(pass);
9144 }
9145 [] RSL.receive {
9146 setverdict(fail, "unexpected RSL message!");
9147 }
9148 [] T.timeout {
9149 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
9150 }
9151 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009152 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01009153 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02009154}
9155
9156/* EMERGENCY CALL situation #1, allowed globally and by BTS */
9157testcase TC_assignment_emerg_setup_allow() runs on test_CT {
9158 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9159 var MSC_ConnHdlr vc_conn;
9160
9161 f_init(1, true);
9162 f_sleep(1.0);
9163
9164 f_vty_allow_emerg_msc(true);
9165 f_vty_allow_emerg_bts(true, 0);
9166 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9167 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009168 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009169}
9170
9171/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
9172testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
9173 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9174 var MSC_ConnHdlr vc_conn;
9175
9176 f_init(1, true);
9177 f_sleep(1.0);
9178
9179 f_vty_allow_emerg_msc(false);
9180 f_vty_allow_emerg_bts(true, 0);
9181 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9182 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009183 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009184}
9185
9186/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
9187testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9188 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9189 var MSC_ConnHdlr vc_conn;
9190
9191 /* Note: This simulates a spec violation by the MS, correct MS
9192 * implementations would not try to establish an emergency call because
9193 * the system information tells in advance that emergency calls are
9194 * not forbidden */
9195
9196 f_init(1, true);
9197 f_sleep(1.0);
9198
9199 f_vty_allow_emerg_msc(true);
9200 f_vty_allow_emerg_bts(false, 0);
9201 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9202 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009203 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009204}
9205
Philipp Maier82812002020-08-13 18:48:27 +02009206/* Test what happens when an emergency call arrives while all TCH channels are
9207 * busy, the BSC is expected to terminate one call in favor of the incoming
9208 * emergency call */
9209testcase TC_emerg_premption() runs on test_CT {
9210 var ASP_RSL_Unitdata rsl_ud;
9211 var integer i;
9212 var integer chreq_total, chreq_nochan;
9213 var RSL_Message rx_rsl;
Philipp Maier82812002020-08-13 18:48:27 +02009214
9215 f_init(1);
9216 f_sleep(1.0);
9217
9218 f_vty_allow_emerg_msc(true);
9219 f_vty_allow_emerg_bts(true, 0);
9220
9221 /* Fill up all channels on the BTS */
9222 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9223 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9224 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 +02009225 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009226 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009227 IPA_RSL[0][0].clear;
Philipp Maier82812002020-08-13 18:48:27 +02009228 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9229 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9230
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009231 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9232 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
9233 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009234 f_ipa_tx(ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009235
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009236 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9237 var BSSAP_N_CONNECT_ind rx_c_ind;
9238 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9239 var integer sccp_conn_id := rx_c_ind.connectionId;
9240 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9241
Philipp Maier82812002020-08-13 18:48:27 +02009242 /* Send Channel request for emegergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009243 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier82812002020-08-13 18:48:27 +02009244
9245 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009246 f_expect_chan_rel(first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009247 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009248
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009249 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9250 var BSSAP_N_DATA_ind rx_clear_req;
9251 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9252 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9253 log("XXX ", rx_clear_req);
9254 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9255 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9256 }
9257
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009258 /* Expect the BSC to send activate/assign the channel for the emergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009259 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009260 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9261 setverdict(fail, "different TCH lchan activated than expected");
9262 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009263 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(first_tch, 33));
9264 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009265
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009266 /* complete the BSSMAP Clear to satisfy the conn leak check */
9267 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9268 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9269 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9270 }
9271
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009272 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009273}
9274
9275/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009276private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009277private type record FHParamsTs {
9278 boolean enabled,
9279 uint6_t hsn,
9280 uint6_t maio,
9281 ArfcnList ma
9282};
9283
9284/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009285private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009286 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009287 FHParamsTs ts[8]
9288};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009289
9290/* Randomly generate the hopping parameters for the given timeslot numbers */
9291private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9292runs on test_CT return FHParamsTrx {
9293 var FHParamsTrx fhp;
9294
Philipp Maier798d8952021-10-19 14:43:19 +02009295 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9296 * fall in the GSM900 band. */
9297 fhp.arfcn.arfcn := f_rnd_int(3);
9298 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009299
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009300 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9301 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009302 fhp.ts[tn].enabled := false;
9303 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009304 continue;
9305 }
9306
9307 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009308 fhp.ts[tn].hsn := f_rnd_int(64);
9309 fhp.ts[tn].maio := f_rnd_int(64);
9310 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009311
9312 /* Random Mobile Allocation (hopping channels) */
9313 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9314 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9315 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009316 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009317 }
9318
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009319 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009320 }
9321
9322 log("f_TC_fh_params_gen(): ", fhp);
9323 return fhp;
9324}
9325
9326/* Make sure that the given Channel Description IE matches the hopping configuration */
9327private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9328{
9329 var template (present) ChannelDescription tr_cd;
9330 var template (present) MaioHsn tr_maio_hsn;
9331 var uint3_t tn := cd.chan_nr.tn;
9332
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009333 if (fhp.ts[tn].enabled) {
9334 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009335 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9336 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009337 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009338 }
9339
9340 if (not match(cd, tr_cd)) {
9341 setverdict(fail, "Channel Description IE does not match: ",
9342 cd, " vs expected ", tr_cd);
9343 }
9344}
9345
9346/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9347private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9348 in MobileAllocationLV ma)
9349{
9350 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9351
9352 if (not match(ma, tr_ma)) {
9353 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9354 tn, "): ", ma, " vs expected: ", tr_ma);
9355 } else {
9356 setverdict(pass);
9357 }
9358}
9359
9360private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9361 in MobileAllocationLV ma)
9362return template MobileAllocationLV {
9363 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009364 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009365 return { len := 0, ma := ''B };
9366 }
9367
9368 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9369 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9370 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009371
9372 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009373 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9374 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9375 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009376 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009377 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009378 }
9379 }
9380
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009381 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009382 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009383
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009384 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009385 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9386 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009387 }
9388
9389 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009390 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009391 if (full_mask[i] != '1'B)
9392 { continue; }
9393
9394 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9395 if (slot_mask[i] == '1'B) {
9396 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009397 } else {
9398 ma_mask := ma_mask & '0'B;
9399 }
9400 }
9401
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009402 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9403 if (full_mask[0] == '1'B) {
9404 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9405 if (slot_mask[0] == '1'B) {
9406 ma_mask := ma_mask & '1'B;
9407 } else {
9408 ma_mask := ma_mask & '0'B;
9409 }
9410 }
9411
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009412 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009413 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009414 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9415
9416 return { len := ma_mask_len, ma := ma_mask };
9417}
9418
Philipp Maier798d8952021-10-19 14:43:19 +02009419/* Configure the appropriate band for a given arfcn, exc */
9420private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9421{
9422 var charstring band;
9423 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9424
9425 select (arfcn_) {
9426 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9427 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9428 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9429 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9430 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9431 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9432 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9433 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9434 case else { return; }
9435 }
9436
9437 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9438 f_vty_transceive(BSCVTY, "band " & band);
9439 f_vty_transceive(BSCVTY, "end");
9440}
9441
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009442/* Configure the hopping parameters in accordance with the given record */
9443private function f_TC_fh_params_set(in FHParamsTrx fhp,
9444 uint8_t bts_nr := 0,
9445 uint8_t trx_nr := 0)
9446runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009447
9448 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9449
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009450 /* Enter the configuration node for the given BTS/TRX numbers */
9451 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9452
Philipp Maier798d8952021-10-19 14:43:19 +02009453 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009454
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009455 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009456 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9457
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009458 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009459 f_vty_transceive(BSCVTY, "hopping enabled 0");
9460 f_vty_transceive(BSCVTY, "exit"); /* go back */
9461 continue;
9462 }
9463
9464 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009465 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9466 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009467
9468 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009469 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9470 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009471 }
9472
9473 f_vty_transceive(BSCVTY, "hopping enabled 1");
9474 f_vty_transceive(BSCVTY, "exit"); /* go back */
9475 }
9476
9477 f_vty_transceive(BSCVTY, "end");
9478}
9479
9480/* Disable frequency hopping on all timeslots */
9481private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9482 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009483 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009484 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009485runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009486
9487 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9488
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009489 /* Enter the configuration node for the given BTS/TRX numbers */
9490 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9491
Philipp Maier798d8952021-10-19 14:43:19 +02009492 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009493
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009494 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009495 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9496
9497 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009498 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9499 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009500 }
9501
9502 f_vty_transceive(BSCVTY, "hopping enabled 0");
9503 f_vty_transceive(BSCVTY, "exit"); /* go back */
9504 }
9505
9506 f_vty_transceive(BSCVTY, "end");
9507 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9508}
9509
9510/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9511 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9512testcase TC_fh_params_chan_activ() runs on test_CT {
9513 var FHParamsTrx fhp := f_TC_fh_params_gen();
9514 var RSL_Message rsl_msg;
9515 var RSL_IE_Body ie;
9516
9517 f_init_vty();
9518
9519 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9520 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9521
9522 f_init(1);
9523
9524 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9525 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009526 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9527 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009528
9529 /* Make sure that Channel Identification IE is present */
9530 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9531 setverdict(fail, "RSL Channel Identification IE is absent");
9532 continue;
9533 }
9534
9535 /* Make sure that hopping parameters (HSN/MAIO) match */
9536 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9537
9538 /* "Mobile Allocation shall be included but empty" - let's check this */
9539 if (ie.chan_ident.ma.v.len != 0) {
9540 setverdict(fail, "Mobile Allocation IE is not empty: ",
9541 ie.chan_ident.ma, ", despite it shall be");
9542 continue;
9543 }
9544 }
9545
9546 /* Disable frequency hopping */
9547 f_TC_fh_params_unset(fhp);
9548
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009549 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009550}
9551
9552/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9553testcase TC_fh_params_imm_ass() runs on test_CT {
9554 var FHParamsTrx fhp := f_TC_fh_params_gen();
9555 var RSL_Message rsl_msg;
9556 var RSL_IE_Body ie;
9557
9558 f_init_vty();
9559
9560 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9561 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9562
9563 f_init(1);
9564
9565 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9566 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009567 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9568 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009569
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009570 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9571 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009572
9573 /* Make sure that Full Immediate Assign Info IE is present */
9574 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9575 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9576 continue;
9577 }
9578
9579 /* Decode the actual Immediate Assignment message */
9580 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9581 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9582 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9583 continue;
9584 }
9585
9586 /* Make sure that hopping parameters (HSN/MAIO) match */
9587 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9588
9589 /* Make sure that the Mobile Allocation IE matches */
9590 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9591 rr_msg.payload.imm_ass.mobile_allocation);
9592 }
9593
9594 /* Disable frequency hopping */
9595 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009596
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009597 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009598}
9599
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009600/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9601testcase TC_fh_params_assignment_cmd() runs on test_CT {
9602 var FHParamsTrx fhp := f_TC_fh_params_gen();
9603 var RSL_Message rsl_msg;
9604 var RSL_IE_Body ie;
9605
9606 f_init_vty();
9607
9608 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9609 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9610
9611 f_init(1);
9612
9613 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02009614 vc_MGCP[0].stop;
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009615
9616 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9617 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9618
9619 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9620 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9621 for (var integer i := 0; i < 3; i := i + 1) {
9622 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
9623 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
9624
9625 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9626 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009627 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009628
9629 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009630 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9631 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009632
9633 /* Make sure that L3 Information IE is present */
9634 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9635 setverdict(fail, "RSL L3 Information IE is absent");
9636 continue;
9637 }
9638
9639 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9640 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9641 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9642 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9643 continue;
9644 }
9645
9646 /* Make sure that hopping parameters (HSN/MAIO) match */
9647 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9648 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9649
9650 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9651 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009652 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009653 continue;
9654 }
9655
9656 /* Make sure that the Mobile Allocation IE matches (if present) */
9657 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9658 if (chan_desc.h and ma_present) {
9659 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9660 l3_msg.payload.ass_cmd.mobile_allocation.v);
9661 } else if (chan_desc.h and not ma_present) {
9662 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9663 continue;
9664 } else if (not chan_desc.h and ma_present) {
9665 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9666 continue;
9667 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009668
9669 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009670 }
9671
9672 /* Give the IUT some time to release all channels */
9673 f_sleep(3.0);
9674
9675 /* Disable frequency hopping */
9676 f_TC_fh_params_unset(fhp);
9677
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009678 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009679}
9680
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009681/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9682private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9683runs on test_CT {
9684 var RSL_Message rsl_msg;
9685 var RSL_IE_Body ie;
9686 var DchanTuple dt;
9687
9688 /* Establish a dedicated channel, so we can trigger handover */
9689 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009690 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009691
9692 /* Trigger handover from BTS0 to BTS1 */
9693 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9694 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9695
9696 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009697 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx := {1, 0});
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009698
9699 /* ACKnowledge channel activation and expect (RR) Handover Command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009700 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33), idx := {1, 0});
9701 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009702
9703 /* Make sure that L3 Information IE is present */
9704 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9705 setverdict(fail, "RSL L3 Information IE is absent");
9706 return;
9707 }
9708
9709 /* Decode the L3 message and make sure it is (RR) Handover Command */
9710 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9711 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9712 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9713 return;
9714 }
9715
9716 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9717 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9718 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9719 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9720 return;
9721 }
9722
9723 /* Make sure that hopping parameters (HSN/MAIO) match */
9724 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9725
9726 /* Make sure that Cell Channel Description IE is present */
9727 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9728 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9729 return;
9730 }
9731
9732 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9733 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9734 if (ma_present) {
9735 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9736 l3_msg.payload.ho_cmd.mobile_allocation.v);
9737 } else {
9738 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9739 return;
9740 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009741
9742 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009743}
9744testcase TC_fh_params_handover_cmd() runs on test_CT {
9745 var FHParamsTrx fhp := f_TC_fh_params_gen();
9746
9747 f_init_vty();
9748
9749 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9750 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9751
9752 f_vty_transceive(BSCVTY, "timeslot 0");
9753 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9754 f_vty_transceive(BSCVTY, "exit"); /* go back */
9755
9756 f_vty_transceive(BSCVTY, "timeslot 1");
9757 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9758 f_vty_transceive(BSCVTY, "end"); /* we're done */
9759
9760 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9761 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9762
9763 f_init(2);
9764
9765 f_TC_fh_params_handover_cmd(fhp);
9766
9767 /* Disable frequency hopping on BTS1 */
9768 f_TC_fh_params_unset(fhp, 1);
9769
9770 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9771 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9772
9773 f_vty_transceive(BSCVTY, "timeslot 0");
9774 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9775 f_vty_transceive(BSCVTY, "exit"); /* go back */
9776
9777 f_vty_transceive(BSCVTY, "timeslot 1");
9778 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9779 f_vty_transceive(BSCVTY, "end"); /* we're done */
9780
9781 f_shutdown_helper();
9782}
9783
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009784/* Verify the hopping parameters in System Information Type 4 */
9785testcase TC_fh_params_si4_cbch() runs on test_CT {
9786 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9787 var ASP_RSL_Unitdata rx_rsl_ud;
9788 timer T := 5.0;
9789
9790 f_init_vty();
9791
9792 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9793 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9794
9795 f_vty_transceive(BSCVTY, "timeslot 0");
9796 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9797 f_vty_transceive(BSCVTY, "exit"); /* go back */
9798
9799 f_vty_transceive(BSCVTY, "timeslot 1");
9800 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9801 f_vty_transceive(BSCVTY, "end"); /* we're done */
9802
9803 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9804 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9805
9806 f_init(1);
9807
9808 T.start;
9809 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009810 [] 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 +07009811 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9812 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9813
9814 /* Make sure that what we decoded is System Information Type 4 */
9815 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9816 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9817 repeat;
9818 }
9819
9820 /* Make sure that CBCH Channel Description IE is present */
9821 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9822 setverdict(fail, "CBCH Channel Description IE is absent");
9823 break;
9824 }
9825
9826 /* Finally, check the hopping parameters (HSN, MAIO) */
9827 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9828 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9829
9830 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9831 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9832 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9833 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9834 break;
9835 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9836 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9837 si.payload.si4.cbch_mobile_alloc.v);
9838 }
9839 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009840 [] IPA_RSL[0][0].receive { repeat; }
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009841 [] T.timeout {
9842 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9843 }
9844 }
9845
9846 /* Disable frequency hopping */
9847 f_TC_fh_params_unset(fhp);
9848
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009849 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009850 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9851
9852 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009853 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009854 f_vty_transceive(BSCVTY, "exit"); /* go back */
9855
9856 f_vty_transceive(BSCVTY, "timeslot 1");
9857 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9858 f_vty_transceive(BSCVTY, "end"); /* we're done */
9859
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009860 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009861}
9862
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009863template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9864 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9865
9866private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9867 template (present) BSSLAP_PDU expect_bsslap)
9868{
9869 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9870 if (not match(bsslap, expect_bsslap)) {
9871 log("EXPECTING BSSLAP: ", expect_bsslap);
9872 log("GOT BSSLAP: ", bsslap);
9873 setverdict(fail, "BSSLAP is not as expected");
9874 mtc.stop;
9875 }
9876 setverdict(pass);
9877}
9878
9879/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9880const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9881
9882private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9883 var PDU_BSSAP_LE rx_bsslap;
9884 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9885 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9886}
9887
9888/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9889 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9890private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9891 f_sleep(1.0);
9892
9893 f_establish_fully(omit, omit);
9894 f_bssap_le_register_imsi(g_pars.imsi, omit);
9895
9896 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9897 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9898
9899 var PDU_BSSAP_LE plr;
9900 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9901
9902 if (not do_ta_request) {
9903 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9904 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9905 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9906 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9907 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9908 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9909 mtc.stop;
9910 }
9911 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9912 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9913 if (not match(bsslap, expect_ta_layer3)) {
9914 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9915 log("GOT BSSLAP: ", bsslap);
9916 setverdict(fail, "BSSLAP is not as expected");
9917 mtc.stop;
9918 }
9919 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9920 * has no need to request the TA from the BSC and directly responds. */
9921 } else {
9922 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9923 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9924 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9925 }
9926
9927 /* SMLC got the TA from the BSC, now responds with geo information data. */
9928 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9929 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9930 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9931
9932 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9933 f_mo_l3_transceive();
9934
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009935 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009936
9937 f_sleep(2.0);
9938 setverdict(pass);
9939}
9940
9941/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9942 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9943private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9944 f_lcs_loc_req_for_active_ms(false);
9945}
9946testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9947 var MSC_ConnHdlr vc_conn;
9948 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9949
9950 f_init(1, true);
9951 f_sleep(1.0);
9952 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9953 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009954 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009955}
9956
9957/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9958 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9959private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9960 f_lcs_loc_req_for_active_ms(true);
9961}
9962testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9963 var MSC_ConnHdlr vc_conn;
9964 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9965
9966 f_init(1, true);
9967 f_sleep(1.0);
9968 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9969 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009970 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009971}
9972
9973/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9974 * conn without an active lchan. */
9975private function f_clear_A_conn() runs on MSC_ConnHdlr
9976{
9977 var BssmapCause cause := 0;
9978 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9979 BSSAP.receive(tr_BSSMAP_ClearComplete);
9980 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9981
9982 timer no_more_bssap := 5.0;
9983 no_more_bssap.start;
9984 alt {
9985 [] no_more_bssap.timeout { break; }
9986 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9987 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9988 mtc.stop;
9989 }
9990 }
9991 setverdict(pass);
9992}
9993
9994/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9995 * for LCS, for cases where there is only an A conn without an active lchan. */
9996private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9997{
9998 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9999
10000 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
10001 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
10002 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
10003 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10004 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10005 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10006
10007 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
10008 f_clear_A_conn();
10009 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10010 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10011}
10012
10013/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10014 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
10015 */
10016private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
10017 f_sleep(1.0);
10018
10019 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10020 f_bssap_le_register_imsi(g_pars.imsi, omit);
10021
10022 /* Register to receive the Paging Command */
10023 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10024 g_chan_nr := new_chan_nr;
10025 f_rslem_register(0, g_chan_nr);
10026
10027 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10028 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10029 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10030 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10031
10032 var PDU_BSSAP_LE plr;
10033 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10034
10035 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10036 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10037
10038 /* OsmoBSC needs to Page */
10039 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
10040 f_logp(BSCVTY, "got Paging Command");
10041
10042 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
10043 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010044 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(g_pars.imsi))), do_clear := false, expect_bssmap_l3 := false);
10045 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010046
10047 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
10048
10049 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10050
10051 /* SMLC got the TA from the BSC, now responds with geo information data. */
10052 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10053 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10054
10055 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10056
10057 /* The lchan is gone, the A-interface conn was created for the LCS only.
10058 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
10059 f_verify_active_A_conn_and_clear();
10060
10061 f_sleep(2.0);
10062 setverdict(pass);
10063}
10064testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
10065 var MSC_ConnHdlr vc_conn;
10066 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10067
10068 f_init(1, true);
10069 f_sleep(1.0);
10070
10071 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10072 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10073
10074 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
10075 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010076 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010077}
10078
10079/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
10080 */
10081private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
10082 f_sleep(1.0);
10083
10084 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10085 f_bssap_le_register_imsi(g_pars.imsi, omit);
10086
10087 /* provoke an abort by omitting both IMSI and IMEI */
10088 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10089 valueof(ts_BSSMAP_Perform_Location_Request(omit,
10090 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
10091 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10092
10093 /* BSC tells MSC about failure */
10094 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10095 locationEstimate := omit, positioningData := omit,
10096 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
10097
10098 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10099 f_verify_active_A_conn_and_clear();
10100
10101 f_sleep(2.0);
10102 setverdict(pass);
10103}
10104testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
10105 var MSC_ConnHdlr vc_conn;
10106 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10107
10108 f_init(1, true);
10109 f_sleep(1.0);
10110
10111 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10112 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10113
10114 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
10115 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010116 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010117}
10118
10119/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10120 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
10121private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
10122 f_sleep(1.0);
10123
10124 f_establish_fully(omit, omit);
10125 f_bssap_le_register_imsi(g_pars.imsi, omit);
10126
10127 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10128 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10129
10130 var PDU_BSSAP_LE plr;
10131 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10132
10133 if (do_ta) {
10134 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10135 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10136 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10137 }
10138
10139 /* SMLC fails to respond, BSC runs into timeout */
10140 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
10141 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10142
10143 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10144 locationEstimate := omit, positioningData := omit,
10145 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
10146
10147 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10148 f_verify_active_A_conn_and_clear();
10149
10150 f_sleep(2.0);
10151 setverdict(pass);
10152}
10153
10154/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10155 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
10156private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
10157 f_lcs_loc_req_for_active_ms_le_timeout(false);
10158}
10159
10160testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
10161 var MSC_ConnHdlr vc_conn;
10162 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10163
10164 f_init(1, true);
10165 f_sleep(1.0);
10166 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
10167 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010168 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010169}
10170
10171/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10172 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
10173private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
10174 f_lcs_loc_req_for_active_ms_le_timeout(true);
10175}
10176
10177testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
10178 var MSC_ConnHdlr vc_conn;
10179 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10180
10181 f_init(1, true);
10182 f_sleep(1.0);
10183 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10184 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010185 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010186}
10187
10188/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10189private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10190 f_sleep(1.0);
10191
10192 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10193 f_bssap_le_register_imsi(g_pars.imsi, omit);
10194
10195 /* Register to receive the Paging Command */
10196 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10197 g_chan_nr := new_chan_nr;
10198 f_rslem_register(0, g_chan_nr);
10199
10200 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10201 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10202 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10203 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10204
10205 var PDU_BSSAP_LE plr;
10206 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10207
10208 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10209 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10210
10211 /* OsmoBSC needs to Page */
10212 var PDU_BSSAP_LE rx_bsslap;
10213 alt {
10214 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10215 f_logp(BSCVTY, "got Paging Command");
10216 repeat;
10217 }
10218 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10219 /* MS does not respond to Paging, TA Req runs into timeout. */
10220 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10221 }
10222 }
10223
10224 /* SMLC responds with failure */
10225 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10226 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10227
10228 /* BSC tells MSC about failure */
10229 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10230 locationEstimate := omit, positioningData := omit,
10231 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10232
10233 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10234 f_verify_active_A_conn_and_clear();
10235
10236 f_sleep(2.0);
10237 setverdict(pass);
10238}
10239testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10240 var MSC_ConnHdlr vc_conn;
10241 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10242
10243 f_init(1, true);
10244 f_sleep(1.0);
10245
10246 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10247 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10248
10249 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10250 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010251 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010252}
10253
10254/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10255 * over. */
10256private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10257 f_sleep(1.0);
10258
10259 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10260 f_bssap_le_register_imsi(g_pars.imsi, omit);
10261
10262 /* Register to receive the Paging Command */
10263 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10264 g_chan_nr := new_chan_nr;
10265 f_rslem_register(0, g_chan_nr);
10266
10267 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10268 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10269 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10270 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10271
10272 var PDU_BSSAP_LE plr;
10273 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10274
10275 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10276 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010277 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 +020010278 do_clear := false, expect_bssmap_l3 := true);
10279
10280 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10281 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10282
10283 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10284 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10285
10286 /* SMLC got the TA from the BSC, now responds with geo information data. */
10287 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10288 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10289 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10290
10291 /* The lchan should still exist, it was from a CM Service Request. */
10292 f_mo_l3_transceive();
10293
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010294 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010295
10296 f_sleep(2.0);
10297 setverdict(pass);
10298}
10299testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10300 var MSC_ConnHdlr vc_conn;
10301 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10302
10303 f_init(1, true);
10304 f_sleep(1.0);
10305
10306 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10307 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10308
10309 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10310 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010311 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010312}
10313
10314/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10315 * the new lchan after handover. */
10316private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10317 f_sleep(1.0);
10318
10319 f_establish_fully(omit, omit);
10320 f_bssap_le_register_imsi(g_pars.imsi, omit);
10321
10322 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10323 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10324
10325 var PDU_BSSAP_LE plr;
10326 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10327
10328 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10329 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10330
10331 var HandoverState hs := {
10332 rr_ho_cmpl_seen := false,
10333 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010334 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010335 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010336 };
10337 /* issue hand-over command on VTY */
10338 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10339 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10340 f_rslem_suspend(RSL1_PROC);
10341
10342 /* From the MGW perspective, a handover is is characterized by
10343 * performing one MDCX operation with the MGW. So we expect to see
10344 * one more MDCX during handover. */
10345 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10346
10347 alt {
10348 [] as_handover(hs);
10349 }
10350
10351 var PDU_BSSAP_LE rx_bsslap;
10352
10353 interleave {
10354 /* Expect the BSC to inform the MSC about the handover */
10355 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10356
10357 /* Expect the BSC to inform the SMLC about the handover */
10358 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10359 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10360 }
10361 }
10362
10363 /* SMLC now responds with geo information data. */
10364 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10365 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10366 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10367
10368 /* lchan still active */
10369 f_mo_l3_transceive(RSL1);
10370
10371 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010372 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010373
10374 f_sleep(2.0);
10375 setverdict(pass);
10376}
10377testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10378 var MSC_ConnHdlr vc_conn;
10379 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10380
10381 f_init(2, true);
10382 f_sleep(1.0);
10383 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10384 vc_conn.done;
Oliver Smith39f53072022-10-27 14:44:04 +020010385 f_shutdown_helper(ho := true);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010386}
10387
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010388private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10389{
10390 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10391 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10392 * another lchan. */
10393 g_pars.ra := 'b7'O;
10394 f_assignment_emerg_setup();
10395
10396 var PDU_BSSAP emerg_setup_data_ind_bssap;
10397 timer T := 3.0;
10398 T.start;
10399 alt {
10400 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10401 var PDU_ML3_MS_NW verify_emerg_setup;
10402 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10403 if (not isbound(verify_emerg_setup.msgs.cc.emergencySetup)) {
10404 setverdict(fail, "no emergency setup");
10405 }
10406 }
10407 [] BSSAP.receive {
10408 setverdict(fail, "unexpected BSSAP message!");
10409 }
10410 [] T.timeout {
10411 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10412 }
10413 }
10414
10415 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10416
10417 /* Do a Location Request in-between the CC call setup */
10418 f_bssap_le_register_imsi(g_pars.imsi, omit);
10419 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10420 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10421 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10422 /* SMLC got the TA from the BSC, now responds with geo information data. */
10423 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10424 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10425 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10426
10427 /* Go on with voice call assignment */
10428 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10429 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10430
10431 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
10432 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
10433 * seems a good idea to see how osmo-bsc reacts to this. */
10434 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
10435 elementIdentifier := '0B'O, /* overwritten */
10436 lengthIndicator := 0, /* overwritten */
10437 speechOrDataIndicator := '0001'B, /* speech */
10438 spare1_4 := '0000'B,
10439 channelRateAndType := ChRate_TCHForH_Fpref,
10440 speechId_DataIndicator := 'c2918105'O
10441 };
10442 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
10443 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
10444
10445 f_rslem_dchan_queue_enable();
10446
10447 var ExpectCriteria mgcpcrit := {
10448 connid := omit,
10449 endpoint := omit,
10450 transid := omit
10451 };
10452 f_create_mgcp_expect(mgcpcrit);
10453
10454 BSSAP.send(ass_cmd);
10455
10456 var AssignmentState st := valueof(ts_AssignmentStateInit);
10457 st.voice_call := true;
10458 st.is_assignment := false;
10459 alt {
10460 [] as_modify(st);
10461 [] as_Media();
10462 [st.modify_done] BSSAP.receive(exp_compl) {
10463 setverdict(pass);
10464 }
10465 }
10466
10467 /* Voice call carries on ... */
10468 f_sleep(2.0);
10469
10470 setverdict(pass);
10471 f_perform_clear();
10472}
10473
10474testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10475 var MSC_ConnHdlr vc_conn;
10476 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10477
10478 f_init(1, true);
10479 f_sleep(1.0);
10480 f_vty_allow_emerg_msc(true);
10481 f_vty_allow_emerg_bts(true, 0);
10482 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10483 vc_conn.done;
10484 f_shutdown_helper();
10485}
10486
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010487private altstep no_bssmap_clear_req() runs on MSC_ConnHdlr {
10488 [] BSSAP.receive(tr_BSSMAP_ClearRequest) {
10489 setverdict(fail, "unexpected BSSMAP Clear Request");
10490 mtc.stop;
10491 }
10492}
10493
10494private type enumerated RslRel {
10495 RSLREL_REL_IND,
10496 RSLREL_CONN_FAIL
10497};
10498
10499private function f_emerg_call_and_lcs_loc_req_early_lchan_release(RslRel rsl_rel) runs on MSC_ConnHdlr
10500{
10501 g_pars.ra := f_rnd_ra_emerg();
10502 f_assignment_emerg_setup();
10503
10504 var PDU_BSSAP emerg_setup_data_ind_bssap;
10505 timer T := 3.0;
10506 T.start;
10507 alt {
10508 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10509 var PDU_ML3_MS_NW verify_emerg_setup;
10510 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10511 if (not ischosen(verify_emerg_setup.msgs.cc.emergencySetup)) {
10512 setverdict(fail, "no emergency setup");
10513 }
10514 }
10515 [] BSSAP.receive {
10516 setverdict(fail, "unexpected BSSAP message!");
10517 }
10518 [] T.timeout {
10519 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10520 }
10521 }
10522
10523 /* Start a Location Request to locate the emergency */
10524 f_bssap_le_register_imsi(g_pars.imsi, omit);
10525 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10526 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10527 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10528
10529 /* 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
10530 * do a Clear Command when the Location Response arrives. */
10531 activate(no_bssmap_clear_req());
10532
10533 /* the lchan gets interrupted while the Location Request has no response */
10534 select (rsl_rel) {
10535 case (RSLREL_REL_IND) {
10536 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10537 f_expect_lchan_rel(RSL, RSL_PROC);
10538 }
10539 case (RSLREL_CONN_FAIL) {
10540 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
10541 }
10542 case else {
10543 setverdict(fail, "Unknown RslRel type");
10544 mtc.stop;
10545 }
10546 }
10547
10548 /* Still expect the Location Response to find its way to the MSC. */
10549 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10550 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10551 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10552
10553 setverdict(pass);
10554
10555 select (rsl_rel) {
10556 case (RSLREL_REL_IND) {
10557 f_perform_clear_no_lchan();
10558 }
10559 case (RSLREL_CONN_FAIL) {
10560 f_perform_clear();
10561 }
10562 }
10563}
10564
10565private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind(charstring id) runs on MSC_ConnHdlr
10566{
10567 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_REL_IND);
10568}
10569
10570testcase TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() runs on test_CT {
10571 var MSC_ConnHdlr vc_conn;
10572 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10573
10574 f_init(1, true);
10575 f_sleep(1.0);
10576 f_vty_allow_emerg_msc(true);
10577 f_vty_allow_emerg_bts(true, 0);
10578 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind), pars);
10579 vc_conn.done;
10580 f_shutdown_helper();
10581}
10582
10583private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail(charstring id) runs on MSC_ConnHdlr
10584{
10585 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_CONN_FAIL);
10586}
10587
10588testcase TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() runs on test_CT {
10589 var MSC_ConnHdlr vc_conn;
10590 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10591
10592 f_init(1, true);
10593 f_sleep(1.0);
10594 f_vty_allow_emerg_msc(true);
10595 f_vty_allow_emerg_bts(true, 0);
10596 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail), pars);
10597 vc_conn.done;
10598 f_shutdown_helper();
10599}
10600
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010601/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10602private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10603 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10604
10605 /* Also disable attach for the single connected MSC */
10606 f_vty_msc_allow_attach(BSCVTY, { false });
10607
10608 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) ));
10609 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10610
10611 /* No MSC is found, expecting a proper release on RSL */
10612 interleave {
10613 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10614 f_logp(BSCVTY, "Got RSL RR Release");
10615 }
10616 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10617 f_logp(BSCVTY, "Got RSL Deact SACCH");
10618 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010619 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010620 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10621 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010622 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010623 }
10624 }
10625 setverdict(pass);
10626}
10627testcase TC_no_msc() runs on test_CT {
10628
10629 f_init(1, true);
10630 f_sleep(1.0);
10631 var MSC_ConnHdlr vc_conn;
10632 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10633
10634 f_ctrs_bsc_init(counternames_bsc_mscpool);
10635
10636 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10637 vc_conn.done;
10638
10639 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10640 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010641 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010642}
10643
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010644/* Dyn PDCH todo:
10645 * activate OSMO as TCH/F
10646 * activate OSMO as TCH/H
10647 * does the BSC-located PCU socket get the updated INFO?
10648 * what if no PCU is connected at the time?
10649 * is the info correct on delayed PCU (re)connect?
10650 */
Harald Welte94e0c342018-04-07 11:33:23 +020010651
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010652private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +020010653 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020010654 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010655
10656 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10657 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10658 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10659 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10660 g_pars.ass_codec_list.codecElements[0];
10661 if (isvalue(g_pars.expect_mr_s0_s7)) {
10662 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10663 g_pars.expect_mr_s0_s7;
10664 }
10665 }
10666 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10667 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10668 log("expecting ASS COMPL like this: ", exp_compl);
10669
10670 f_establish_fully(ass_cmd, exp_compl);
10671
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010672 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 +000010673
10674 var RSL_Message rsl;
10675
10676 timer T := 5.0;
10677 T.start;
10678 alt {
10679 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10680 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10681 log("Rx L3 from net: ", l3);
10682 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10683 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10684 mtc.stop;
10685 }
10686 }
10687 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10688 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10689 mtc.stop;
10690 }
10691 [] T.timeout {
10692 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10693 setverdict(pass);
10694 }
10695 }
10696 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010697
10698 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010699}
10700
10701/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10702 * osmo-bsc. */
10703testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10704 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10705 var MSC_ConnHdlr vc_conn;
10706
10707 f_init(1, true);
10708 f_sleep(1.0);
10709
10710 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10711 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10712 vc_conn.done;
10713 f_shutdown_helper();
10714}
10715
10716/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10717 */
10718testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10719 f_init_vty();
10720
10721 f_init(1, false);
10722 f_sleep(1.0);
10723
10724 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10725
10726 var ASP_RSL_Unitdata rx_rsl_ud;
10727 timer T := 5.0;
10728
10729 T.start;
10730 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010731 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010732 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10733 T.stop;
10734 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10735 mtc.stop;
10736 }
10737 repeat;
10738 }
10739 [] T.timeout {
10740 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10741 setverdict(pass);
10742 }
10743 }
10744}
10745
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010746private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10747 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010748 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010749
10750 /* Trigger re-assignment to another lchan */
10751 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10752
10753 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10754 * one MDCX on MGCP. */
10755 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10756
10757 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10758 * as the old lchan used. */
10759 g_media.bts.ipa_crcx_seen := false;
10760 g_media.bts.ipa_mdcx_seen := false;
10761
10762 /* Send different BTS side RTP port number for the new lchan */
10763 g_media.bts.bts.port_nr := 4223;
10764
10765 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10766
10767 /* Trigger re-assignment. */
10768 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10769
10770 timer T := 5.0;
10771 T.start;
10772 alt {
10773 [] as_assignment(assignment_st);
10774 [] as_Media();
10775 [] T.timeout {
10776 break;
10777 }
10778 }
10779
10780 if (not assignment_st.assignment_done) {
10781 setverdict(fail, "Assignment did not complete");
10782 mtc.stop;
10783 }
10784
10785 f_check_mgcp_expectations()
10786 setverdict(pass);
10787
10788 f_sleep(2.0);
10789 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10790
10791 /* Instruct BSC to clear channel */
10792 var BssmapCause cause := 0;
10793 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10794 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010795 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10796 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010797 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010798 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010799 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010800 }
10801 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10802 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10803 }
10804 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010805 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010806
10807 f_sleep(0.5);
10808}
10809
10810testcase TC_reassignment_fr() runs on test_CT {
10811 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10812 var MSC_ConnHdlr vc_conn;
10813
10814 f_init(1, true);
10815 f_sleep(1.0);
10816
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010817 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010818
10819 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10820 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10821 vc_conn.done;
10822
10823 /* from f_establish_fully() */
10824 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10825 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10826 /* from re-assignment */
10827 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10828 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10829 f_ctrs_bsc_and_bts_verify();
10830 f_shutdown_helper();
10831}
10832
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010833const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10834const charstring REEST_CLEAR := "REEST_CLEAR";
10835const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10836
10837/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10838 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10839 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10840 * the MSC as the CM Re-Establishment is handled.
10841 *
10842 * MS bts0 bts1 bsc msc test-component
10843 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10844 * | | _1 wait a bit, to settle down
10845 * |<-x x--| | _1 "lose connection"
10846 * | | REEST_LOST_CONNECTION
10847 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10848 * | | REEST_CLEAR
10849 * | |<-0---| _1 Clear Command on first A-conn
10850 * | |--0-->| _1 Clear Complete
10851 * | |<----------------->| | _1 Release first channel
10852 * | | REEST_CLEAR_DONE
10853 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10854 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10855 *
10856 */
10857private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10858 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10859 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10860
10861 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10862 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10863
10864 f_establish_fully(ass_cmd, exp_compl);
10865
10866 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10867 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10868 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10869 f_sleep(2.0);
10870 COORD.send(REEST_LOST_CONNECTION);
10871
10872 alt {
10873 [] COORD.receive(REEST_CLEAR);
10874 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10875 setverdict(fail, "Unexpected channel release");
10876 mtc.stop;
10877 }
10878 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10879 setverdict(fail, "Unexpected channel release");
10880 mtc.stop;
10881 }
10882 }
10883 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010884 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010885 COORD.send(REEST_CLEAR_DONE);
10886}
10887
10888private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10889 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10890
10891 /* The MS lost the connection on the first channel, now establishes another one */
10892 COORD.receive(REEST_LOST_CONNECTION);
10893
10894 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10895 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10896 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10897
10898 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010899 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 +020010900 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10901
10902 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10903 COORD.send(REEST_CLEAR);
10904 COORD.receive(REEST_CLEAR_DONE);
10905
10906 f_sleep(2.0);
10907
10908 /* Answer the CM Re-Establishment with an Assignment Command. */
10909 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10910 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10911 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10912 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10913
10914 var AssignmentState st := valueof(ts_AssignmentStateInit);
10915 st.voice_call := true;
10916 st.is_assignment := true;
10917
10918 var ExpectCriteria mgcpcrit := {
10919 connid := omit,
10920 endpoint := omit,
10921 transid := omit
10922 };
10923 f_create_mgcp_expect(mgcpcrit);
10924
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010925 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010926
10927 BSSAP.send(ass_cmd);
10928
10929 var PDU_BSSAP bssap;
10930
10931 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010932 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10933 [] as_Media_ipacc(RSL1, RSL2);
10934 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010935 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10936 break;
10937 }
10938 }
10939
10940 f_sleep(3.0);
10941
10942 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010943 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010944}
10945
10946testcase TC_cm_reestablishment() runs on test_CT {
10947 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10948 var MSC_ConnHdlr vc_conn1;
10949
10950 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10951 var MSC_ConnHdlr vc_conn2;
10952 pars2.imsi := pars1.imsi;
10953 pars2.media_nr := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010954 pars2.expect_tsc := c_BtsParams[1].tsc;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010955
10956 f_init(2, true, guard_timeout := 40.0);
10957 f_sleep(1.0);
10958
10959 vc_conn1 := f_start_handler_create(pars1);
10960 vc_conn2 := f_start_handler_create(pars2);
10961 connect(vc_conn1:COORD, vc_conn2:COORD);
10962 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10963 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10964 vc_conn1.done;
10965 vc_conn2.done;
10966
10967 f_shutdown_helper();
10968}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010969
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010970function f_exp_ipa_rx_nonfatal(template (present) RSL_Message t_rx,
10971 boolean ignore_other_rx := true,
10972 BtsTrxIdx idx := {0, 0},
10973 float Tval := 2.0)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010974runs on test_CT return template (omit) RSL_Message {
10975 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010976 timer T := Tval;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010977
10978 T.start;
10979 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010980 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010981 T.stop;
10982 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010983 [ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
10984 [not ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010985 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10986 T.stop;
10987 return omit;
10988 }
10989 [] T.timeout {
10990 return omit;
10991 }
10992 }
10993 return rx_rsl_ud.rsl;
10994}
10995
10996private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
10997 f_vty_enter_cfg_bts(pt, bts_nr);
10998 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
10999 f_vty_transceive(pt, "exit");
11000 f_vty_transceive(pt, "exit");
11001 f_vty_transceive(pt, "exit");
11002}
11003
11004private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030011005 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011006 template (present) uint12_t arfcn := ?,
11007 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011008{
11009 var RSL_IE_Body full_imm_ass_info;
11010 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
11011 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
11012 mtc.stop;
11013 }
11014
11015 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
11016 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
11017 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011018 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011019 page_mode := ?);
11020 if (not match(rr_imm_ass, expect_imm_ass)) {
11021 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
11022 setverdict(fail, "Failed to match Immediate Assignment");
11023 mtc.stop;
11024 }
11025}
11026
11027testcase TC_imm_ass_post_chan_ack() runs on test_CT {
11028 var RSL_Message chan_act;
11029 var RSL_Message imm_ass;
11030
11031 f_init(1, false);
11032 f_sleep(1.0);
11033
11034 /* (should be the default anyway, just to make things clear) */
11035 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
11036
11037 /* RA containing reason=LU */
11038 var GsmFrameNumber fn := 2342;
11039 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011040 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011041
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011042 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011043
11044 /* First send the Chan Act ACK */
11045 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011046 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011047 var RSL_IE_Body chan_ident_ie;
11048 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11049 setverdict(fail, "RSL Channel Identification IE is absent");
11050 mtc.stop;
11051 }
11052
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011053 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011054
11055 /* Then expect the Immediate Assignment, after we ACKed the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011056 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011057
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011058 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11059 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011060
11061 /* Check that the lchan is working */
11062 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011063 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011064
11065 var BSSAP_N_CONNECT_ind rx_c_ind;
11066 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011067 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011068 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11069
11070 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011071 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011072 f_shutdown_helper();
11073}
11074
11075testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
11076 var RSL_Message chan_act;
11077 var RSL_Message imm_ass;
11078
11079 f_init(1, false);
11080 f_sleep(1.0);
11081
11082 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11083
11084 /* RA containing reason=LU */
11085 var GsmFrameNumber fn := 2342;
11086 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011087 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011088
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011089 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011090 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011091 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011092 var RSL_IE_Body chan_ident_ie;
11093 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11094 setverdict(fail, "RSL Channel Identification IE is absent");
11095 mtc.stop;
11096 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011097
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011098 /* (set bts 0 cfg back to default) */
11099 f_vty_set_imm_ass(BSCVTY);
11100
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011101 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011102 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011103 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11104 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011105
11106 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011107 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011108
11109 /* Check that the lchan is working */
11110 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011111 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011112
11113 var BSSAP_N_CONNECT_ind rx_c_ind;
11114 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011115 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011116 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11117
11118 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011119 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011120 f_shutdown_helper();
11121}
11122
Neels Hofmeyr23158742021-09-07 19:08:07 +020011123testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
11124 var RSL_Message chan_act;
11125 var RSL_Message imm_ass;
11126
11127 f_init(1, false);
11128 f_sleep(1.0);
11129
11130 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11131
11132 /* RA containing reason=LU */
11133 var GsmFrameNumber fn := 2342;
11134 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011135 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011136
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011137 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011138 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011139 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr23158742021-09-07 19:08:07 +020011140 var RSL_IE_Body chan_ident_ie;
11141 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11142 setverdict(fail, "RSL Channel Identification IE is absent");
11143 mtc.stop;
11144 }
11145
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011146 /* (set bts 0 cfg back to default) */
11147 f_vty_set_imm_ass(BSCVTY);
11148
Neels Hofmeyr23158742021-09-07 19:08:07 +020011149 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011150 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011151 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11152 chan_ident_ie.chan_ident.ch_desc.v.tsc);
11153
11154 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011155 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011156
11157 /* Check that the lchan is working */
11158 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011159 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011160
11161 var BSSAP_N_CONNECT_ind rx_c_ind;
11162 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011163 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020011164 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11165
11166 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011167 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020011168 f_shutdown_helper();
11169}
11170
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011171testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
11172 /* change Timeslot 6 before f_init() starts RSL */
11173 f_init_vty();
11174 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11175 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11176
11177 f_init(1, false);
11178 f_sleep(1.0);
11179
11180 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11181 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011182 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11183 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011184
11185 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11186 f_ts_set_chcomb(0, 0, 6, "PDCH");
11187
11188 /* block all static timeslots so that the dyn TS will be used */
11189 f_disable_all_tch_f();
11190 f_disable_all_tch_h();
11191 f_disable_all_sdcch();
11192
11193 var RSL_Message chan_act;
11194 var RSL_Message imm_ass;
11195
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011196 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11197
11198 /* RA containing reason=LU */
11199 var GsmFrameNumber fn := 2342;
11200 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011201 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011202
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011203 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011204 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
11205 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011206
11207 /* Now activation as SDCCH8 */
11208 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011209 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011210
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011211 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011212 var RSL_IE_Body chan_ident_ie;
11213 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11214 setverdict(fail, "RSL Channel Identification IE is absent");
11215 mtc.stop;
11216 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011217
11218 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011219 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011220 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11221 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011222
11223 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011224 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011225
11226 /* Check that the lchan is working */
11227 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011228 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011229
11230 var BSSAP_N_CONNECT_ind rx_c_ind;
11231 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011232 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011233 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11234
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011235 /* (set bts 0 cfg back to default) */
11236 f_vty_set_imm_ass(BSCVTY);
11237
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011238 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011239 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011240 f_shutdown_helper();
11241}
11242
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011243testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
11244 /* change Timeslot 6 before f_init() starts RSL */
11245 f_init_vty();
11246 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11247 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11248
11249 f_init(1, false);
11250 f_sleep(1.0);
11251
11252 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11253 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011254 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11255 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011256
11257 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11258 f_ts_set_chcomb(0, 0, 6, "PDCH");
11259
11260 /* block all static timeslots so that the dyn TS will be used */
11261 f_disable_all_tch_f();
11262 f_disable_all_tch_h();
11263 f_disable_all_sdcch();
11264
11265 var RSL_Message chan_act;
11266 var RSL_Message imm_ass;
11267
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011268 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11269
11270 /* RA containing reason=LU */
11271 var GsmFrameNumber fn := 2342;
11272 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011273 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011274
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011275 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011276 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011277
11278 /* And already the Immediate Assignment even before the PDCH Deact ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011279 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011280
11281 /* continue the Osmo style PDCH Deact (usual chan rel) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011282 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011283
11284 /* Now activation as SDCCH8 */
11285 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011286 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011287
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011288 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011289 var RSL_IE_Body chan_ident_ie;
11290 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11291 setverdict(fail, "RSL Channel Identification IE is absent");
11292 mtc.stop;
11293 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011294 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011295
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011296 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11297 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011298
11299 /* Check that the lchan is working */
11300 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011301 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011302
11303 var BSSAP_N_CONNECT_ind rx_c_ind;
11304 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011305 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011306 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11307
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011308 /* (set bts 0 cfg back to default) */
11309 f_vty_set_imm_ass(BSCVTY);
11310
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011311 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011312 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011313 f_shutdown_helper();
11314}
11315
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011316/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11317testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11318 var MSC_ConnHdlr vc_conn;
11319
11320 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11321 f_sleep(1.0);
11322
11323 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11324 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11325 "0,0,operational,unlocked,on,rsl-up;" &
11326 "1,0,operational,unlocked,on,rsl-up;" &
11327 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011328 "2,1,operational,unlocked,on,rsl-down;" &
11329 "2,2,operational,unlocked,on,rsl-down;" &
11330 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011331 "3,0,inoperational,locked,on,rsl-down;");
11332
11333 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11334 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11335 /* give it a moment to settle the FSM status */
11336 f_sleep(1.0);
11337
11338 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11339 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11340 * of "off"? But that's for a future patch if at all. */
11341 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11342 "0,0,operational,unlocked,on,rsl-up;" &
11343 "1,0,operational,locked,on,rsl-up;" &
11344 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011345 "2,1,operational,unlocked,on,rsl-down;" &
11346 "2,2,operational,unlocked,on,rsl-down;" &
11347 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011348 "3,0,inoperational,locked,on,rsl-down;");
11349
11350 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11351 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11352 f_sleep(1.0);
11353 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11354 "0,0,operational,unlocked,on,rsl-up;" &
11355 "1,0,operational,locked,on,rsl-up;" &
11356 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011357 "2,1,operational,unlocked,on,rsl-down;" &
11358 "2,2,operational,unlocked,on,rsl-down;" &
11359 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011360 "3,0,inoperational,locked,on,rsl-down;");
11361
11362 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11363 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11364 f_sleep(1.0);
11365 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11366 "0,0,operational,unlocked,on,rsl-up;" &
11367 "1,0,operational,unlocked,on,rsl-up;" &
11368 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011369 "2,1,operational,unlocked,on,rsl-down;" &
11370 "2,2,operational,unlocked,on,rsl-down;" &
11371 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011372 "3,0,inoperational,locked,on,rsl-down;");
11373
11374 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11375 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11376 f_sleep(1.0);
11377 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11378 "0,0,operational,unlocked,on,rsl-up;" &
11379 "1,0,operational,unlocked,on,rsl-up;" &
11380 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011381 "2,1,operational,unlocked,on,rsl-down;" &
11382 "2,2,operational,unlocked,on,rsl-down;" &
11383 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011384 "3,0,inoperational,locked,on,rsl-down;");
11385
11386 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11387 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11388 f_sleep(1.0);
11389 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11390 "0,0,operational,unlocked,on,rsl-up;" &
11391 "1,0,operational,unlocked,on,rsl-up;" &
11392 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011393 "2,1,operational,unlocked,on,rsl-down;" &
11394 "2,2,operational,unlocked,on,rsl-down;" &
11395 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011396 "3,0,inoperational,locked,on,rsl-down;");
11397
11398 f_shutdown_helper();
11399}
11400
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011401const CounterNameVals counternames_cm_serv_rej := {
11402 { "cm_serv_rej", 0 },
11403 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11404 { "cm_serv_rej:illegal_ms", 0 },
11405 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11406 { "cm_serv_rej:imei_not_accepted", 0 },
11407 { "cm_serv_rej:illegal_me", 0 },
11408 { "cm_serv_rej:plmn_not_allowed", 0 },
11409 { "cm_serv_rej:loc_not_allowed", 0 },
11410 { "cm_serv_rej:roaming_not_allowed", 0 },
11411 { "cm_serv_rej:network_failure", 0 },
11412 { "cm_serv_rej:synch_failure", 0 },
11413 { "cm_serv_rej:congestion", 0 },
11414 { "cm_serv_rej:srv_opt_not_supported", 0 },
11415 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11416 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11417 { "cm_serv_rej:call_can_not_be_identified", 0 },
11418 { "cm_serv_rej:incorrect_message", 0 },
11419 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11420 { "cm_serv_rej:msg_type_not_implemented", 0 },
11421 { "cm_serv_rej:msg_type_not_compatible", 0 },
11422 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11423 { "cm_serv_rej:condtional_ie_error", 0 },
11424 { "cm_serv_rej:msg_not_compatible", 0 },
11425 { "cm_serv_rej:protocol_error", 0 },
11426 { "cm_serv_rej:retry_in_new_cell", 0 }
11427};
11428
11429private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11430{
11431 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011432 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011433 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011434 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11435 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011436 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011437}
11438testcase TC_cm_serv_rej() runs on test_CT {
11439 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11440 var MSC_ConnHdlr vc_conn;
11441
11442 f_init(1, true);
11443 f_sleep(1.0);
11444
11445 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11446
11447 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11448 vc_conn.done;
11449
11450 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11451 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11452 f_ctrs_bts_verify();
11453
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011454 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011455 f_shutdown_helper();
11456}
11457
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011458/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11459 * Activ Ack (SYS#5627). */
11460private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11461 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011462
11463 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11464 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011465
11466 var BSSMAP_FIELD_CodecType codecType;
11467 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11468
11469 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11470
11471 /* First establish a signalling lchan */
11472 f_create_chan_and_exp();
11473 f_rslem_dchan_queue_enable();
11474
11475 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011476
11477 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011478 activate(as_Media_mgw(fail_on_dlcx := false));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011479
11480 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11481 f_rslem_register(0, chan_nr);
11482
11483 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11484 BSSAP.send(ass_cmd);
11485
11486
11487 /* Wait for the Channel Activ for the TCH channel */
11488 var ASP_RSL_Unitdata rx_rsl_ud;
11489 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11490
11491 /* make the original SDCCH disappear */
11492 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11493
11494 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11495 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11496
11497 interleave {
11498 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11499 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11500 }
11501
11502 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11503 BSSAP.receive(tr_BSSMAP_ClearComplete);
11504 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11505
11506 var MgcpCommand mgcp;
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011507 var MGCP_RecvFrom mrf;
11508 var template MgcpMessage msg_dlcx := { command := tr_DLCX };
11509 alt {
11510 [g_pars.aoip] MGCP.receive(tr_DLCX) -> value mgcp {
11511 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11512 }
11513 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
11514 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
11515 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
11516 }));
11517 }
11518 }
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011519
11520 f_sleep(0.5);
11521}
11522testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11523 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11524 var MSC_ConnHdlr vc_conn;
11525
11526 f_init(1, true);
11527 f_sleep(1.0);
11528
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011529 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11530 vc_conn.done;
11531
11532 f_shutdown_helper();
11533}
11534
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011535const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11536 { "all_allocated:sdcch", 0 },
11537 { "all_allocated:static_sdcch", 0 },
11538 { "all_allocated:tch", 0 },
11539 { "all_allocated:static_tch", 0 }
11540}
11541
11542private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11543{
11544 /* Make sure counters settle first */
11545 f_sleep(1.0);
11546
11547 /* Take a baseline of counters */
11548 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11549
11550 /* Elapse some time so that we see changes in counters, hopefully where expected */
11551 f_sleep(2.0);
11552
11553 /* Get new counters */
11554 var charstring_list all_changed := {};
11555 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11556 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11557
11558 /* Compare with expectations */
11559 var charstring_list all_expect_changed := {};
11560 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11561 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11562 }
11563 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11564}
11565
11566testcase TC_ratectr_all_available_allocated() runs on test_CT {
11567 var ASP_RSL_Unitdata rsl_ud;
11568 var integer i;
11569 var integer chreq_total, chreq_nochan;
11570
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011571 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011572 f_sleep(1.0);
11573
11574 /* Exhaust all dedicated SDCCH lchans.
11575 /* GSM 44.018 Table 9.1.8.2:
11576 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11577 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011578 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011579 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011580 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011581 }
11582
11583 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11584 * level.
11585 * All SDCCH are now occupied. */
11586 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11587
11588 /* Also fill up all remaining (TCH) channels */
11589 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011590 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011591 }
11592
11593 /* All TCH are now also occupied */
11594 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11595 "all_allocated:tch", "all_allocated:static_tch"});
11596
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011597 /* Clean up SDCCH lchans */
11598 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11599 f_perform_clear_test_ct(chan_cleanup[i]);
11600 }
11601
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011602 f_shutdown_helper();
11603}
11604
11605testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11606 var ASP_RSL_Unitdata rsl_ud;
11607 var integer i;
11608 var integer chreq_total, chreq_nochan;
11609
11610 f_init_vty();
11611 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11612 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11613 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11614
11615 f_init(1, guard_timeout := 60.0);
11616 f_sleep(1.0);
11617
11618 /* The dyn TS wants to activate PDCH mode, ACK that. */
11619 var RslChannelNr chan_nr;
11620 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011621 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11622 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011623
11624 /* Exhaust all dedicated SDCCH lchans.
11625 /* GSM 44.018 Table 9.1.8.2:
11626 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11627 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011628 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011629 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011630 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011631 }
11632
11633 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11634 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11635 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11636
11637 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11638 * Will release them later, so remember all the DchanTuples. */
11639 var DchanTuples dyn_sddch := {};
11640 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11641
11642 /* Also occupy the seven other SDCCH of the dyn TS */
11643 for (i := 0; i < 7; i := i+1) {
11644 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11645 }
11646
11647 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11648 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11649
11650 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11651 for (i := 0; i < 5; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011652 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011653 }
11654
11655 /* All TCH lchans are now also occupied, both static and dynamic */
11656 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11657 "all_allocated:tch", "all_allocated:static_tch"});
11658
11659 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11660 * incrementing. */
11661 var BssmapCause cause := 0;
11662 var DchanTuple dt := dyn_sddch[0];
11663 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011664 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011665
11666 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11667 * count as occupied, so those still both increment. */
11668 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11669 "all_allocated:tch", "all_allocated:static_tch"});
11670
11671 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11672 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11673 dt := dyn_sddch[i];
11674 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011675 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011676 }
11677
11678 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11679 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011680 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11681 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011682
11683 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11684 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11685
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011686 /* Clean up SDCCH lchans */
11687 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11688 f_perform_clear_test_ct(chan_cleanup[i]);
11689 }
11690
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011691 /* clean up config */
11692 f_ts_reset_chcomb(0);
11693
11694 f_shutdown_helper();
11695}
11696
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011697private function f_TC_chan_alloc_algo(DchanTuple dt, BtsTrxIdx idx)
11698runs on test_CT {
11699 /* MSC sends an Assignment Request */
11700 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11701 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11702 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11703 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
11704
11705 /* Expect the BSC to allocate a TCH channel on the given BTS/TRX */
11706 var RSL_Message rsl_chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
11707 /* Send CHAN ACT NACK, so that the requested TCH channel becomes BORKEN */
11708 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(rsl_chan_act.ies[0].body.chan_nr, RSL_ERR_EQUIPMENT_FAIL), idx);
11709 /* Expect to receive an Assignment Failure */
11710 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail));
11711}
11712
11713testcase TC_chan_alloc_algo_ascending() runs on test_CT {
11714 /* We need to access BTS2, which has 4 TRXs */
11715 f_init(nr_bts := 3);
11716
11717 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011718 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011719
11720 f_vty_enter_cfg_bts(BSCVTY, 2);
11721 f_vty_transceive(BSCVTY, "channel allocator ascending");
11722 f_vty_transceive(BSCVTY, "end");
11723
11724 /* Expect the BSC to allocate 4 x TCH/F channels on BTS2/TRX0 */
11725 for (var integer i := 0; i < 4; i := i + 1) {
11726 var DchanTuple dt := f_est_dchan('23'O, 23, '00000000'O, {2, 0});
11727 f_TC_chan_alloc_algo(dt, {2, 0});
11728 f_perform_clear_test_ct(dt);
11729 }
11730
11731 /* At this point all 4 x TCH/F channels are BORKEN, but they will be
11732 * resurrected upon the A-bis/OML link re-establishment. */
11733 f_shutdown_helper();
11734}
11735
11736testcase TC_chan_alloc_algo_descending() runs on test_CT {
11737 /* We need to access BTS2, which has 4 TRXs */
11738 f_init(nr_bts := 3);
11739
11740 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011741 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011742
11743 f_vty_enter_cfg_bts(BSCVTY, 2);
11744 f_vty_transceive(BSCVTY, "channel allocator descending");
11745 f_vty_transceive(BSCVTY, "end");
11746
11747 /* Expect the BSC to allocate 5 x TCH/F channels on BTS2/TRX3 */
11748 for (var integer i := 0; i < 5; i := i + 1) {
11749 var DchanTuple dt := f_est_dchan('23'O, 23, '00000000'O, {2, 0});
11750 f_TC_chan_alloc_algo(dt, {2, 3});
11751 f_perform_clear_test_ct(dt);
11752 }
11753
11754 /* At this point all 5 x TCH/F channels are BORKEN, but they will be
11755 * resurrected upon the A-bis/OML link re-establishment. */
11756 f_shutdown_helper();
11757}
11758
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011759testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
11760 const BtsTrxIdx TRX0 := {2, 0};
11761 const BtsTrxIdx TRX3 := {2, 3};
11762
11763 /* We need to access BTS2, which has 4 TRXs */
11764 f_init(nr_bts := 3);
11765
11766 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011767 vc_MGCP[0].stop;
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011768
11769 f_vty_enter_cfg_bts(BSCVTY, 2);
11770 f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
11771 f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
11772 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
11773 f_vty_transceive(BSCVTY, "end");
11774
11775 var DchanTuple dt;
11776
11777 f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
11778 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11779 f_TC_chan_alloc_algo(dt, TRX0);
11780 f_perform_clear_test_ct(dt);
11781
11782 f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
11783 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11784 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11785 ts_RSL_IE_UplinkMeas(30, 0),
11786 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011787 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011788 f_TC_chan_alloc_algo(dt, TRX0);
11789 f_perform_clear_test_ct(dt);
11790
11791 f_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
11792 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11793 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11794 ts_RSL_IE_UplinkMeas(45, 0),
11795 ts_RSL_IE_BS_Power(0)), TRX0);
11796 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11797 ts_RSL_IE_UplinkMeas(48, 0),
11798 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011799 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011800 f_TC_chan_alloc_algo(dt, TRX0);
11801 f_perform_clear_test_ct(dt);
11802
11803 f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
11804 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11805 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11806 ts_RSL_IE_UplinkMeas(50, 0),
11807 ts_RSL_IE_BS_Power(0)), TRX0);
11808 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11809 ts_RSL_IE_UplinkMeas(58, 0),
11810 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011811 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011812 f_TC_chan_alloc_algo(dt, TRX3);
11813 f_perform_clear_test_ct(dt);
11814
11815 f_vty_enter_cfg_bts(BSCVTY, 2);
11816 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
11817 f_vty_transceive(BSCVTY, "end");
11818
11819 f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
11820 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11821 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11822 ts_RSL_IE_UplinkMeas(50, 0),
11823 ts_RSL_IE_BS_Power(0)), TRX0);
11824 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11825 ts_RSL_IE_UplinkMeas(58, 0),
11826 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011827 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011828 f_TC_chan_alloc_algo(dt, TRX0);
11829 f_perform_clear_test_ct(dt);
11830
11831 f_vty_enter_cfg_bts(BSCVTY, 2);
11832 f_vty_transceive(BSCVTY, "channel allocator ascending");
11833 f_vty_transceive(BSCVTY, "end");
11834
11835 /* At this point some TCH/F channels are BORKEN, but they will be
11836 * resurrected upon the A-bis/OML link re-establishment. */
11837 f_shutdown_helper();
11838}
11839
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020011840private function f_vty_mgw_enable(integer mgw_nr := 1) runs on test_CT {
11841 var rof_charstring cmds := {
11842 "remote-ip " & mp_test_ip,
11843 "remote-port " & int2str(2427 + mgw_nr)
11844 };
11845 f_vty_config3(BSCVTY, {"network", "mgw " & int2str(mgw_nr)}, cmds);
11846 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " reconnect")
11847}
11848private function f_vty_mgw_disable(integer mgw_nr := 1) runs on test_CT {
11849 f_vty_config3(BSCVTY, {"network"}, { "no mgw " &int2str(mgw_nr) });
11850}
11851private function f_vty_mgw_block(integer mgw_nr := 1, boolean blocked := true) runs on test_CT {
11852 var charstring arg;
11853 if (blocked) {
11854 arg := "block";
11855 } else {
11856 arg := "unblock";
11857 }
11858 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " " & arg);
11859}
11860private const charstring COORD_CMD_ESTABLISHED := "COORD_CMD_ESTABLISHED";
11861private function f_TC_mgwpool_call_seq_1(charstring id) runs on MSC_ConnHdlr {
11862 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11863 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11864 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11865 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11866
11867 f_establish_fully(ass_cmd, exp_compl);
11868 COORD.send(COORD_CMD_ESTABLISHED);
11869
11870 COORD.receive(COORD_CMD_ESTABLISHED);
11871 f_perform_clear()
11872 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11873}
11874private function f_TC_mgwpool_call_seq_2(charstring id) runs on MSC_ConnHdlr {
11875 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11876 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11877 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11878 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11879
11880
11881 COORD.receive(COORD_CMD_ESTABLISHED);
11882 f_establish_fully(ass_cmd, exp_compl);
11883 COORD.send(COORD_CMD_ESTABLISHED);
11884
11885 f_perform_clear()
11886 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11887}
11888/* Test load is spread around 2 available MGWs */
11889testcase TC_mgwpool_all_used() runs on test_CT {
11890 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11891 var MSC_ConnHdlr vc_conn1;
11892 pars1.mgwpool_idx := 0;
11893
11894 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11895 var MSC_ConnHdlr vc_conn2;
11896 pars2.mgwpool_idx := 1;
11897
11898 f_init(1, true, nr_mgw := 2);
11899 f_sleep(1.0);
11900
11901 f_vty_mgw_enable(1);
11902
11903 vc_conn1 := f_start_handler_create(pars1);
11904 vc_conn2 := f_start_handler_create(pars2);
11905 connect(vc_conn1:COORD, vc_conn2:COORD);
11906 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11907 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11908 vc_conn1.done;
11909 vc_conn2.done;
11910
11911 f_vty_mgw_disable(1);
11912
11913 f_shutdown_helper();
11914}
11915
11916/* Test blocked MGW in the pool are not selected */
11917testcase TC_mgwpool_blocked_not_used() runs on test_CT {
11918 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11919 var MSC_ConnHdlr vc_conn1;
11920 pars1.mgwpool_idx := 0;
11921
11922 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11923 var MSC_ConnHdlr vc_conn2;
11924 pars2.mgwpool_idx := 0; /* expect it in the first one, since the second will be blocked */
11925 pars2.media_nr := 2;
11926
11927 f_init(1, true, nr_mgw := 2);
11928 f_sleep(1.0);
11929
11930 f_vty_mgw_enable(1);
11931 f_vty_mgw_block(1, true);
11932
11933 vc_conn1 := f_start_handler_create(pars1);
11934 vc_conn2 := f_start_handler_create(pars2);
11935 connect(vc_conn1:COORD, vc_conn2:COORD);
11936 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11937 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11938 vc_conn1.done;
11939 vc_conn2.done;
11940
11941 f_vty_mgw_disable(1);
11942
11943 f_shutdown_helper();
11944}
11945
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020011946/* Test BTS pinning to an MGW is applied */
11947testcase TC_mgwpool_pin_bts() runs on test_CT {
11948 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11949 var MSC_ConnHdlr vc_conn1;
11950 pars1.mgwpool_idx := 0;
11951
11952 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11953 var MSC_ConnHdlr vc_conn2;
11954 pars2.mgwpool_idx := 0; /* expect it in the first one, since the BTS is pinned to the first MGW */
11955 pars2.media_nr := 2;
11956
11957 f_init(1, true, nr_mgw := 2);
11958 f_sleep(1.0);
11959
11960 f_vty_mgw_enable(1);
11961 f_vty_cfg_bts(BSCVTY, 0, { "mgw pool-target 0" });
11962
11963 vc_conn1 := f_start_handler_create(pars1);
11964 vc_conn2 := f_start_handler_create(pars2);
11965 connect(vc_conn1:COORD, vc_conn2:COORD);
11966 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11967 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11968 vc_conn1.done;
11969 vc_conn2.done;
11970
11971 f_vty_cfg_bts(BSCVTY, 0, { "no mgw pool-target" } );
Vadim Yanitskiy389d7e02022-10-25 17:44:05 +070011972 f_vty_mgw_disable(1);
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020011973
11974 f_shutdown_helper();
11975}
11976
Oliver Smithc9a5f532022-10-21 11:32:23 +020011977private function f_tc_ho_meas_rep_multi_band(charstring id) runs on MSC_ConnHdlr {
11978 g_pars := f_gen_test_hdlr_pars();
11979 var PDU_BSSAP ass_req := f_gen_ass_req();
11980 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11981 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11982 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11983 f_establish_fully(ass_req, exp_compl);
11984
11985 /* Send a measurement report with bad rxlev except on 3rd entry. The
11986 * measurement report is divided into two sub lists, as described in
11987 * 3GPP TS 04.08 § 10.5.2.20. */
11988 var NcellReports neighbor_rep := {
11989 /* Sub list 1: same band */
Oliver Smitha6773042022-10-24 12:56:30 +020011990 { rxlev := 0, bcch_freq := 0, bsic := 12 }, /* ARFCN 800, band 1800, LAC 98 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020011991 /* Sub list 2: different band */
Oliver Smitha6773042022-10-24 12:56:30 +020011992 { rxlev := 0, bcch_freq := 1, bsic := 13 }, /* ARFCN 200, band 850, LAC 97 */
11993 { rxlev := 40, bcch_freq := 2, bsic := 14 }, /* ARFCN 1000, band 900, LAC 99 */
11994 { rxlev := 0, bcch_freq := 3, bsic := 11 } /* ARFCN 0, band 900, LAC 96 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020011995 };
11996 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
11997 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
11998 l3_mr, 0));
11999
12000 /* Expect a handover to the third entry. If the BSC parsed the report
Oliver Smitha6773042022-10-24 12:56:30 +020012001 * correctly, the third entry has LAC 99. */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012002 var template BSSMAP_FIELD_CellIdentificationList cid_list := {
Oliver Smitha6773042022-10-24 12:56:30 +020012003 cIl_LAC := { ts_BSSMAP_CI_LAC(99) }
Oliver Smithc9a5f532022-10-21 11:32:23 +020012004 };
12005 alt {
12006 [] BSSAP.receive(tr_BSSMAP_HandoverRequired(cid_list := cid_list)) {
12007 setverdict(pass);
12008 }
12009 [] BSSAP.receive(tr_BSSMAP_HandoverRequired()) {
12010 setverdict(fail, "Handover has unexpected LAC in Cell Identification List. The BSC probably"
12011 & " didn't parse the multi-band measurement report correctly.");
12012 }
12013 }
12014
12015 f_ho_out_of_this_bsc(skip_meas_rep := true);
12016}
12017testcase TC_ho_meas_rep_multi_band() runs on test_CT {
12018 /* Verify that the BSC parses the measurement report correctly when
12019 * neighbors in multiple bands are configured (OS#5717). See
12020 * gsm_arfcn2band_rc() in libosmocore src/gsm/gsm_utils.c for the
12021 * ARFCN -> band mapping. The MS is connected to band 1800. */
12022 var MSC_ConnHdlr vc_conn;
12023
12024 f_init_vty();
12025 f_bts_0_cfg(BSCVTY,
12026 {"neighbor-list mode automatic",
12027 "handover 1",
12028 "handover algorithm 2",
12029 "handover2 window rxlev averaging 1",
12030 "no neighbors",
12031 "neighbor lac 99 arfcn 1000 bsic any", /* band 900 */
12032 "neighbor lac 98 arfcn 800 bsic any", /* band 1800 */
12033 "neighbor lac 97 arfcn 200 bsic any", /* band 850 */
Oliver Smitha6773042022-10-24 12:56:30 +020012034 "neighbor lac 96 arfcn 0 bsic any"}); /* band 900 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012035 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
12036
12037 f_init(1, true);
12038 f_sleep(1.0);
12039
12040 f_ctrs_bsc_and_bts_handover_init();
12041
12042 vc_conn := f_start_handler(refers(f_tc_ho_meas_rep_multi_band));
12043 vc_conn.done;
12044
12045 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
12046 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
12047 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
12048 f_ctrs_bsc_and_bts_add(0, "handover:completed");
12049 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
12050 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
12051 f_ctrs_bsc_and_bts_verify();
12052 f_shutdown_helper(ho := true);
12053}
12054
Harald Welte28d943e2017-11-25 15:00:50 +010012055control {
Harald Welte898113b2018-01-31 18:32:21 +010012056 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010012057 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010012058 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020012059 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
12060 * these in the AoIP test suite. */
12061 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12062 execute( TC_stat_num_msc_connected_1() );
12063 execute( TC_stat_num_msc_connected_2() );
12064 execute( TC_stat_num_msc_connected_3() );
12065 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020012066 execute( TC_stat_num_bts_connected_1() );
12067 execute( TC_stat_num_bts_connected_2() );
12068 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010012069 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012070 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020012071 execute( TC_ctrl_location() );
12072 }
Harald Welte898113b2018-01-31 18:32:21 +010012073
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012074 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020012075 execute( TC_si2quater_2_earfcns() );
12076 execute( TC_si2quater_3_earfcns() );
12077 execute( TC_si2quater_4_earfcns() );
12078 execute( TC_si2quater_5_earfcns() );
12079 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020012080 execute( TC_si2quater_12_earfcns() );
12081 execute( TC_si2quater_23_earfcns() );
12082 execute( TC_si2quater_32_earfcns() );
12083 execute( TC_si2quater_33_earfcns() );
12084 execute( TC_si2quater_42_earfcns() );
12085 execute( TC_si2quater_48_earfcns() );
12086 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020012087 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020012088 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012089
Harald Welte898113b2018-01-31 18:32:21 +010012090 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010012091 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010012092 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010012093 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020012094 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020012095 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010012096 execute( TC_chan_act_ack_est_ind_noreply() );
12097 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010012098 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010012099 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070012100 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010012101 execute( TC_chan_rel_rll_rel_ind() );
12102 execute( TC_chan_rel_conn_fail() );
12103 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020012104 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
12105 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010012106 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010012107 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020012108 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010012109 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010012110 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020012111 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010012112
Harald Weltecfe2c962017-12-15 12:09:32 +010012113 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010012114
12115 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010012116 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010012117 execute( TC_assignment_csd() );
12118 execute( TC_assignment_ctm() );
12119 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012120 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12121 execute( TC_assignment_aoip_tla_v6() );
12122 }
Harald Welte235ebf12017-12-15 14:18:16 +010012123 execute( TC_assignment_fr_a5_0() );
12124 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012125 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020012126 execute( TC_assignment_fr_a5_1_codec_missing() );
12127 }
Harald Welte235ebf12017-12-15 14:18:16 +010012128 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020012129 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020012130 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020012131 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012132 execute( TC_ciph_mode_a5_0() );
12133 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020012134 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020012135 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012136 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020012137 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010012138
Harald Welte60aa5762018-03-21 19:33:13 +010012139 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020012140 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010012141 execute( TC_assignment_codec_hr() );
12142 execute( TC_assignment_codec_efr() );
12143 execute( TC_assignment_codec_amr_f() );
12144 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012145
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012146 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010012147 execute( TC_assignment_codec_amr_f_S1() );
12148 execute( TC_assignment_codec_amr_h_S1() );
12149 execute( TC_assignment_codec_amr_f_S124() );
12150 execute( TC_assignment_codec_amr_h_S124() );
12151 execute( TC_assignment_codec_amr_f_S0() );
12152 execute( TC_assignment_codec_amr_f_S02() );
12153 execute( TC_assignment_codec_amr_f_S024() );
12154 execute( TC_assignment_codec_amr_f_S0247() );
12155 execute( TC_assignment_codec_amr_h_S0() );
12156 execute( TC_assignment_codec_amr_h_S02() );
12157 execute( TC_assignment_codec_amr_h_S024() );
12158 execute( TC_assignment_codec_amr_h_S0247() );
12159 execute( TC_assignment_codec_amr_f_S01234567() );
12160 execute( TC_assignment_codec_amr_f_S0234567() );
12161 execute( TC_assignment_codec_amr_f_zero() );
12162 execute( TC_assignment_codec_amr_f_unsupp() );
12163 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000012164 execute( TC_assignment_codec_amr_f_start_mode_auto() );
12165 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000012166 execute( TC_assignment_codec_amr_f_start_mode_4() );
12167 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000012168 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012169 }
Harald Welte60aa5762018-03-21 19:33:13 +010012170
Philipp Maierac09bfc2019-01-08 13:41:39 +010012171 execute( TC_assignment_codec_fr_exhausted_req_hr() );
12172 execute( TC_assignment_codec_fr_exhausted_req_fr() );
12173 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
12174 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
12175 execute( TC_assignment_codec_hr_exhausted_req_fr() );
12176 execute( TC_assignment_codec_hr_exhausted_req_hr() );
12177 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
12178 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
12179 execute( TC_assignment_codec_req_hr_fr() );
12180 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020012181 execute( TC_assignment_sdcch_exhausted_req_signalling() );
12182 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
12183 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010012184
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +020012185 execute( TC_assignment_codec_hr_osmux_on() );
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020012186 execute( TC_assignment_osmux() );
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020012187 execute( TC_assignment_osmux_cn() );
12188 execute( TC_assignment_osmux_bts() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020012189
Harald Welte898113b2018-01-31 18:32:21 +010012190 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010012191 execute( TC_rll_est_ind_inact_lchan() );
12192 execute( TC_rll_est_ind_inval_sapi1() );
12193 execute( TC_rll_est_ind_inval_sapi3() );
12194 execute( TC_rll_est_ind_inval_sacch() );
12195
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070012196 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
12197 execute( TC_tch_dlci_link_id_sapi() );
12198
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012199 /* SAPI N Reject triggered by RLL establishment failures */
12200 execute( TC_rll_rel_ind_sapi_n_reject() );
12201 execute( TC_rll_err_ind_sapi_n_reject() );
12202 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070012203 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012204
Harald Welte898113b2018-01-31 18:32:21 +010012205 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010012206 execute( TC_paging_imsi_nochan() );
12207 execute( TC_paging_tmsi_nochan() );
12208 execute( TC_paging_tmsi_any() );
12209 execute( TC_paging_tmsi_sdcch() );
12210 execute( TC_paging_tmsi_tch_f() );
12211 execute( TC_paging_tmsi_tch_hf() );
12212 execute( TC_paging_imsi_nochan_cgi() );
12213 execute( TC_paging_imsi_nochan_lac_ci() );
12214 execute( TC_paging_imsi_nochan_ci() );
12215 execute( TC_paging_imsi_nochan_lai() );
12216 execute( TC_paging_imsi_nochan_lac() );
12217 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010012218 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
12219 execute( TC_paging_imsi_nochan_rnc() );
12220 execute( TC_paging_imsi_nochan_lac_rnc() );
12221 execute( TC_paging_imsi_nochan_lacs() );
12222 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010012223 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010012224 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010012225 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010012226 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010012227 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020012228 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020012229 execute( TC_paging_450req_no_paging_load_ind() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010012230
12231 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010012232 execute( TC_rsl_unknown_unit_id() );
12233
12234 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012235
12236 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020012237 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012238 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010012239 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010012240 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010012241 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010012242 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012243
Harald Welte261af4b2018-02-12 21:20:39 +010012244 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020012245 execute( TC_ho_int_a5_0() );
12246 execute( TC_ho_int_a5_1() );
12247 execute( TC_ho_int_a5_3() );
12248 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000012249 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012250
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012251 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020012252 execute( TC_ho_out_fail_no_msc_response() );
12253 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020012254 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012255
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012256 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020012257 execute( TC_ho_into_this_bsc_a5_0() );
12258 execute( TC_ho_into_this_bsc_a5_1() );
12259 execute( TC_ho_into_this_bsc_a5_3() );
12260 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010012261 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
12262 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010012263 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012264 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12265 execute( TC_ho_into_this_bsc_tla_v6() );
12266 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020012267 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030012268 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010012269 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020012270 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020012271 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
12272 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012273 execute( TC_ho_in_fail_msc_clears() );
12274 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
12275 execute( TC_ho_in_fail_no_detect() );
12276 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010012277 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012278
Neels Hofmeyr91401012019-07-11 00:42:35 +020012279 execute( TC_ho_neighbor_config_1() );
12280 execute( TC_ho_neighbor_config_2() );
12281 execute( TC_ho_neighbor_config_3() );
12282 execute( TC_ho_neighbor_config_4() );
12283 execute( TC_ho_neighbor_config_5() );
12284 execute( TC_ho_neighbor_config_6() );
12285 execute( TC_ho_neighbor_config_7() );
12286
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012287 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010012288 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010012289 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020012290
12291 execute( TC_dyn_pdch_ipa_act_deact() );
12292 execute( TC_dyn_pdch_ipa_act_nack() );
12293 execute( TC_dyn_pdch_osmo_act_deact() );
12294 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010012295 execute( TC_dyn_ts_sdcch8_act_deact() );
12296 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
12297 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
12298 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012299
Stefan Sperling0796a822018-10-05 13:01:39 +020012300 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020012301 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020012302
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010012303 /* Power control related */
12304 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020012305 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020012306
12307 /* MSC pooling */
12308 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
12309 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
12310 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
12311 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
12312 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12313 execute( TC_mscpool_L3Compl_on_1_msc() );
12314 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
12315 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
12316 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
12317 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
12318 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
12319 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
12320 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
12321 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
12322 execute( TC_mscpool_paging_and_response_imsi() );
12323 execute( TC_mscpool_paging_and_response_tmsi() );
12324 execute( TC_mscpool_no_allow_attach_round_robin() );
12325 execute( TC_mscpool_no_allow_attach_valid_nri() );
12326 }
12327
Harald Welte99f3ca02018-06-14 13:40:29 +020012328 execute( TC_early_conn_fail() );
12329 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020012330 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012331
Philipp Maier783681c2020-07-16 16:47:06 +020012332 /* Emergency call handling (deny / allow) */
12333 execute( TC_assignment_emerg_setup_allow() );
12334 execute( TC_assignment_emerg_setup_deny_msc() );
12335 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020012336 execute( TC_emerg_premption() );
12337
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070012338 /* Frequency hopping parameters handling */
12339 execute( TC_fh_params_chan_activ() );
12340 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070012341 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070012342 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070012343 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012344
12345 if (mp_enable_lcs_tests) {
12346 execute( TC_lcs_loc_req_for_active_ms() );
12347 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
12348 execute( TC_lcs_loc_req_for_idle_ms() );
12349 execute( TC_lcs_loc_req_no_subscriber() );
12350 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
12351 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
12352 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
12353 execute( TC_cm_service_during_lcs_loc_req() );
12354 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020012355 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020012356 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() );
12357 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012358 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000012359
12360 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000012361
12362 execute( TC_refuse_chan_act_to_vamos() );
12363 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000012364
12365 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020012366
12367 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020012368
12369 execute( TC_imm_ass_post_chan_ack() );
12370 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020012371 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020012372 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020012373 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020012374
12375 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012376
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020012377 execute( TC_ratectr_all_available_allocated() );
12378 execute( TC_ratectr_all_available_allocated_dyn() );
12379
Neels Hofmeyrb7581872021-11-07 14:02:49 +010012380 execute( TC_cm_serv_rej() );
12381
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012382 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012383
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012384 /* Channel allocator */
12385 execute( TC_chan_alloc_algo_ascending() );
12386 execute( TC_chan_alloc_algo_descending() );
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012387 execute( TC_chan_alloc_algo_ass_dynamic() );
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012388
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012389 /* MGW pool */
12390 /* TODO: this conditional canbe dropped once osmo-bsc >1.10.0 is released: */
12391 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
12392 execute( TC_mgwpool_all_used() );
12393 execute( TC_mgwpool_blocked_not_used() );
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012394 execute( TC_mgwpool_pin_bts() );
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012395 }
12396
Oliver Smithc9a5f532022-10-21 11:32:23 +020012397 execute( TC_ho_meas_rep_multi_band() );
12398
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012399 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
12400 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
12401 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010012402}
12403
12404}