blob: 0cc9552b9c0f6e305dae21237a1d3bd60705d75d [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
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +0100610friend function gen_l3_valid_payload(hexstring imsi := ''H) return octetstring {
611 var octetstring l3_payload;
612 if (lengthof(imsi) == 0) {
613 imsi := f_rnd_imsi('00101'H);
614 }
615 l3_payload := enc_PDU_ML3_MS_NW(valueof(ts_LU_REQ(LU_Type_IMSI_Attach, ts_MI_LV(ts_MI_IMSI(imsi)))));
616 return l3_payload;
617}
618
Harald Weltea4ca4462018-02-09 00:17:14 +0100619type component test_CT extends CTRL_Adapter_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600620 /* Array of per-BTS/TRX state */
621 var BTS_State bts[NUM_BTS][NUM_TRX];
Harald Welte89ab1912018-02-23 18:56:29 +0100622 /* RSL common Channel Port (for RSL_Emulation) */
623 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600624 /* array of per-BTS/TRX RSL test ports */
625 port IPA_RSL_PT IPA_RSL[NUM_BTS][NUM_TRX];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100626 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200627 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
628 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200629 /* Configure/manage IPA_Emulation per-BTS/TRX port: */
630 port IPA_CFG_PT IPA_CFG_PORT[NUM_BTS][NUM_TRX];
Harald Weltea5d2ab22017-12-09 14:21:42 +0100631
Pau Espin Pedrol3c630532022-10-20 19:00:11 +0200632 var MGCP_Emulation_CT vc_MGCP[NUM_MGW];
633 var integer g_nr_mgw; /* number of vc_MGCP to initialize */
Harald Weltebc03c762018-02-12 18:09:38 +0100634 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100635
Daniel Willmannebdecc02020-08-12 15:30:17 +0200636 /* StatsD */
637 var StatsD_Checker_CT vc_STATSD;
638
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200639 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200640 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100641 /* for old legacy-tests only */
642 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200643 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100644
Harald Welte21b46bd2017-12-17 19:46:32 +0100645 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100646 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100647
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200648 /* Osmux is enabled through VTY */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200649 var boolean g_osmux_enabled_cn := false;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +0200650 var boolean g_osmux_enabled_bts := false;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200651
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100652 /*Configure T(tias) over VTY, seconds */
653 var integer g_bsc_sccp_timer_ias := 7 * 60;
654 /*Configure T(tiar) over VTY, seconds */
655 var integer g_bsc_sccp_timer_iar := 15 * 60;
656
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200657 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100658 timer T_guard := 30.0;
659
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200660 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000661 var CounterNameValsList g_ctr_bsc;
662 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200663
664 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
665 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100666}
667
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200668type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100669modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100670 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100671 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100672 /* port number to which to establish the IPA OML connections */
673 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100674 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100675 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100676 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100677 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200678 /* port number to which to listen for STATSD metrics */
679 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100680 /* IP address at which the test binds */
681 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100682
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200683 RAN_Configurations mp_bssap_cfg := {
684 {
685 transport := BSSAP_TRANSPORT_AoIP,
686 sccp_service_type := "mtp3_itu",
687 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
688 own_pc := 185, /* 0.23.1 first MSC emulation */
689 own_ssn := 254,
690 peer_pc := 187, /* 0.23.3 osmo-bsc */
691 peer_ssn := 254,
692 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200693 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200694 },
695 {
696 transport := BSSAP_TRANSPORT_AoIP,
697 sccp_service_type := "mtp3_itu",
698 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
699 own_pc := 2, /* 0.0.2 second MSC emulation */
700 own_ssn := 254,
701 peer_pc := 187, /* 0.23.3 osmo-bsc */
702 peer_ssn := 254,
703 sio := '83'O,
704 rctx := 2
705 },
706 {
707 transport := BSSAP_TRANSPORT_AoIP,
708 sccp_service_type := "mtp3_itu",
709 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
710 own_pc := 3, /* 0.0.3 third MSC emulation */
711 own_ssn := 254,
712 peer_pc := 187, /* 0.23.3 osmo-bsc */
713 peer_ssn := 254,
714 sio := '83'O,
715 rctx := 3
716 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100717 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200718
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200719 /* Must match per BTS config in osmo-bsc.cfg */
720 phys_chan_configs phys_chan_config := {
721 "CCCH+SDCCH4+CBCH",
722 "TCH/F",
723 "TCH/F",
724 "TCH/F",
725 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600726 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200727 "PDCH",
728 "PDCH"
729 };
730
Harald Welte47cd0e32020-08-21 12:39:11 +0200731 BSSAP_LE_Configuration mp_bssap_le_cfg := {
732 sccp_service_type := "mtp3_itu",
733 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200734 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200735 own_ssn := 252, /* SMLC side SSN */
736 peer_pc := 187, /* 0.23.3 osmo-bsc */
737 peer_ssn := 250, /* BSC side SSN */
738 sio := '83'O,
739 rctx := 6
740 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200741 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200742
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100743 /* Value set in osmo-bsc.cfg "ms max power" */
744 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600745
746 /* Whether to check for memory leaks */
747 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100748}
749
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200750friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200751
752 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200753 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200754 pars.aoip := true;
755 } else {
756 pars.aoip := false;
757 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100758 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200759 pars.mscpool.bssap_idx := bssap_idx;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600760 pars.expect_tsc := c_BtsParams[0].tsc;
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300761 pars.imsi := f_rnd_imsi('00101'H);
762
763 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200764
Philipp Maier48604732018-10-09 15:00:37 +0200765 return pars;
766}
767
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200768/* Convenience functions for rate counters using g_ctr_msc. */
769
770private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
771 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
772 log("initial msc rate counters: ", g_ctr_msc);
773}
774
775private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200776 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200777}
778
779/* f_ctrs_msc_init();
780 * f_do_thing(on_msc := 0);
781 * f_do_thing(on_msc := 0);
782 * f_do_other(on_msc := 1);
783 * f_ctrs_msc_add(0, "thing", 2);
784 * f_ctrs_msc_add(1, "other");
785 * f_ctrs_msc_verify();
786 */
787private function f_ctrs_msc_verify() runs on test_CT {
788 log("verifying msc rate counters: ", g_ctr_msc);
789 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
790}
791
792/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
793 * f_ctrs_msc_init();
794 * f_do_thing(on_msc := 0);
795 * f_do_thing(on_msc := 0);
796 * f_do_thing(on_msc := 0);
797 * f_ctrs_msc_expect(0, "thing", 3);
798 */
799private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
800 f_ctrs_msc_add(msc_nr, countername, val);
801 f_ctrs_msc_verify();
802}
803
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000804/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
805
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100806private 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 +0000807 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100808 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100809}
810
811function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
812 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000813 f_ctrs_bsc_init(counternames);
814}
815
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100816private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
817 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100818 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100819 f_ctrs_bsc_init(counternames_bsc_bts_handover);
820}
821
822private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000823 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100824}
825
826private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
827 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000828 f_ctrs_bsc_add(countername, val);
829}
830
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100831function f_ctrs_bts_verify() runs on test_CT {
832 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
833}
834
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000835/* f_ctrs_bsc_and_bts_init();
836 * f_do_thing(on_bts := 0);
837 * f_do_thing(on_bts := 0);
838 * f_do_other(on_bts := 1);
839 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
840 * f_ctrs_bsc_and_bts_add(1, "other");
841 * f_ctrs_bsc_and_bts_verify();
842 */
843private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100844 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000845 f_ctrs_bsc_verify();
846}
847
848/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
849 * f_ctrs_bsc_and_bts_init();
850 * f_do_thing(on_bts := 0);
851 * f_do_thing(on_bts := 0);
852 * f_do_thing(on_bts := 0);
853 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
854 */
855private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
856 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
857 f_ctrs_bsc_and_bts_verify();
858}
859
860
861/* Convenience functions for rate counters using g_ctr_bsc. */
862
863private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
864 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
865 log("initial bsc rate counters: ", g_ctr_bsc);
866}
867
868private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
869 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
870}
871
872/* f_ctrs_bsc_init();
873 * f_do_thing();
874 * f_do_thing();
875 * f_do_other();
876 * f_ctrs_bsc_add("thing", 2);
877 * f_ctrs_bsc_add("other");
878 * f_ctrs_bsc_verify();
879 */
880private function f_ctrs_bsc_verify() runs on test_CT {
881 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
882}
883
884/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
885 * f_ctrs_bsc_init();
886 * f_do_thing();
887 * f_ctrs_bsc_expect("thing", 1);
888 */
889private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
890 f_ctrs_bsc_add(countername, val);
891 f_ctrs_bsc_verify();
892}
893
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200894
Oliver Smith39f53072022-10-27 14:44:04 +0200895friend function f_shutdown_helper(boolean ho := false) runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100896 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600897 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100898 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
899 }
900
Oliver Smith39f53072022-10-27 14:44:04 +0200901 /* Reset handover related configuration */
902 if (ho) {
903 f_bts_0_cfg(BSCVTY,
904 {"no neighbors",
905 "neighbor-list mode manual-si5",
906 "neighbor-list add arfcn 100",
907 "neighbor-list add arfcn 200",
908 "si5 neighbor-list add arfcn 10",
909 "si5 neighbor-list add arfcn 20",
910 "handover algorithm 1"});
911 }
912
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200913 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100914 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200915 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100916}
917
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200918private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100919 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200920 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100921 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200922 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 +0200923 ts_BSSMAP_Reset(0, g_osmux_enabled_cn)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100924 T.start;
925 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200926 [] 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 +0200927 tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200928 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100929 }
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200930 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200931 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100932 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200933 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200934 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100935 repeat;
936 }
937 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200938 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200939 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200940 /* If we received a RESET after ours was sent, it
941 may be a race condition where the other peer beacame
942 available after we sent it, but we are in a desired
943 state anyway, so go forward. */
944 if (not reset_received) {
945 setverdict(fail);
946 }
947 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100948 }
Harald Welte28d943e2017-11-25 15:00:50 +0100949}
950
Harald Welteae026692017-12-09 01:03:01 +0100951type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100952 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100953 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100954 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100955 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100956 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100957 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100958 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100959 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100960}
961
Harald Welte21b46bd2017-12-17 19:46:32 +0100962/*! Start the IPA/RSL related bits for one IPA_Client.
963 * \param clnt IPA_Client for which to establish
964 * \param bsc_host IP address / hostname of the BSC
965 * \param bsc_port TCP port number of the BSC
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600966 * \param idx BTS/TRX index values
Harald Welte21b46bd2017-12-17 19:46:32 +0100967 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600968function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port,
969 BtsTrxIdx idx := {0, 0}, boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100970runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100971 timer T := 10.0;
972
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600973 clnt.id := "IPA-BTS" & int2str(idx.bts) & "-TRX" & int2str(idx.trx) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100974 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100975 clnt.ccm_pars := c_IPA_default_ccm_pars;
976 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600977 clnt.ccm_pars.unit_id := int2str(1234 + idx.bts) & "/0/" & int2str(idx.trx);
Harald Welte624f9632017-12-16 19:26:04 +0100978 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100979 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600980 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[idx.bts]);
Harald Welte624f9632017-12-16 19:26:04 +0100981 }
Harald Welteae026692017-12-09 01:03:01 +0100982
983 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200984 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100985 if (handler_mode) {
986 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
987 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600988 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100989 }
Harald Welteae026692017-12-09 01:03:01 +0100990
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600991 var integer local_port := 10000 + idx.bts * 1000 + idx.trx;
992 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", local_port, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100993 if (handler_mode) {
994 clnt.vc_RSL.start(RSL_Emulation.main());
995 return;
996 }
Harald Welteae026692017-12-09 01:03:01 +0100997
998 /* wait for IPA RSL link to connect and send ID ACK */
999 T.start;
1000 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001001 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +01001002 T.stop;
Harald Welteae026692017-12-09 01:03:01 +01001003 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001004 [] IPA_RSL[idx.bts][idx.trx].receive(ASP_IPA_Event:?) { repeat }
1005 [] IPA_RSL[idx.bts][idx.trx].receive { repeat }
Harald Welteae026692017-12-09 01:03:01 +01001006 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +01001007 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001008 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +01001009 }
1010 }
1011}
1012
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001013function f_ipa_rsl_stop(inout IPA_Client clnt, BtsTrxIdx idx := {0, 0}) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001014 var IPL4asp_Types.Result res := {
1015 errorCode := omit,
1016 connId := omit,
1017 os_error_code := omit,
1018 os_error_text := omit
1019 };
1020
Harald Welte12055472018-03-17 20:10:08 +01001021 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
1022 return;
1023 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001024
1025 /* Alive components don't finish sockets (TCP FIN) when they are
1026 * stopped. Hence, we need to manually call close() on them to make sure
1027 * the IUT knows about it. */
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001028 f_ipa_cfg_disconnect(IPA_CFG_PORT[idx.bts][idx.trx], res);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001029
Harald Welte12055472018-03-17 20:10:08 +01001030 clnt.vc_IPA.stop;
1031 if (isbound(clnt.vc_RSL)) {
1032 clnt.vc_RSL.stop;
1033 }
1034}
1035
Harald Welte21b46bd2017-12-17 19:46:32 +01001036/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +01001037function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1038 timer T := secs_max;
1039 T.start;
1040 while (true) {
1041 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1042 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001043 /* the 'degraded' state exists from OML connection time, and we have to wait
1044 * until all MO's are initialized */
1045 T.start(1.0);
1046 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001047 return;
1048 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001049 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001050 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001051 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001052 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001053 }
1054 }
1055}
1056
Harald Welte21b46bd2017-12-17 19:46:32 +01001057/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001058altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001059 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001060 [] T_guard.timeout {
1061 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001062 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001063 }
Harald Welte60e823a2017-12-10 14:10:59 +01001064 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001065 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001066 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001067 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Harald Welte69c1c262017-12-13 21:02:08 +01001068 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001069 }
Harald Welte28d943e2017-11-25 15:00:50 +01001070}
1071
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001072altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001073 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001074 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001075 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001076 }
1077}
1078
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001079function f_init_mgcp(integer mgw_nr, charstring id) runs on test_CT {
1080 id := id & "-MGCP-" & int2str(mgw_nr);
Daniel Willmann191e0d92018-01-17 12:44:35 +01001081
1082 var MGCPOps ops := {
1083 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1084 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1085 };
1086 var MGCP_conn_parameters mgcp_pars := {
1087 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001088 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001089 mgw_ip := mp_test_ip,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001090 mgw_udp_port := 2427 + mgw_nr,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001091 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
Pau Espin Pedrol36eeaf72022-10-20 16:50:31 +02001092 the one with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001093 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001094 };
1095
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001096 vc_MGCP[mgw_nr] := MGCP_Emulation_CT.create(id) alive;
1097 vc_MGCP[mgw_nr].start(MGCP_Emulation.main(ops, mgcp_pars, id));
Daniel Willmann191e0d92018-01-17 12:44:35 +01001098}
1099
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001100/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1101 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1102 * OsmuxCID IE.
1103 */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001104private function f_vty_allow_osmux_cn(boolean allow) runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001105 f_vty_enter_cfg_msc(BSCVTY, 0);
1106 if (allow) {
1107 f_vty_transceive(BSCVTY, "osmux on");
1108 } else {
1109 f_vty_transceive(BSCVTY, "osmux off");
1110 }
1111 f_vty_transceive(BSCVTY, "exit");
1112 f_vty_transceive(BSCVTY, "exit");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001113}
1114
Max2253c0b2018-11-06 19:28:05 +01001115function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001116 if (BSCVTY.checkstate("Mapped")) {
1117 /* skip initialization if already executed once */
1118 return;
1119 }
Harald Weltebc03c762018-02-12 18:09:38 +01001120 map(self:BSCVTY, system:BSCVTY);
1121 f_vty_set_prompts(BSCVTY);
1122 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001123 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1124 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001125}
1126
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001127friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001128{
1129 // log on TTCN3 log output
1130 log(log_msg);
1131 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001132 if (pt.checkstate("Mapped")) {
1133 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1134 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001135}
1136
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001137private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1138{
1139 if (rsl_idx >= lengthof(g_system_information)) {
1140 g_system_information[rsl_idx] := SystemInformationConfig_omit
1141 }
1142 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1143}
1144
1145altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1146 var ASP_RSL_Unitdata rx_rsl_ud;
1147
1148 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001149 [] 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 +02001150 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1151 repeat;
1152 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001153 [] 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 +02001154 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1155 repeat;
1156 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001157 [] 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 +02001158 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1159 repeat;
1160 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001161 [] 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 +02001162 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1163 repeat;
1164 }
1165
1166 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1167 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1168 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1169 repeat;
1170 }
1171 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1172 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1173 repeat;
1174 }
1175 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1176 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1177 repeat;
1178 }
1179 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1180 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1181 repeat;
1182 }
1183}
1184
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001185/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1186private type record of boolean my_BooleanList;
1187
1188private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1189{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001190 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1191
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001192 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001193 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1194 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1195 * stepping into that config node. */
1196 log("msc ", msc_nr, " is not configured, skipping");
1197 continue;
1198 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001199 f_vty_enter_cfg_msc(pt, msc_nr);
1200 if (allow_attach_list[msc_nr]) {
1201 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1202 f_vty_transceive(pt, "allow-attach", strict := false);
1203 } else {
1204 f_vty_transceive(pt, "no allow-attach", strict := false);
1205 }
1206 f_vty_transceive(pt, "exit");
1207 f_vty_transceive(pt, "exit");
1208 }
1209}
1210
Harald Welte21b46bd2017-12-17 19:46:32 +01001211/* global initialization function
1212 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001213 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1214 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1215 */
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001216function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001217 integer nr_msc := 1, integer nr_mgw := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001218 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001219
Harald Welteae026692017-12-09 01:03:01 +01001220 if (g_initialized) {
1221 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001222 }
Harald Welteae026692017-12-09 01:03:01 +01001223 g_initialized := true;
1224
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001225 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001226 activate(as_Tguard());
1227
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001228 f_init_vty("VirtMSC");
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001229 f_vty_allow_osmux_cn(g_osmux_enabled_cn);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001230
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001231 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001232 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1233
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001234 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1235 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1236 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1237 }
1238
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001239 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001240 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001241 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1242 * MSC-side BSSAP emulation */
1243 if (handler_mode) {
1244 var RanOps ranops := MSC_RanOps;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001245 ranops.use_osmux := g_osmux_enabled_cn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001246 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1247 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1248 f_ran_adapter_start(g_bssap[bssap_idx]);
1249 } else {
1250 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1251 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1252 f_ran_adapter_start(g_bssap[bssap_idx]);
1253 f_legacy_bssap_reset();
1254 }
Harald Welte67089ee2018-01-17 22:19:03 +01001255 }
Harald Welted5833a82018-05-27 16:52:56 +02001256
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001257 if (mp_enable_lcs_tests) {
1258 if (handler_mode) {
1259 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1260 } else {
1261 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1262 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1263 }
1264 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001265 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001266
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001267 /* start the test with exactly all enabled MSCs allowed to attach */
1268 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1269
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001270 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001271
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001272 g_nr_mgw := nr_mgw;
1273 for (var integer i := 0; i < g_nr_mgw; i := i+1) {
1274 f_init_mgcp(i, "VirtMGW");
1275 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01001276
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001277 for (var integer i := 0; i < nr_bts; i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001278 f_init_bts(i, c_BtsParams[i].trx_num, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001279 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001280
1281 /* Emit a marker to appear in the SUT's own logging output */
1282 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001283}
Harald Welte696ddb62017-12-08 14:01:43 +01001284
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001285function f_init_bts(integer bts_idx := 0,
1286 integer trx_num := NUM_TRX_CFG,
1287 boolean handler_mode := false)
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001288runs on test_CT {
1289 /* wait until osmo-bts-omldummy has respawned */
1290 f_wait_oml(bts_idx, "degraded", 5.0);
1291
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001292 /* start RSL connection(s) */
1293 for (var integer trx_idx := 0; trx_idx < trx_num; trx_idx := trx_idx + 1) {
1294 f_ipa_rsl_start(bts[bts_idx][trx_idx].rsl,
1295 mp_bsc_ip, mp_bsc_rsl_port,
1296 {bts_idx, trx_idx}, handler_mode);
1297 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001298 /* wait until BSC tells us "connected" */
1299 f_wait_oml(bts_idx, "connected", 5.0);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001300
1301 /* Set up BTS with VTY commands: */
Vadim Yanitskiy4d852082022-09-14 14:07:20 +07001302 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
1303 f_vty_enter_cfg_bts(BSCVTY, bts_idx);
1304 if (g_osmux_enabled_bts) {
1305 f_vty_transceive(BSCVTY, "osmux on");
1306 } else {
1307 f_vty_transceive(BSCVTY, "osmux off");
1308 }
1309 f_vty_transceive(BSCVTY, "end");
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001310 }
Harald Welte28d943e2017-11-25 15:00:50 +01001311}
1312
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001313function f_init_bts_and_check_sysinfo(integer bts_idx := 0,
1314 integer trx_num := NUM_TRX_CFG,
1315 boolean handler_mode := false,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001316 template SystemInformationConfig expect_si)
1317runs on test_CT {
1318 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1319
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001320 f_init_bts(bts_idx, trx_num, handler_mode);
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001321
1322 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1323 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1324 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1325 */
1326 f_sleep(5.0);
1327 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1328
1329 deactivate(sysinfo);
1330
1331 if (match(g_system_information[bts_idx], expect_si)) {
1332 setverdict(pass);
1333 } else {
1334 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1335 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1336 setverdict(fail, "received SI does not match expectations");
1337 return;
1338 }
1339}
1340
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001341/* expect to receive a RSL message matching a specified template on a given BTS / TRX */
1342function f_exp_ipa_rx(template (present) RSL_Message t_rx,
1343 BtsTrxIdx idx := {0, 0},
1344 float Tval := 2.0)
Harald Welteae026692017-12-09 01:03:01 +01001345runs on test_CT return RSL_Message {
1346 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001347 timer T := Tval;
Harald Welteae026692017-12-09 01:03:01 +01001348
1349 T.start;
1350 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001351 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001352 T.stop;
1353 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001354 [] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001355 [] T.timeout {
1356 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001357 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001358 }
Harald Welteae026692017-12-09 01:03:01 +01001359 }
1360 return rx_rsl_ud.rsl;
1361}
1362
Harald Welte21b46bd2017-12-17 19:46:32 +01001363/* helper function to transmit RSL on a given BTS/stream */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001364function f_ipa_tx(template (value) RSL_Message t_tx,
1365 BtsTrxIdx idx := {0, 0},
1366 IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001367runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001368 IPA_RSL[idx.bts][idx.trx].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001369}
1370
1371
Harald Welte4003d112017-12-09 22:35:39 +01001372/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001373testcase TC_chan_act_noreply() runs on test_CT {
1374 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001375 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001376
Harald Welte89d42e82017-12-17 16:42:41 +01001377 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001378
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001379 f_ipa_tx(ts_RSL_CHAN_RQD('23'O, 23));
1380 rsl_unused := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001381 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001382}
1383
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001384const CounterNameVals counternames_bts_chreq := {
1385 { "chreq:total", 0 },
1386 { "chreq:attempted_emerg", 0 },
1387 { "chreq:attempted_call", 0 },
1388 { "chreq:attempted_location_upd", 0 },
1389 { "chreq:attempted_pag", 0 },
1390 { "chreq:attempted_pdch", 0 },
1391 { "chreq:attempted_other", 0 },
1392 { "chreq:attempted_unknown", 0 },
1393 { "chreq:successful", 0 },
1394 { "chreq:successful_emerg", 0 },
1395 { "chreq:successful_call", 0 },
1396 { "chreq:successful_location_upd", 0 },
1397 { "chreq:successful_pag", 0 },
1398 { "chreq:successful_pdch", 0 },
1399 { "chreq:successful_other", 0 },
1400 { "chreq:successful_unknown", 0 },
1401 { "chreq:no_channel", 0 },
1402 { "chreq:max_delay_exceeded", 0 }
1403};
1404
1405/* verify the "chreq:*" counters */
1406private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1407{
1408 var GsmFrameNumber fn := 23;
1409
1410 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1411
1412 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001413 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn));
1414 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001415 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1416
1417 f_ctrs_bts_add(0, "chreq:total");
1418 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1419 f_ctrs_bts_verify();
1420
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001421 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1422 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001423
1424 f_ctrs_bts_add(0, "chreq:successful");
1425 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1426 f_ctrs_bts_verify();
1427
1428 /* test is done, release RSL Conn Fail Ind to clean up */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001429 f_ipa_tx(ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1430 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
1431 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001432 f_sleep(1.0);
1433}
1434
Harald Welte4003d112017-12-09 22:35:39 +01001435testcase TC_chan_act_counter() runs on test_CT {
1436 var BSSAP_N_UNITDATA_ind ud_ind;
1437 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001438 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001439
Harald Welte89d42e82017-12-17 16:42:41 +01001440 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001441
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001442 f_vty_allow_emerg_bts(true, 0);
1443
1444 f_ctrs_bts_init(1, counternames_bts_chreq);
1445
1446 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1447 f_chan_act_counter('a3'O, "emerg");
1448
1449 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1450 f_chan_act_counter('43'O, "call");
1451
1452 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1453 f_chan_act_counter('03'O, "location_upd");
1454
1455 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1456 f_chan_act_counter('23'O, "pag");
1457 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1458 f_chan_act_counter('33'O, "pag");
1459
1460 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1461 /* no PCU, so PDCH not allowed. Skip this test for now. */
1462 /* f_chan_act_counter('7b'O, "pdch"); */
1463
1464 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1465 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001466
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001467 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001468}
1469
Harald Welteae026692017-12-09 01:03:01 +01001470/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001471private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001472 var RSL_Message rx_rsl;
1473
Harald Welteae026692017-12-09 01:03:01 +01001474 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001475 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001476
1477 /* expect BSC to disable the channel again if there's no RLL EST IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001478 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := T3101_MAX);
Harald Welteae026692017-12-09 01:03:01 +01001479
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001480 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001481}
1482
Philipp Maier9c60a622020-07-09 15:08:46 +02001483/* Normal variant */
1484testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001485 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001486 f_TC_chan_act_ack_noest();
1487}
1488
1489/* Emergency call variant */
1490testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1491 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001492 f_init(1);
1493 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001494 f_TC_chan_act_ack_noest(ra := 'A5'O);
1495}
1496
Philipp Maier606f07d2020-08-12 17:21:58 +02001497/* Emergency call variant, but emergency calls are not allowed */
1498testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1499 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1500
1501 var RSL_Message rx_rsl;
1502 var GsmRrMessage rr;
1503
1504 f_init(1);
1505 f_vty_allow_emerg_bts(false, 0);
1506
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001507 IPA_RSL[0][0].clear;
1508 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier606f07d2020-08-12 17:21:58 +02001509
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001510 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Philipp Maier606f07d2020-08-12 17:21:58 +02001511 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1512 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1513 setverdict(pass);
1514 } else {
1515 setverdict(fail, "immediate assignment not rejected");
1516 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001517
1518 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001519}
1520
Harald Welteae026692017-12-09 01:03:01 +01001521/* Test behavior if MSC never answers to CR */
1522testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001523 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1524 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001525 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001526 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001527 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001528
Harald Welte89d42e82017-12-17 16:42:41 +01001529 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001530
1531 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001532 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001533
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001534 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001535
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001536 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload)));
Harald Welteae026692017-12-09 01:03:01 +01001537
1538 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001539 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001540 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001541 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001542}
1543
1544/* Test behavior if MSC answers with CREF to CR */
1545testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1546 var BSSAP_N_CONNECT_ind rx_c_ind;
1547 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001548 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welteae026692017-12-09 01:03:01 +01001549
Harald Welte89d42e82017-12-17 16:42:41 +01001550 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001551
1552 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001553 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001554
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001555 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welteae026692017-12-09 01:03:01 +01001556
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001557 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Harald Welteae026692017-12-09 01:03:01 +01001558 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1559
1560 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001561 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001562 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001563}
1564
Harald Welte618ef642017-12-14 14:58:20 +01001565/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1566testcase TC_chan_act_nack() runs on test_CT {
1567 var RSL_Message rx_rsl;
1568 var integer chact_nack;
1569
Harald Welte89d42e82017-12-17 16:42:41 +01001570 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001571
1572 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1573
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001574 f_ipa_tx(ts_RSL_CHAN_RQD('33'O, 33));
1575 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte618ef642017-12-14 14:58:20 +01001576 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1577
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001578 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte618ef642017-12-14 14:58:20 +01001579
1580 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1581 f_sleep(0.5);
1582
1583 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1584
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001585 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001586}
1587
Harald Welte799c97b2017-12-14 17:50:30 +01001588/* Test for channel exhaustion due to RACH overload */
1589testcase TC_chan_exhaustion() runs on test_CT {
1590 var ASP_RSL_Unitdata rsl_ud;
1591 var integer i;
1592 var integer chreq_total, chreq_nochan;
1593
Harald Welte89d42e82017-12-17 16:42:41 +01001594 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001595
1596 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1597 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1598
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001599 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001600 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1601 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001602 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001603 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001604 }
1605
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001606 IPA_RSL[0][0].clear;
Harald Welte799c97b2017-12-14 17:50:30 +01001607
Harald Weltedd8cbf32018-01-28 12:07:52 +01001608 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001609 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001610
1611 /* now expect additional channel activations to fail */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001612 f_ipa_tx(ts_RSL_CHAN_RQD('42'O, 42));
Harald Welte799c97b2017-12-14 17:50:30 +01001613
1614 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001615 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001616 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1617 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001618 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001619 var GsmRrMessage rr;
1620 /* match on IMM ASS REJ */
1621 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1622 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1623 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001624 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001625 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1626 chreq_nochan+1);
1627 setverdict(pass);
1628 } else {
1629 repeat;
1630 }
1631 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001632 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte799c97b2017-12-14 17:50:30 +01001633 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001634 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001635}
1636
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001637/* Test channel deactivation due to silence from MS */
1638testcase TC_chan_deact_silence() runs on test_CT {
1639 var RslChannelNr chan_nr;
1640
1641 f_init(1);
1642
1643 /* Request for a dedicated channel */
1644 chan_nr := f_chreq_act_ack('23'O);
1645
1646 /* Wait some time until the channel is released */
1647 f_sleep(2.0);
1648
1649 /* Expect CHANnel RELease */
1650 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001651 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001652 log("Received CHANnel RELease");
1653 setverdict(pass);
1654 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001655 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001656 /* See OS#3709, OsmoBSC should not send Immediate
1657 * Assignment Reject since a dedicated channel was
1658 * already allocated, and Immediate Assignment was
1659 * already sent. */
1660 setverdict(fail, "Unexpected Immediate Assignment!");
1661 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001662 [] IPA_RSL[0][0].receive {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001663 setverdict(fail, "Unexpected RSL message!");
1664 }
1665 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001666 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001667}
1668
Harald Weltecfe2c962017-12-15 12:09:32 +01001669/***********************************************************************
1670 * Assignment Testing
1671 ***********************************************************************/
1672
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001673/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1674 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001675testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001676 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001677
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001678 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1679 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001680 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001681 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001682}
1683
Harald Welte16a4adf2017-12-14 18:54:01 +01001684/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001685testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001686 var BSSAP_N_CONNECT_ind rx_c_ind;
1687 var RSL_Message rx_rsl;
1688 var DchanTuple dt;
1689
Harald Welte89d42e82017-12-17 16:42:41 +01001690 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001691
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001692 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001693 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001694 /* send assignment without AoIP IEs */
1695 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1696 } else {
1697 /* Send assignmetn without CIC in IPA case */
1698 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1699 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1700 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1701 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001702 alt {
1703 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1704 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1705 }
Harald Welte235ebf12017-12-15 14:18:16 +01001706 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001707 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1708 setverdict(pass);
1709 }
1710 [] BSSAP.receive { repeat; }
1711 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001712 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001713 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001714}
1715
Harald Welteed848512018-05-24 22:27:58 +02001716/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001717function f_gen_ass_req(boolean osmux_enabled := false, integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4") return PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001718 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001719 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001720 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001721 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001722 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001723 if (osmux_enabled) {
1724 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1725 } else {
1726 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1727 }
Harald Welteed848512018-05-24 22:27:58 +02001728 } else {
1729 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001730 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001731 }
1732 return ass_cmd;
1733}
1734
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001735function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001736 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001737 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1738 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001739 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001740
1741 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1742 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001743 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1744 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001745 if (ispresent(enc)) {
1746 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001747 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1748 if (ispresent(v_enc.enc_alg_chosen)) {
1749 chosenEncryptionAlgorithm := valueof(
1750 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1751 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1752 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001753 if (ispresent(v_enc.enc_kc128)) {
1754 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1755 }
1756 }
1757
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001758 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001759 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001760 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001761 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1762 cell_id_source := cell_id_source,
1763 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001764 encryptionInformation := encryptionInformation,
1765 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001766 kC128 := kc128,
1767 /* on AoIP, allow "all" codecs (until we add more concise
1768 * tests) */
1769 codecList := ts_BSSMAP_IE_CodecList(
1770 {ts_CodecAMR_F, ts_CodecAMR_H,
1771 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001772 } else {
1773 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001774 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1775 cell_id_source := cell_id_source,
1776 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001777 encryptionInformation := encryptionInformation,
1778 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1779 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001780 }
1781 return ho_req;
1782}
1783
Harald Welteed848512018-05-24 22:27:58 +02001784/* generate an assignment complete template for either AoIP or SCCPlite */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001785function f_gen_exp_compl(integer bssap_idx := 0)
1786runs on MSC_ConnHdlr return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001787 var template PDU_BSSAP exp_compl;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001788 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001789 var template BSSMAP_IE_Osmo_OsmuxCID exp_osmux_cid := omit;
1790 if (g_pars.use_osmux_cn) {
1791 var template (present) INT1 exp_cid := ?;
1792 if (isbound(g_media.mgcp_conn[0].local_osmux_cid) and isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1793 exp_cid := (g_media.mgcp_conn[0].local_osmux_cid, g_media.mgcp_conn[1].local_osmux_cid);
1794 } else if (isbound(g_media.mgcp_conn[0].local_osmux_cid)) {
1795 exp_cid := g_media.mgcp_conn[0].local_osmux_cid;
1796 } else if (isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1797 exp_cid := g_media.mgcp_conn[1].local_osmux_cid;
1798 }
1799 exp_osmux_cid := tr_OsmuxCID(exp_cid);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001800 }
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001801 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, exp_osmux_cid);
Harald Welteed848512018-05-24 22:27:58 +02001802 } else {
1803 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001804 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit, omit);
Harald Welteed848512018-05-24 22:27:58 +02001805 }
1806 return exp_compl;
1807}
1808
Harald Welte235ebf12017-12-15 14:18:16 +01001809/* Run everything required up to sending a caller-specified assignment command and expect response */
1810function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001811runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001812 var BSSAP_N_CONNECT_ind rx_c_ind;
1813 var RSL_Message rx_rsl;
1814 var DchanTuple dt;
1815
Harald Welte89d42e82017-12-17 16:42:41 +01001816 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001817
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001818 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte235ebf12017-12-15 14:18:16 +01001819 /* send assignment without AoIP IEs */
1820 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1821 alt {
1822 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1823 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1824 setverdict(pass);
1825 } else {
1826 setverdict(fail, fail_text);
1827 }
1828 }
1829 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1830 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1831 setverdict(pass);
1832 } else {
1833 setverdict(fail, fail_text);
1834 }
1835 }
1836 [] BSSAP.receive { repeat; }
1837 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001838 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001839}
1840testcase TC_assignment_csd() runs on test_CT {
1841 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001842 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001843 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1844 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001845 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1846 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001847 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001848}
1849
1850testcase TC_assignment_ctm() runs on test_CT {
1851 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001852 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001853 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1854 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001855 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1856 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001857 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001858}
1859
Harald Welte4003d112017-12-09 22:35:39 +01001860type record DchanTuple {
1861 integer sccp_conn_id,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001862 RslChannelNr rsl_chan_nr,
1863 BtsTrxIdx idx
Harald Weltea5d2ab22017-12-09 14:21:42 +01001864}
1865
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001866type record of DchanTuple DchanTuples;
1867
Harald Welted6939652017-12-13 21:02:46 +01001868/* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001869private function f_chreq_act_ack(OCT1 ra := '23'O,
1870 GsmFrameNumber fn := 23,
1871 BtsTrxIdx idx := {0, 0})
Harald Welted6939652017-12-13 21:02:46 +01001872runs on test_CT return RslChannelNr {
1873 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001874 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
1875 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Harald Welted6939652017-12-13 21:02:46 +01001876 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001877 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10), idx);
1878 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Harald Welted6939652017-12-13 21:02:46 +01001879 return chan_nr;
1880}
1881
Harald Welte4003d112017-12-09 22:35:39 +01001882/* helper function to establish a dedicated channel via BTS and MSC */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001883function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1884 BtsTrxIdx idx := {0, 0})
Harald Welte4003d112017-12-09 22:35:39 +01001885runs on test_CT return DchanTuple {
1886 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001887 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001888
Harald Welte4003d112017-12-09 22:35:39 +01001889 /* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001890 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn, idx);
Harald Welte4003d112017-12-09 22:35:39 +01001891
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001892 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3), idx);
Harald Welte4003d112017-12-09 22:35:39 +01001893
1894 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1895 dt.sccp_conn_id := rx_c_ind.connectionId;
1896 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1897
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001898 dt.idx := idx;
Harald Welte4003d112017-12-09 22:35:39 +01001899 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001900}
1901
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001902/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001903function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1904 BtsTrxIdx idx := {0, 0})
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001905runs on test_CT return DchanTuple {
1906 var BSSAP_N_CONNECT_ind rx_c_ind;
1907 var DchanTuple dt;
1908
1909 /* Send CHAN RQD */
1910 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001911 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001912
1913 /* The dyn TS first deactivates PDCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001914 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), idx, Tval := T3101_MAX);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001915 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001916 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001917
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001918 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001919 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1920
1921 /* Now activates the signalling channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001922 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10), idx);
1923 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001924
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001925 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001926
1927 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1928 dt.sccp_conn_id := rx_c_ind.connectionId;
1929 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1930
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001931 dt.idx := idx;
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001932 return dt;
1933}
1934
Harald Welte641fcbe2018-06-14 10:58:35 +02001935/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001936private function f_exp_chan_rel_and_clear(DchanTuple dt)
1937runs on test_CT {
Harald Welte641fcbe2018-06-14 10:58:35 +02001938 var RSL_Message rx_rsl;
1939 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001940 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), dt.idx, Tval := T3101_MAX);
Harald Welte641fcbe2018-06-14 10:58:35 +02001941 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001942 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), dt.idx);
Harald Welte641fcbe2018-06-14 10:58:35 +02001943
1944 /* expect Clear Complete from BSC */
1945 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1946
1947 /* MSC disconnects as instructed. */
1948 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1949}
1950
Harald Welte4003d112017-12-09 22:35:39 +01001951/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1952testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001953 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001954 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001955
Harald Welte89d42e82017-12-17 16:42:41 +01001956 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001957
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001958 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01001959
1960 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001961 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Harald Welte4003d112017-12-09 22:35:39 +01001962
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001963 /* expect Clear Request on MSC side */
1964 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1965
1966 /* Instruct BSC to clear channel */
1967 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1968 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1969
Harald Welte4003d112017-12-09 22:35:39 +01001970 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001971 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001972
1973 /* wait for SCCP emulation to do its job */
1974 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001975
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001976 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001977}
1978
1979/* Test behavior of channel release after CONN FAIL IND from BTS */
1980testcase TC_chan_rel_conn_fail() runs on test_CT {
1981 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001982 var DchanTuple dt;
1983
Harald Welte89d42e82017-12-17 16:42:41 +01001984 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001985
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01001986 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01001987
Vadim Yanitskiy01d0a902022-12-14 22:41:42 +07001988 /* Sending CONN FAIL IND immediately may trigger a race condition.
1989 * Give the BSC some time to process a new SCCP connection (OS#5823). */
1990 f_sleep(0.2);
1991
Harald Welte4003d112017-12-09 22:35:39 +01001992 /* simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001993 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001994 /* TODO: different cause values? */
1995
Harald Welte4003d112017-12-09 22:35:39 +01001996 /* expect Clear Request from BSC */
1997 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1998
1999 /* Instruct BSC to clear channel */
2000 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
2001 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2002
Harald Welte6ff76ea2018-01-28 13:08:01 +01002003 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002004 f_exp_chan_rel_and_clear(dt);
Harald Welte4003d112017-12-09 22:35:39 +01002005
2006 /* wait for SCCP emulation to do its job */
2007 f_sleep(1.0);
2008
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002009 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002010}
2011
Harald Welte99f3ca02018-06-14 13:40:29 +02002012/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
2013/* See also https://www.osmocom.org/issues/3182 */
2014testcase TC_early_conn_fail() runs on test_CT {
2015 var RSL_Message rx_rsl;
2016 var DchanTuple dt;
2017
2018 f_init(1);
2019
2020 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02002021 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02002022
2023 /* BTS->BSC: simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002024 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002025
2026 /* BTS->BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002027 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002028
2029 /* BTS<-BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002030 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002031
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002032 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002033}
2034
2035/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
2036/* See also https://www.osmocom.org/issues/3182 */
2037testcase TC_late_conn_fail() runs on test_CT {
2038 var RSL_Message rx_rsl;
2039 var DchanTuple dt;
2040
2041 f_init(1);
2042
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002043 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99f3ca02018-06-14 13:40:29 +02002044
2045 /* BSC<-MSC: Instruct BSC to clear connection */
2046 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
2047
2048 /* BTS->BSC: expect BSC to deactivate SACCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002049 rx_rsl := f_exp_ipa_rx(tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002050
2051 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002052 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002053
2054 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002055 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002056 /* BTS->BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002057 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002058
2059 /* BSC->MSC: expect Clear Complete from BSC */
2060 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2061
2062 /* BSC<-MSC: MSC disconnects as requested. */
2063 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2064
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002065 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002066}
2067
Oliver Smithaf03bef2021-08-24 15:34:51 +02002068private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
2069 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
2070 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2071
2072 f_statsd_reset();
2073
2074 /* Establish SDCCH */
2075 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
2076 f_establish_fully(ass_cmd, exp_fail);
2077
2078 /* Expect stats to be 0 */
2079 var StatsDExpects expect := {
2080 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
2081 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
2082 };
2083 f_statsd_expect(expect);
2084
2085 /* Simulate CONN FAIL IND on SDCCH */
2086 RSL.send(ts_ASP_RSL_UD(
2087 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2088 IPAC_PROTO_RSL_TRX0));
2089
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002090 f_sleep(1.0);
2091
Oliver Smithaf03bef2021-08-24 15:34:51 +02002092 /* Expect stats to be 1 */
2093 expect := {
2094 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2095 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2096 };
2097 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002098 BSSAP.receive(tr_BSSMAP_ClearRequest);
2099 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002100}
2101testcase TC_stats_conn_fail() runs on test_CT {
2102 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2103 var MSC_ConnHdlr vc_conn;
2104
2105 f_init(1, true);
2106 f_sleep(1.0);
2107
2108 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2109 vc_conn.done;
2110
2111 f_shutdown_helper();
2112}
2113
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002114function f_expect_chan_rel(RslChannelNr rsl_chan_nr,
2115 BtsTrxIdx idx := {0, 0},
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002116 boolean expect_deact_sacch := true,
2117 boolean expect_rr_chan_rel := true,
2118 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002119 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002120 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002121 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002122 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002123
2124 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002125 var boolean got_deact_sacch := false;
2126 var boolean got_rr_chan_rel := false;
2127 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002128 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002129 var RSL_IE_Body l3_ie;
2130 var PDU_ML3_NW_MS l3;
2131 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002132 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2133 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002134 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002135 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002136 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002137 repeat;
2138 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002139 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) -> value ud {
Harald Welte99787102019-02-04 10:41:36 +01002140 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002141
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002142 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2143 setverdict(fail, "cannot find L3");
2144 mtc.stop;
2145 }
2146 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2147
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002148 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002149 var CellSelIndValue cells := dec_CellSelIndValue(
2150 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2151
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002152 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2153 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002154 setverdict(pass);
2155 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002156 log("EXPECTED CELLS: ", expect_cells);
2157 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002158 }
2159 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002160
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002161 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2162 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2163 if (match(got_cause, expect_rr_cause)) {
2164 setverdict(pass);
2165 } else {
2166 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2167 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002168 }
Harald Welte99787102019-02-04 10:41:36 +01002169 repeat;
2170 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002171 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002172 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002173 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002174 if (handle_rll_rel) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002175 f_ipa_tx(ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002176 }
Harald Welte91d54a52018-01-28 15:35:07 +01002177 repeat;
2178 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002179 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002180 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002181 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
Harald Welte91d54a52018-01-28 15:35:07 +01002182 }
2183 /* ignore any user data */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002184 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002185 repeat;
2186 }
2187 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002188
2189 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2190 " got_rll_rel_req=", got_rll_rel_req);
2191
2192 if (expect_deact_sacch != got_deact_sacch) {
2193 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2194 }
2195 if (expect_rr_chan_rel != got_rr_chan_rel) {
2196 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2197 }
2198 if (expect_rll_rel_req != got_rll_rel_req) {
2199 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2200 }
Harald Welte91d54a52018-01-28 15:35:07 +01002201}
2202
Harald Welte4003d112017-12-09 22:35:39 +01002203/* Test behavior of channel release after hard Clear Command from MSC */
2204testcase TC_chan_rel_hard_clear() runs on test_CT {
2205 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002206 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002207
Harald Welte89d42e82017-12-17 16:42:41 +01002208 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002209
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002210 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte4003d112017-12-09 22:35:39 +01002211
2212 /* Instruct BSC to clear channel */
2213 var BssmapCause cause := 0;
2214 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2215
2216 /* expect Clear Complete from BSC on A */
2217 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2218 /* release the SCCP connection */
2219 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2220 }
2221
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002222 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002223 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002224}
2225
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002226function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2227 var BSSAP_N_DATA_ind rx_di;
2228 var DchanTuple dt;
2229
2230 f_init(1);
2231
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002232 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002233 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2234 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2235 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2236
2237 /* Instruct BSC to clear channel */
2238 var BssmapCause cause := 0;
2239 if (tx_csfb_ind) {
2240 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2241 } else {
2242 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2243 }
2244
2245 /* expect Clear Complete from BSC on A */
2246 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2247 /* release the SCCP connection */
2248 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2249 }
2250
2251 /* 1 neighbor is added by default in osmo-bts.cfg and
2252 SystemInformationConfig_default, use that: */
2253 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2254
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002255 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002256 f_shutdown_helper();
2257}
2258
2259/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2260 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2261 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2262 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2263 Indicator or not shouldn't matter at all. */
2264testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2265 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2266}
2267
2268/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2269 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2270 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2271 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2272testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2273 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2274}
2275
2276/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2277 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2278 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2279 CSFB Indicator should not be used anymore, and hence, there should be no
2280 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2281 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002282testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2283 var BSSAP_N_DATA_ind rx_di;
2284 var DchanTuple dt;
2285
2286 f_init(1);
2287
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002288 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte99787102019-02-04 10:41:36 +01002289
2290 /* Instruct BSC to clear channel */
2291 var BssmapCause cause := 0;
2292 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2293
2294 /* expect Clear Complete from BSC on A */
2295 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2296 /* release the SCCP connection */
2297 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2298 }
2299
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002300 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002301 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002302}
2303
Harald Welted8c36cd2017-12-09 23:05:31 +01002304/* Test behavior of channel release after hard RLSD from MSC */
2305testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002306 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002307
Harald Welte89d42e82017-12-17 16:42:41 +01002308 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002309
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002310 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welted8c36cd2017-12-09 23:05:31 +01002311
2312 /* release the SCCP connection */
2313 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2314
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002315 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002316 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002317}
2318
Harald Welte550daf92018-06-11 19:22:13 +02002319/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2320testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2321 var DchanTuple dt;
2322
2323 f_init(1);
2324
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002325 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte550daf92018-06-11 19:22:13 +02002326
2327 /* release the SCCP connection */
2328 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2329
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002330 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002331 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002332}
2333
Harald Welte85804d42017-12-10 14:11:58 +01002334/* Test behavior of channel release after BSSMAP RESET from MSC */
2335testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002336 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002337
Harald Welte89d42e82017-12-17 16:42:41 +01002338 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002339
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002340 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Harald Welte85804d42017-12-10 14:11:58 +01002341
2342 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002343 IPA_RSL[0][0].clear;
Harald Welte85804d42017-12-10 14:11:58 +01002344
2345 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002346 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled_cn)));
Harald Welte85804d42017-12-10 14:11:58 +01002347 interleave {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002348 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) { }
Harald Welte85804d42017-12-10 14:11:58 +01002349 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2350 }
2351
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002352 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002353 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002354}
2355
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002356/* Verify T(iar) triggers and releases the channel */
2357testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2358 var DchanTuple dt;
2359
2360 /* Set T(iar) in BSC low enough that it will trigger before other side
2361 has time to keep alive with a T(ias). Keep recommended ratio of
2362 T(iar) >= T(ias)*2 */
2363 g_bsc_sccp_timer_ias := 2;
2364 g_bsc_sccp_timer_iar := 5;
2365
2366 f_init(1);
2367
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002368 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002369 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002370 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002371}
2372
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002373private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2374 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002375runs on test_CT
2376{
2377 var DchanTuple dt;
2378
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002379 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002380 var BssmapCause cause := 0;
2381 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2382 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2383 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2384 }
2385
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002386 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_rr_cause := expect_rr_cause);
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002387}
2388
2389/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2390testcase TC_chan_rel_rr_cause() runs on test_CT {
2391 f_init(1);
2392
2393 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2394 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2395 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2396 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2397 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2398 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002399
2400 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002401}
2402
Harald Welte5cd20ed2017-12-13 21:03:20 +01002403/* Test behavior if RSL EST IND for non-active channel */
2404testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2405 timer T := 2.0;
2406
Harald Welte89d42e82017-12-17 16:42:41 +01002407 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002408
Harald Welte5cd20ed2017-12-13 21:03:20 +01002409 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002410 var octetstring l3_payload := gen_l3_valid_payload();
2411 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002412
2413 T.start;
2414 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002415 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002416 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2417 }
2418 [] BSSAP.receive {}
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002419 [] IPA_RSL[0][0].receive {}
Harald Welte5cd20ed2017-12-13 21:03:20 +01002420 [] T.timeout {}
2421 }
2422
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002423 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002424}
2425
2426/* Test behavior if RSL EST IND for invalid SAPI */
2427testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2428 var RslChannelNr chan_nr;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002429 var octetstring l3_payload;
Harald Welte5cd20ed2017-12-13 21:03:20 +01002430
Harald Welte89d42e82017-12-17 16:42:41 +01002431 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002432
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002433 chan_nr := f_chreq_act_ack();
2434 l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002435
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002436 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002437
2438 timer T := 2.0;
2439 T.start;
2440 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002441 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002442 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2443 }
2444 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002445 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002446 [] T.timeout {}
2447 }
2448
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002449 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002450}
2451
2452/* Test behavior if RSL EST IND for invalid SAPI */
2453testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2454 timer T := 2.0;
2455
Harald Welte89d42e82017-12-17 16:42:41 +01002456 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002457
2458 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002459 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002460
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002461 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002462
2463 T.start;
2464 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002465 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002466 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2467 }
2468 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002469 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002470 [] T.timeout {}
2471 }
2472
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002473 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002474}
2475
2476/* Test behavior if RSL EST IND for invalid SACCH */
2477testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2478 timer T := 2.0;
2479
Harald Welte89d42e82017-12-17 16:42:41 +01002480 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002481
2482 var RslChannelNr chan_nr := f_chreq_act_ack();
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002483 var octetstring l3_payload := gen_l3_valid_payload();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002484
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002485 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3_payload));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002486
2487 T.start;
2488 alt {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002489 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) {
Harald Welte5cd20ed2017-12-13 21:03:20 +01002490 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2491 }
2492 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002493 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002494 [] T.timeout {}
2495 }
2496
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002497 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002498}
2499
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002500/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2501private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2502 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2503 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2504
2505 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2506 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2507
2508 f_establish_fully(ass_cmd, exp_compl);
2509
2510 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2511 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2512 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2513 BSSAP.receive(PDU_BSSAP:{
2514 discriminator := '1'B,
2515 spare := '0000000'B,
2516 dlci := 'C3'O,
2517 lengthIndicator := ?,
2518 pdu := { dtap := '0904'O }
2519 });
2520
2521 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2522 for (var integer i := 0; i < 32; i := i + 1) {
2523 var octetstring l3 := '09'O & f_rnd_octstring(14);
2524 var template (value) RslLinkId link_id;
2525 var template (value) OCT1 dlci;
2526
2527 if (i mod 2 == 0) {
2528 /* SAPI0 on FACCH or SDCCH */
2529 link_id := ts_RslLinkID_DCCH(0);
2530 dlci := '80'O;
2531 } else {
2532 /* SAPI3 on SACCH */
2533 link_id := ts_RslLinkID_SACCH(3);
2534 dlci := 'C3'O;
2535 }
2536
2537 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002538 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002539 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002540 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002541 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002542 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002543}
2544testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2545 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2546 var MSC_ConnHdlr vc_conn;
2547
2548 f_init(1, true);
2549 f_sleep(1.0);
2550
2551 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2552 vc_conn.done;
2553
2554 f_shutdown_helper();
2555}
2556
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002557private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002558 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002559 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002560 float T_val := 2.0)
2561runs on test_CT {
2562 var BSSAP_N_DATA_ind rx_di;
2563 timer T;
2564
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002565 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2566 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002567
2568 T.start(T_val);
2569 alt {
2570 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2571 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2572 if (not match(rx_cause, tr_cause)) {
2573 setverdict(fail, "Rx unexpected Cause IE: ",
2574 rx_cause, " vs expected ", tr_cause);
2575 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002576
2577 /* Who ever on the earth decided to define this field as two separate bits?!? */
2578 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2579 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2580 if (not match(rx_cc, cc)) {
2581 setverdict(fail, "Rx unexpected Control Channel type: ",
2582 rx_cc, " vs expected ", cc);
2583 }
2584
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002585 setverdict(pass);
2586 }
2587 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2588 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2589 }
2590 [] T.timeout {
2591 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2592 }
2593 }
2594}
2595
2596/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2597testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002598 var RSL_Message rx_rsl;
2599 var DchanTuple dt;
2600
2601 f_init(1);
2602
2603 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002604 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002605
2606 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002607 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002608 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002609 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002610
2611 /* MS sends unexpected RELease INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002612 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002613 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2614 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2615
2616 /* Clean up the connection */
2617 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002618 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002619
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002620 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002621}
2622
2623/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2624testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002625 var RSL_Message rx_rsl;
2626 var DchanTuple dt;
2627
2628 f_init(1);
2629
2630 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002631 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002632
2633 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002634 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002635 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002636 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002637
2638 /* BTS sends unexpected ERROR INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002639 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002640 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2641 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2642
2643 /* Clean up the connection */
2644 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002645 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002646
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002647 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002648}
2649
2650/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2651testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002652 var RSL_Message rx_rsl;
2653 var DchanTuple dt;
2654
2655 f_init(1);
2656
2657 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002658 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002659
2660 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002661 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002662 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002663 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002664
2665 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2666 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2667
2668 /* Clean up the connection */
2669 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002670 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002671
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002672 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002673}
2674
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002675/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2676testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002677 var RSL_Message rx_rsl;
2678 var DchanTuple dt;
2679
2680 f_init(1);
2681
2682 /* MS establishes a SAPI=0 link on DCCH */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002683 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002684
2685 /* MSC sends some data on (not yet established) SAPI=3 link */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002686 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(gen_l3_valid_payload(), '03'O)));
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002687 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002688 rx_rsl := f_exp_ipa_rx(tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002689
2690 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002691 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002692 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002693
2694 /* Clean up the connection */
2695 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002696 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002697
2698 f_shutdown_helper();
2699}
2700
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002701testcase TC_si_default() runs on test_CT {
2702 f_init(0);
2703 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002704 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002705}
Harald Welte4003d112017-12-09 22:35:39 +01002706
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002707/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2708 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2709private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2710{
2711 select (earfcn_index) {
2712 case (0) {
2713 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2714 return 111;
2715 }
2716 case (1) {
2717 return 1;
2718 }
2719 case (2) {
2720 return 0;
2721 }
2722 case (3) {
2723 return 65535;
2724 }
2725 case else {
2726 return 23 * (earfcn_index - 3);
2727 }
2728 }
2729}
2730
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002731function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2732 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002733
2734 f_init(0);
2735
2736 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2737 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002738 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2739 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002740 }
2741
2742 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2743
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002744 if (not istemplatekind(expect_cells, "omit")) {
2745 /* Also check that RR Channel Release contains these EARFCNs.
2746 * (copied code from TC_chan_rel_hard_clear_csfb) */
2747 var BSSAP_N_DATA_ind rx_di;
2748 var DchanTuple dt;
2749
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01002750 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002751 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2752 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2753 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002754
2755 /* Instruct BSC to clear channel */
2756 var BssmapCause cause := 0;
2757 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2758
2759 /* expect Clear Complete from BSC on A */
2760 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2761 /* release the SCCP connection */
2762 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2763 }
2764
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002765 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002766 }
2767
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002768 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002769 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list del earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002770 }
2771}
2772
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002773private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2774{
2775 var template SI2quaterRestOctetsList si2quater := {};
2776 var integer si2quater_count := (count + 2) / 3;
2777
2778 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002779 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002780 var integer index := i / 3;
2781 var integer earfcn_index := i mod 3;
2782 if (index >= lengthof(si2quater)) {
2783 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2784 }
2785 si2quater[index].rel_additions.rel5.rel6.rel7.rel8.prio_eutran_params_desc.desc.eutran_params_desc.desc.repeated_neigh_cells[0].cell_desc_list[earfcn_index] := tr_EUTRAN_CellDesc_default(e_arfcn := earfcn);
2786 }
2787
2788 return si2quater;
2789}
2790
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002791private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2792{
2793 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2794
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002795 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002796 for (var integer i := 0; i < count; i := i + 1) {
2797 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002798 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002799 }
2800
2801 return tr_CellSelIndValue_EUTRAN(cells);
2802}
2803
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002804private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2805{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002806 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002807 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002808 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2809 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002810}
2811
2812testcase TC_si2quater_2_earfcns() runs on test_CT {
2813 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002814 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002815}
2816
2817testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002818 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002819 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002820}
2821
2822testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002823 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002824 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002825}
2826
2827testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002828 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002829 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002830}
2831
2832testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002833 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002834 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002835}
2836
2837testcase TC_si2quater_12_earfcns() runs on test_CT {
2838 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002839 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002840}
2841
2842testcase TC_si2quater_23_earfcns() runs on test_CT {
2843 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002844 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002845}
2846
2847testcase TC_si2quater_32_earfcns() runs on test_CT {
2848 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002849 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002850}
2851
2852testcase TC_si2quater_33_earfcns() runs on test_CT {
2853 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002854 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002855}
2856
2857testcase TC_si2quater_42_earfcns() runs on test_CT {
2858 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002859 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002860}
2861
2862testcase TC_si2quater_48_earfcns() runs on test_CT {
2863 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002864 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002865}
2866
2867/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2868 * 48 EARFCNs. */
2869testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002870 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002871 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2872 f_init(0);
2873
2874 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002875 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2876 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002877 }
2878
2879 /* The 49th EARFCN no longer fits, expect VTY error */
2880 f_vty_enter_cfg_bts(BSCVTY, 0);
2881 var charstring vty_error;
2882 vty_error := f_vty_transceive_ret(BSCVTY,
2883 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2884 f_vty_transceive(BSCVTY, "end");
2885
2886 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2887 log("Got expected VTY error: ", vty_error);
2888 setverdict(pass);
2889 } else {
2890 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2891 }
2892
2893 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2894
2895 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002896 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list del earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002897 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002898 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002899}
2900
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002901private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2902{
2903 var uint8_t count := 0;
2904 for (var integer i := 5; i < 16; i := i + 1) {
2905 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2906 count := count + 1;
2907 }
2908 }
2909 return count;
2910}
2911
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002912private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2913{
2914 var ASP_RSL_Unitdata rx_rsl_ud;
2915 var SystemInformationType1 last_si1;
2916
2917 timer T := 30.0;
2918 T.start;
2919 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002920 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2921 tr_RSL_BCCH_INFO,
2922 tr_RSL_NO_SACCH_FILL,
2923 tr_RSL_SACCH_FILL))) -> value rx_rsl_ud {
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002924 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2925 if (g_system_information[rsl_idx].si1 == omit) {
2926 repeat;
2927 }
2928 last_si1 := g_system_information[rsl_idx].si1;
2929 g_system_information[rsl_idx].si1 := omit;
2930 T.stop;
2931 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002932 [] IPA_RSL[rsl_idx][0].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002933 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2934 }
2935 return last_si1;
2936}
2937
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002938/* verify ACC rotate feature */
2939testcase TC_si_acc_rotate() runs on test_CT {
2940 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002941 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002942 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002943 var uint8_t count;
2944 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2945
2946 f_init(0, guard_timeout := 60.0);
2947
2948 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2949 "access-control-class-rotate 3",
2950 "access-control-class-rotate-quantum 1"});
2951
2952 /* Init and get first sysinfo */
2953 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2954
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002955 for (var integer i:= 0; i < 20; i := i + 1) {
2956 last_si1 := f_recv_next_si1(0);
2957 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002958 count := f_acc09_count_allowed(acc);
2959 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2960
2961 if (count != 3) {
2962 log("RSL: EXPECTED SI ACC len=3");
2963 setverdict(fail, "received SI does not match expectations");
2964 break;
2965 }
2966
2967 for (var integer j := 0; j < 10; j := j + 1) {
2968 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2969 times_allowed[j] := times_allowed[j] + 1;
2970 }
2971 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002972 }
2973
2974 for (var integer j := 0; j < 10; j := j + 1) {
2975 log("ACC", j, " allowed ", times_allowed[j], " times" );
2976 if (j != 5 and times_allowed[j] < 3) {
2977 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2978 } else if (j == 5 and times_allowed[j] > 0) {
2979 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2980 }
2981 }
2982
2983 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2984 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002985 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002986}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002987
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002988/* verify ACC startup ramp+rotate feature */
2989testcase TC_si_acc_ramp_rotate() runs on test_CT {
2990 var template SystemInformationConfig sic := SystemInformationConfig_default;
2991 var SystemInformationType1 last_si1;
2992 var AccessControlClass acc;
2993 var ASP_RSL_Unitdata rx_rsl_ud;
2994 var uint8_t count;
2995 var uint8_t prev_count;
2996 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2997
2998 f_init(0, guard_timeout := 80.0);
2999
3000 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
3001 "access-control-class-rotate 0",
3002 "access-control-class-rotate-quantum 1",
3003 "access-control-class-ramping",
3004 "access-control-class-ramping-step-interval 5",
3005 "access-control-class-ramping-step-size 5"});
3006
3007 /* Init and get first sysinfo */
3008 f_init_bts_and_check_sysinfo(0, expect_si := ?);
3009 last_si1 := g_system_information[0].si1;
3010 acc := last_si1.rach_control.acc;
3011 count := f_acc09_count_allowed(acc);
3012 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
3013 while (count > 0) {
3014 last_si1 := f_recv_next_si1(0);
3015 acc := last_si1.rach_control.acc;
3016 count := f_acc09_count_allowed(acc);
3017 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
3018 }
3019
3020 /* Increase adm subset size, we should see ramping start up */
3021 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
3022 prev_count := 0;
3023 while (true) {
3024 last_si1 := f_recv_next_si1(0);
3025 acc := last_si1.rach_control.acc;
3026 count := f_acc09_count_allowed(acc);
3027 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
3028
3029 if (prev_count > count) {
3030 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
3031 break;
3032 }
3033
3034 if (count == 9) {
3035 break; /* Maximum reached (10 - 1 perm barred), done here */
3036 }
3037
3038 prev_count := count;
3039 }
3040
3041 setverdict(pass);
3042
3043 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
3044 "rach access-control-class 4 allowed",
3045 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003046 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003047}
3048
Harald Welte4003d112017-12-09 22:35:39 +01003049testcase TC_ctrl_msc_connection_status() runs on test_CT {
3050 var charstring ctrl_resp;
3051
Harald Welte89d42e82017-12-17 16:42:41 +01003052 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003053
3054 /* See https://osmocom.org/issues/2729 */
3055 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003056 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01003057}
3058
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003059testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3060 var charstring ctrl_resp;
3061
3062 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003063
3064 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003065 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003066}
3067
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003068/* Verify correct stats on the number of configured and connected MSCs */
3069private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3070 g_pars := f_gen_test_hdlr_pars();
3071 var StatsDExpects expect := {
3072 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3073 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3074 };
3075 f_statsd_expect(expect);
3076}
3077
3078private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3079{
3080 var MSC_ConnHdlr vc_conn;
3081
3082 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3083 f_sleep(1.0);
3084 vc_conn := f_start_handler(tc_fn);
3085 vc_conn.done;
3086
3087 /* Also verify stat exposed on CTRL interface */
3088 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3089 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3090
3091 f_shutdown_helper();
3092}
3093
3094/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3095private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3096 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3097}
3098testcase TC_stat_num_msc_connected_1() runs on test_CT {
3099 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3100}
3101
3102/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3103private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3104 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3105}
3106testcase TC_stat_num_msc_connected_2() runs on test_CT {
3107 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3108}
3109
3110/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3111private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3112 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3113}
3114testcase TC_stat_num_msc_connected_3() runs on test_CT {
3115 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3116}
3117
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003118/* Verify correct stats on the number of configured and connected MSCs */
3119private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003120 var integer num_trx_connected := 0;
3121 var integer num_trx_total := 0;
3122
3123 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3124 var integer trx_num := c_BtsParams[i].trx_num;
3125 num_trx_total := num_trx_total + trx_num;
3126 if (i < expect_num_bts_connected) {
3127 num_trx_connected := num_trx_connected + trx_num;
3128 }
3129 }
3130
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003131 var StatsDExpects expect := {
3132 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3133 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3134 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003135 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := num_trx_connected, max := num_trx_connected },
3136 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := num_trx_total, max := num_trx_total }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003137 };
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003138
3139 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003140 f_statsd_expect(expect);
3141}
3142
3143private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003144 var integer num_trx_connected := 0;
3145 var integer num_trx_total := 0;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003146 var MSC_ConnHdlr vc_conn;
3147
3148 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3149 f_sleep(1.0);
3150 vc_conn := f_start_handler(tc_fn);
3151 vc_conn.done;
3152
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003153 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3154 var integer trx_num := c_BtsParams[i].trx_num;
3155 num_trx_total := num_trx_total + trx_num;
3156 if (i < nr_bts) {
3157 num_trx_connected := num_trx_connected + trx_num;
3158 }
3159 }
3160
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003161 /* Also verify stat exposed on CTRL interface */
3162 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3163 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003164 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(num_trx_connected));
3165 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(num_trx_total));
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003166
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003167 /* Verify rf_states exposed on CTRL interface */
3168 var charstring expect_net_rf_states := "";
3169 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003170 var charstring expect_bts_rf_states := "";
3171
3172 for (var integer j := 0; j < c_BtsParams[i].trx_num; j := j + 1) {
3173 expect_bts_rf_states := expect_bts_rf_states &
3174 int2str(i) & "," & int2str(j) & ",";
3175 if (i < NUM_BTS) {
3176 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3177 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3178 } else {
3179 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3180 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3181 }
3182 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3183 expect_bts_rf_states := expect_bts_rf_states & "on,";
3184 if (i < nr_bts) {
3185 /* For BTS where RSL is connected, the RSL state will be "up" */
3186 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3187 } else {
3188 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3189 }
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003190 }
3191
3192 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3193 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3194 }
3195 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3196
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003197 f_shutdown_helper();
3198}
3199
3200/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3201private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3202 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3203}
3204testcase TC_stat_num_bts_connected_1() runs on test_CT {
3205 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3206}
3207
3208/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3209private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3210 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3211}
3212testcase TC_stat_num_bts_connected_2() runs on test_CT {
3213 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3214}
3215
3216/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3217private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3218 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3219}
3220testcase TC_stat_num_bts_connected_3() runs on test_CT {
3221 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3222}
3223
Harald Welte4003d112017-12-09 22:35:39 +01003224testcase TC_ctrl() runs on test_CT {
3225 var charstring ctrl_resp;
3226
Harald Welte89d42e82017-12-17 16:42:41 +01003227 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003228
3229 /* all below values must match the osmo-bsc.cfg config file used */
3230
Harald Welte6a129692018-03-17 17:30:14 +01003231 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3232 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003233 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003234
3235 var integer bts_nr := 0;
3236 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3237 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3238 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3239 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3240 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3241 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3242 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3243
3244 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3245 f_sleep(2.0);
3246 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3247 setverdict(fail, "oml-uptime not incrementing as expected");
3248 }
3249 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3250
3251 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3252
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003253 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003254}
3255
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003256/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3257 "location-state" over the SCCPlite IPA conn */
3258testcase TC_ctrl_location() runs on test_CT {
3259 var MSC_ConnHdlr vc_conn;
3260 var integer bts_nr := 0;
3261
3262 f_init(1, true);
3263 f_sleep(1.0);
3264
3265 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3266 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3267 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3268
3269 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3270 f_sleep(2.0);
3271
3272 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3273 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3274 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3275
3276 /* should match the one from config */
3277 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3278
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003279 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003280}
3281
Harald Welte6f521d82017-12-11 19:52:02 +01003282
3283/***********************************************************************
3284 * Paging Testing
3285 ***********************************************************************/
3286
3287type record Cell_Identity {
3288 GsmMcc mcc,
3289 GsmMnc mnc,
3290 GsmLac lac,
3291 GsmCellId ci
3292};
Harald Welte24135bd2018-03-17 19:27:53 +01003293private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003294private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003295
Harald Welte5d1a2202017-12-13 19:51:29 +01003296type set of integer BtsIdList;
3297
3298private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3299 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3300 if (bts_id == bts_ids[j]) {
3301 return true;
3302 }
3303 }
3304 return false;
3305}
Harald Welte6f521d82017-12-11 19:52:02 +01003306
3307/* core paging test helper function; used by most paging test cases */
3308private function f_pageing_helper(hexstring imsi,
3309 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003310 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003311 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003312 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003313{
3314 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003315 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003316 var RSL_Message rx_rsl;
3317 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003318 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003319
3320 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003321
3322 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003323 for (i := 0; i < NUM_BTS; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003324 IPA_RSL[i][0].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003325 }
Harald Welte6f521d82017-12-11 19:52:02 +01003326
3327 if (isvalue(rsl_chneed)) {
3328 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3329 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3330 } else {
3331 bssmap_chneed := omit;
3332 }
3333
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003334 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3335 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003336
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003337 if (not istemplatekind(tmsi, "omit")) {
3338 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003339 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003340 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003341 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003342
Harald Welte5d1a2202017-12-13 19:51:29 +01003343 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003344 rx_rsl := f_exp_ipa_rx(tr_RSL_PAGING_CMD(mi), idx := {bts_ids[i], 0});
Harald Welte5d1a2202017-12-13 19:51:29 +01003345 /* check channel type, paging group */
3346 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3347 setverdict(fail, "Paging for wrong paging group");
3348 }
3349 if (ispresent(rsl_chneed) and
3350 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3351 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3352 }
Harald Welte6f521d82017-12-11 19:52:02 +01003353 }
Harald Welte2fccd982018-01-31 15:48:19 +01003354 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003355 /* do a quick check on all not-included BTSs if they received paging */
3356 for (i := 0; i < NUM_BTS; i := i + 1) {
3357 timer T := 0.1;
3358 if (f_bts_in_list(i, bts_ids)) {
3359 continue;
3360 }
3361 T.start;
3362 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003363 [] IPA_RSL[i][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003364 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3365 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003366 [] IPA_RSL[i][0].receive { repeat; }
Harald Welte5d1a2202017-12-13 19:51:29 +01003367 [] T.timeout { }
3368 }
Harald Welte6f521d82017-12-11 19:52:02 +01003369 }
3370
3371 setverdict(pass);
3372}
3373
Harald Welte5d1a2202017-12-13 19:51:29 +01003374const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003375const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003376const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3377const BtsIdList c_BtsId_LAC2 := { 2 };
3378
Harald Welte6f521d82017-12-11 19:52:02 +01003379/* PAGING by IMSI + TMSI */
3380testcase TC_paging_imsi_nochan() runs on test_CT {
3381 var BSSMAP_FIELD_CellIdentificationList cid_list;
3382 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003383 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003384 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003385}
3386
3387/* PAGING by IMSI + TMSI */
3388testcase TC_paging_tmsi_nochan() runs on test_CT {
3389 var BSSMAP_FIELD_CellIdentificationList cid_list;
3390 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003391 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003392 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003393}
3394
3395/* Paging with different "channel needed' values */
3396testcase TC_paging_tmsi_any() runs on test_CT {
3397 var BSSMAP_FIELD_CellIdentificationList cid_list;
3398 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003399 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003400 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003401}
3402testcase TC_paging_tmsi_sdcch() runs on test_CT {
3403 var BSSMAP_FIELD_CellIdentificationList cid_list;
3404 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003405 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003406 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003407}
3408testcase TC_paging_tmsi_tch_f() runs on test_CT {
3409 var BSSMAP_FIELD_CellIdentificationList cid_list;
3410 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003411 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003412 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003413}
3414testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3415 var BSSMAP_FIELD_CellIdentificationList cid_list;
3416 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003417 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003418 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003419}
3420
3421/* Paging by CGI */
3422testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3423 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3424 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003425 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003426 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003427}
3428
3429/* Paging by LAC+CI */
3430testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3431 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3432 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003433 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003434 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003435}
3436
3437/* Paging by CI */
3438testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3439 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3440 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003441 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003442 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003443}
3444
3445/* Paging by LAI */
3446testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3447 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3448 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003449 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003450 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003451}
3452
3453/* Paging by LAC */
3454testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3455 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3456 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003457 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003458 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003459}
3460
3461/* Paging by "all in BSS" */
3462testcase TC_paging_imsi_nochan_all() runs on test_CT {
3463 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3464 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003465 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003466 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003467}
3468
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003469/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003470testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3471 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3472 cid_list := { cIl_PLMN_LAC_RNC := { ts_BSSMAP_CI_PLMN_LAC_RNC(cid.mcc, cid.mnc, cid.lac, 12) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003473 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003474 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003475}
Harald Welte6f521d82017-12-11 19:52:02 +01003476
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003477/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003478testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3479 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3480 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003481 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003482 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003483}
3484
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003485/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003486testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3487 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3488 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003489 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003490 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003491}
3492
Harald Welte6f521d82017-12-11 19:52:02 +01003493/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003494testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3495 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3496 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3497 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003498 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003499}
3500
3501/* Paging on empty list: Verify none of them page */
3502testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3503 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3504 cid_list := { cIl_LAC := { } };
3505 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003506 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003507}
3508
Stefan Sperling049a86e2018-03-20 15:51:00 +01003509/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3510testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3511 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3512 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3513 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3514 f_shutdown_helper();
3515}
3516
Harald Welte6f521d82017-12-11 19:52:02 +01003517/* Verify paging retransmission interval + count */
3518/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003519/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003520
Harald Weltee65d40e2017-12-13 00:09:06 +01003521/* Verify PCH load */
3522testcase TC_paging_imsi_load() runs on test_CT {
3523 var BSSMAP_FIELD_CellIdentificationList cid_list;
3524 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003525 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003526 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003527 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003528
3529 /* tell BSC there is no paging space anymore */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003530 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003531 f_sleep(0.2);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003532 IPA_RSL[0][0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003533
3534 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3535 * there would be 8 retransmissions during 4 seconds */
3536 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003537 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003538 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003539 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003540 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003541 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003542 }
Harald Welte2caa1062018-03-17 18:19:05 +01003543 [] T_retrans.timeout {
3544 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003545 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte2caa1062018-03-17 18:19:05 +01003546 T_retrans.start;
3547 repeat;
3548 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003549 [] T.timeout {
3550 setverdict(pass);
3551 }
3552 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003553
3554 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003555}
3556
Harald Welte235ebf12017-12-15 14:18:16 +01003557/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003558testcase TC_paging_counter() runs on test_CT {
3559 var BSSMAP_FIELD_CellIdentificationList cid_list;
3560 timer T := 4.0;
3561 var integer i;
3562 var integer paging_attempted_bsc;
3563 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003564 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003565 var integer paging_expired_bts[NUM_BTS];
3566 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3567
3568 f_init();
3569
3570 /* read counters before paging */
3571 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003572 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3573 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3574 }
Harald Welte1ff69992017-12-14 12:31:17 +01003575 for (i := 0; i < NUM_BTS; i := i+1) {
3576 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3577 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3578 }
3579
3580 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3581
3582 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3583 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3584 for (i := 0; i < NUM_BTS; i := i+1) {
3585 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3586 paging_attempted_bts[i]+1);
3587 }
3588
3589 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3590 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003591 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3592 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3593 }
Harald Welte1ff69992017-12-14 12:31:17 +01003594 for (i := 0; i < NUM_BTS; i := i+1) {
3595 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3596 paging_expired_bts[i]+1);
3597 }
Harald Welte1ff69992017-12-14 12:31:17 +01003598
Philipp Maier282ca4b2018-02-27 17:17:00 +01003599 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003600}
3601
3602
Harald Welte10985002017-12-12 09:29:15 +01003603/* Verify paging stops after A-RESET */
3604testcase TC_paging_imsi_a_reset() runs on test_CT {
3605 var BSSMAP_FIELD_CellIdentificationList cid_list;
3606 timer T := 3.0;
3607 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003608 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003609
3610 /* Perform a BSSMAP Reset and wait for ACK */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003611 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 +01003612 alt {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003613 [] 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 +01003614 [] BSSAP.receive { repeat; }
3615 }
3616
Daniel Willmanncbef3982018-07-30 09:22:40 +02003617 /* Wait to avoid a possible race condition if a paging message is
3618 * received right before the reset ACK. */
3619 f_sleep(0.2);
3620
Harald Welte10985002017-12-12 09:29:15 +01003621 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003622 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003623 IPA_RSL[i][0].clear;
Philipp Maier1e6b4422018-02-23 14:02:13 +01003624 }
Harald Welte10985002017-12-12 09:29:15 +01003625
3626 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3627 T.start;
3628 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003629 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003630 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003631 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003632 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003633 [] IPA_RSL[1][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003634 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003635 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003636 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003637 [] IPA_RSL[2][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003638 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003639 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003640 }
Harald Welte10985002017-12-12 09:29:15 +01003641 [] T.timeout {
3642 setverdict(pass);
3643 }
3644 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003645
3646 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003647}
Harald Welteae026692017-12-09 01:03:01 +01003648
Philipp Maierf45824a2019-08-14 14:44:10 +02003649/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3650 * paging response we can not know which MSC is in charge, so we will blindly
3651 * pick the first configured MSC. This behavior is required in order to make
3652 * MT-CSFB calls working because in those cases the BSC can not know that the
3653 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3654 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003655 */
3656testcase TC_paging_resp_unsol() runs on test_CT {
3657
3658 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003659 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003660
3661 var BSSAP_N_CONNECT_ind rx_c_ind;
3662 var DchanTuple dt;
3663 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003664 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003665
3666 /* Send CHAN RQD and wait for allocation; acknowledge it */
3667 dt.rsl_chan_nr := f_chreq_act_ack();
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003668 dt.idx := {0, 0};
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003669
3670 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
Pau Espin Pedrole8a51012023-01-03 11:59:59 +01003671 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), rr_pag_resp));
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003672
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003673
Philipp Maierf45824a2019-08-14 14:44:10 +02003674 /* Expevct a CR with a matching Paging response on the A-Interface */
3675 T.start;
3676 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003677 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003678 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003679 dt.sccp_conn_id := rx_c_ind.connectionId;
3680 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003681 }
3682 [] BSSAP.receive {
3683 setverdict(fail, "Received unexpected message on A-Interface!");
3684 }
3685 [] T.timeout {
3686 setverdict(fail, "Received nothing on A-Interface!");
3687 }
3688 }
3689
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003690 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003691 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003692}
3693
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003694/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3695function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003696 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003697 var Hexstrings imsis := {};
3698 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003699 var integer rx_paging_num := 0;
3700 var integer i;
3701 timer T_rx := 60.0;
3702 timer T_load_ind := 1.0;
3703
3704 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003705 imsis := imsis & {f_gen_imsi(i)};
3706 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003707 }
3708
3709 f_init(1, guard_timeout := 100.0);
3710
3711 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003712 IPA_RSL[0][0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003713 if (send_pag_load_ind) {
3714 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003715 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(65535));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003716 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003717
3718 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003719 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003720 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 +02003721 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3722 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003723 }
3724
3725 T_rx.start;
3726 T_load_ind.start;
3727 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003728 [] 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 +02003729 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3730 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3731 var charstring imsi_str := hex2str(imsi_suffix);
3732 var integer imsi_idx := str2int(imsi_str);
3733 if (rx_paging_done[imsi_idx] == false) {
3734 rx_paging_done[imsi_idx] := true;
3735 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003736 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003737 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 +02003738 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003739 }
3740 if (rx_paging_num < num_subscribers) {
3741 repeat;
3742 }
3743 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003744 [] IPA_RSL[0][0].receive { repeat; }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003745 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003746 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3747 if (send_pag_load_ind) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003748 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(40));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003749 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003750 T_load_ind.start;
3751 repeat;
3752 }
3753 [] T_rx.timeout {
3754 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3755 mtc.stop;
3756 }
3757 }
3758
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003759 /* Drop OML connection to have all paging requests flushed: */
3760 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3761
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003762 f_shutdown_helper();
3763}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003764/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3765testcase TC_paging_500req() runs on test_CT {
3766 f_TC_paging_Nreq(500, true);
3767}
3768/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3769 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3770 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3771 * for current config yields ~8req/sec, so 480req/min maximum. */
3772testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3773 f_TC_paging_Nreq(450, false);
3774}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003775
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003776/* Test RSL link drop causes counter increment */
3777testcase TC_rsl_drop_counter() runs on test_CT {
3778 var integer rsl_fail;
3779
Harald Welte89d42e82017-12-17 16:42:41 +01003780 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003781
3782 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3783
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003784 f_ipa_rsl_stop(bts[0][0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003785
3786 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3787
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003788 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003789}
3790
3791/* TODO: Test OML link drop causes counter increment */
3792
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003793/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3794function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003795 var IPA_Client client;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003796 timer T := 10.0;
3797
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003798 client.id := "IPA-BTS0-TRX0-RSL";
3799 client.vc_IPA := IPA_Emulation_CT.create(client.id & "-IPA") alive;
3800 client.ccm_pars := c_IPA_default_ccm_pars;
3801 client.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
3802 client.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003803
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003804 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003805
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003806 f_init_mgcp(0, "VirtMGW");
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003807
3808 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003809 map(client.vc_IPA:IPA_PORT, system:IPA);
3810 connect(client.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0][0]);
3811 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 +01003812
3813 /* wait for IPA OML link to connect and then disconnect */
3814 T.start;
3815 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003816 [] IPA_RSL[0][0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003817 T.stop;
3818 return true;
3819 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003820 [] IPA_RSL[0][0].receive { repeat }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003821 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003822 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003823 }
3824 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003825 return false;
3826}
3827
3828/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3829testcase TC_rsl_unknown_unit_id() runs on test_CT {
3830 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3831 setverdict(pass);
3832 } else {
3833 setverdict(fail, "Timeout RSL waiting for connection to close");
3834 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003835 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003836}
3837
3838
3839/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3840testcase TC_oml_unknown_unit_id() runs on test_CT {
3841 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3842 setverdict(pass);
3843 } else {
3844 setverdict(fail, "Timeout OML waiting for connection to close");
3845 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003846 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003847}
3848
3849
Harald Weltec1a2fff2017-12-17 11:06:19 +01003850/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003851 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003852 ***********************************************************************/
3853
Harald Welte6811d102019-04-14 22:23:14 +02003854import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003855import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003856import from RSL_Emulation all;
3857import from MSC_ConnectionHandler all;
3858
3859type function void_fn(charstring id) runs on MSC_ConnHdlr;
3860
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003861/* helper function to create and connect a MSC_ConnHdlr component
3862 * TODO: allow connecting to TRX1..N, not only TRX0 */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003863private 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 +02003864 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003865 connect(vc_conn:RSL, bts[0][0].rsl.vc_RSL:CLIENT_PT);
3866 connect(vc_conn:RSL_PROC, bts[0][0].rsl.vc_RSL:RSL_PROC);
3867 if (isvalue(bts[1][0])) {
3868 connect(vc_conn:RSL1, bts[1][0].rsl.vc_RSL:CLIENT_PT);
3869 connect(vc_conn:RSL1_PROC, bts[1][0].rsl.vc_RSL:RSL_PROC);
Philipp Maier956a92f2018-02-16 10:58:07 +01003870 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003871 if (isvalue(bts[2][0])) {
3872 connect(vc_conn:RSL2, bts[2][0].rsl.vc_RSL:CLIENT_PT);
3873 connect(vc_conn:RSL2_PROC, bts[2][0].rsl.vc_RSL:RSL_PROC);
Neels Hofmeyr91401012019-07-11 00:42:35 +02003874 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003875 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003876 if (mp_enable_lcs_tests) {
3877 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3878 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3879 }
Daniel Willmannebdecc02020-08-12 15:30:17 +02003880 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003881 connect(vc_conn:MGCP_PROC, vc_MGCP[mgwpool_idx]:MGCP_PROC);
3882 connect(vc_conn:MGCP, vc_MGCP[mgwpool_idx]:MGCP_CLIENT);
3883 connect(vc_conn:MGCP_MULTI, vc_MGCP[mgwpool_idx]:MGCP_CLIENT_MULTI);
Harald Welte336820c2018-05-31 20:34:52 +02003884}
3885
Neels Hofmeyrda436782021-07-20 22:09:06 +02003886function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003887runs on test_CT return MSC_ConnHdlr {
3888 var charstring id := testcasename();
3889 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003890 var integer bssap_idx := 0;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003891 var integer mgwpool_idx := 0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003892 if (isvalue(pars)) {
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003893 var TestHdlrParams pars_val := valueof(pars);
3894 bssap_idx := pars_val.mscpool.bssap_idx;
3895 mgwpool_idx := pars_val.mgwpool_idx;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003896 }
Harald Welte336820c2018-05-31 20:34:52 +02003897 vc_conn := MSC_ConnHdlr.create(id);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003898 f_connect_handler(vc_conn, bssap_idx, mgwpool_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003899 return vc_conn;
3900}
3901
3902function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3903runs on test_CT return MSC_ConnHdlr {
3904 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003905 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003906 return vc_conn;
3907}
3908
Neels Hofmeyrda436782021-07-20 22:09:06 +02003909function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3910runs on test_CT return MSC_ConnHdlr {
3911 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3912}
3913
Harald Weltea0630032018-03-20 21:09:55 +01003914/* first function inside ConnHdlr component; sets g_pars + starts function */
3915private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3916runs on MSC_ConnHdlr {
3917 if (isvalue(pars)) {
3918 g_pars := valueof(pars);
3919 }
3920 fn.apply(id);
3921}
3922
Oliver Smith26a3db72021-07-09 13:51:29 +02003923private function f_vty_encryption_a5(charstring options) runs on test_CT {
3924 f_vty_transceive(BSCVTY, "configure terminal");
3925 f_vty_transceive(BSCVTY, "network");
3926 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3927 f_vty_transceive(BSCVTY, "exit");
3928 f_vty_transceive(BSCVTY, "exit");
3929}
3930
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003931const charstring VTY_A5_DEFAULT := "0 1 3";
3932
Oliver Smith26a3db72021-07-09 13:51:29 +02003933private function f_vty_encryption_a5_reset() runs on test_CT {
3934 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003935 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003936}
3937
Harald Welte3c86ea02018-05-10 22:28:05 +02003938/* Establish signalling channel (non-assignment case) followed by cipher mode */
3939private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003940 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3941 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003942 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003943 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3944 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3945 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3946 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003947
Philipp Maier23000732018-05-18 11:25:37 +02003948 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003949 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003950}
3951testcase TC_ciph_mode_a5_0() runs on test_CT {
3952 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003953 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003954 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3955
3956 f_init(1, true);
3957 f_sleep(1.0);
3958 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3959 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003960 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003961}
3962testcase TC_ciph_mode_a5_1() runs on test_CT {
3963 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003964 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003965 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3966
3967 f_init(1, true);
3968 f_sleep(1.0);
3969 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3970 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003971 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003972}
Oliver Smith50b98122021-07-09 15:00:28 +02003973/* OS#4975: verify that A5/2 is preferred over A5/0 */
3974testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3975 var MSC_ConnHdlr vc_conn;
3976 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3977
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003978 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003979
3980 f_init(1, true);
3981 f_vty_encryption_a5("0 1 2 3");
3982 f_sleep(1.0);
3983 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3984 vc_conn.done;
3985 f_vty_encryption_a5_reset();
3986 f_shutdown_helper();
3987}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003988/* OS#4975: verify that A5/1 is preferred over A5/2 */
3989testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3990 var MSC_ConnHdlr vc_conn;
3991 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3992
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003993 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003994
3995 f_init(1, true);
3996 f_vty_encryption_a5("1 2");
3997 f_sleep(1.0);
3998 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3999 vc_conn.done;
4000 f_vty_encryption_a5_reset();
4001 f_shutdown_helper();
4002}
Harald Welte3c86ea02018-05-10 22:28:05 +02004003testcase TC_ciph_mode_a5_3() runs on test_CT {
4004 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004005 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004006 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
4007
4008 f_init(1, true);
4009 f_sleep(1.0);
4010 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4011 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004012 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004013}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004014/* Establish a Signalling channel with A5/4 encryption. */
4015testcase TC_ciph_mode_a5_4() runs on test_CT {
4016 var MSC_ConnHdlr vc_conn;
4017 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4018 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02004019
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004020 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02004021 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004022 f_sleep(1.0);
4023 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4024 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02004025 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004026 f_shutdown_helper();
4027}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004028/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
4029private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
4030 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4031 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
4032 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4033 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4034
4035 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004036 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004037}
4038testcase TC_assignment_aoip_tla_v6() runs on test_CT {
4039 var MSC_ConnHdlr vc_conn;
4040 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4041
4042 f_init(1, true);
4043 f_sleep(1.0);
4044 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
4045 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004046 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004047}
4048
Harald Welte3c86ea02018-05-10 22:28:05 +02004049
4050/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02004051private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004052 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4053 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004054
Harald Welte552620d2017-12-16 23:21:36 +01004055 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4056 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01004057
Harald Weltea0630032018-03-20 21:09:55 +01004058 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004059 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004060}
Harald Welte552620d2017-12-16 23:21:36 +01004061testcase TC_assignment_fr_a5_0() runs on test_CT {
4062 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004063 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004064 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01004065
Harald Welte89d42e82017-12-17 16:42:41 +01004066 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004067 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004068 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004069 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004070 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004071}
Harald Welte552620d2017-12-16 23:21:36 +01004072testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01004073 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004074 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004075 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004076
Harald Welte89d42e82017-12-17 16:42:41 +01004077 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004078 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004079 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4080 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004081 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02004082}
4083testcase TC_assignment_fr_a5_3() runs on test_CT {
4084 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004085 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004086 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004087
Harald Welte651fcdc2018-05-10 20:23:16 +02004088 f_init(1, true);
4089 f_sleep(1.0);
4090 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004091 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004092 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004093}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004094/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
4095testcase TC_assignment_fr_a5_4() runs on test_CT {
4096 var MSC_ConnHdlr vc_conn;
4097 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4098 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
4099
4100 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004101 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004102 f_sleep(1.0);
4103 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4104 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02004105 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004106 f_shutdown_helper();
4107}
Harald Weltec1a2fff2017-12-17 11:06:19 +01004108
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02004109/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
4110testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
4111 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4112 var MSC_ConnHdlr vc_conn;
4113
4114 f_init(1, true);
4115 f_sleep(1.0);
4116
4117 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4118 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4119 vc_conn.done;
4120 f_shutdown_helper();
4121}
4122
Harald Welte552620d2017-12-16 23:21:36 +01004123/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4124private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004125 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004126 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004127 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004128
4129 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004130 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4131
Harald Weltea0630032018-03-20 21:09:55 +01004132 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004133 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004134}
Harald Welte552620d2017-12-16 23:21:36 +01004135testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4136 var MSC_ConnHdlr vc_conn;
4137
Harald Welte89d42e82017-12-17 16:42:41 +01004138 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004139 f_sleep(1.0);
4140
Harald Welte8863fa12018-05-10 20:15:27 +02004141 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004142 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004143 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004144}
4145
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004146private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4147 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4148 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004149
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004150 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4151 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4152
4153 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4154
4155 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004156
4157 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4158 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4159
4160 f_create_chan_and_exp();
4161 /* we should now have a COMPL_L3 at the MSC */
4162
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004163 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004164 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004165 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004166}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004167testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4168 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004169 var MSC_ConnHdlr vc_conn;
4170
Harald Welte89d42e82017-12-17 16:42:41 +01004171 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004172 f_sleep(1.0);
4173
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004174 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004175 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004176 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004177 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004178}
4179
4180
Harald Welte4532e0a2017-12-23 02:05:44 +01004181private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004182 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004183 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004184 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004185 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004186
4187 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004188 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004189
4190 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004191 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4192 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004193 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4194 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4195 };
4196 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004197 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004198}
4199
4200testcase TC_assignment_sign() runs on test_CT {
4201 var MSC_ConnHdlr vc_conn;
4202
4203 f_init(1, true);
4204 f_sleep(1.0);
4205
Harald Welte8863fa12018-05-10 20:15:27 +02004206 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004207 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004208 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004209}
4210
Harald Welte60aa5762018-03-21 19:33:13 +01004211/***********************************************************************
4212 * Codec (list) testing
4213 ***********************************************************************/
4214
4215/* check if the given rsl_mode is compatible with the a_elem */
4216private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4217return boolean {
4218 select (a_elem.codecType) {
4219 case (GSM_FR) {
4220 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4221 return true;
4222 }
4223 }
4224 case (GSM_HR) {
4225 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4226 return true;
4227 }
4228 }
4229 case (GSM_EFR) {
4230 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4231 return true;
4232 }
4233 }
4234 case (FR_AMR) {
4235 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4236 return true;
4237 }
4238 }
4239 case (HR_AMR) {
4240 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4241 return true;
4242 }
4243 }
4244 case else { }
4245 }
4246 return false;
4247}
4248
4249/* check if the given rsl_mode is compatible with the a_list */
4250private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4251return boolean {
4252 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4253 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4254 return true;
4255 }
4256 }
4257 return false;
4258}
4259
4260/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004261function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004262return BSSMAP_IE_ChannelType {
4263 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4264 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4265 select (a_elem.codecType) {
4266 case (GSM_FR) {
4267 ret.channelRateAndType := ChRate_TCHF;
4268 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4269 }
4270 case (GSM_HR) {
4271 ret.channelRateAndType := ChRate_TCHH;
4272 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4273 }
4274 case (GSM_EFR) {
4275 ret.channelRateAndType := ChRate_TCHF;
4276 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4277 }
4278 case (FR_AMR) {
4279 ret.channelRateAndType := ChRate_TCHF;
4280 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4281 }
4282 case (HR_AMR) {
4283 ret.channelRateAndType := ChRate_TCHH;
4284 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4285 }
4286 case else {
4287 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004288 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004289 }
4290 }
4291 return ret;
4292}
4293
Harald Weltea63b9102018-03-22 20:36:16 +01004294private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4295return template RSL_IE_Body {
4296 var template RSL_IE_Body mode_ie := {
4297 chan_mode := {
4298 len := ?,
4299 reserved := ?,
4300 dtx_d := ?,
4301 dtx_u := ?,
4302 spd_ind := RSL_SPDI_SPEECH,
4303 ch_rate_type := -,
4304 coding_alg_rate := -
4305 }
4306 }
4307
4308 select (a_elem.codecType) {
4309 case (GSM_FR) {
4310 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4311 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4312 }
4313 case (GSM_HR) {
4314 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4315 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4316 }
4317 case (GSM_EFR) {
4318 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4319 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4320 }
4321 case (FR_AMR) {
4322 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4323 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4324 }
4325 case (HR_AMR) {
4326 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4327 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4328 }
4329 }
4330 return mode_ie;
4331}
4332
Harald Welte60aa5762018-03-21 19:33:13 +01004333type record CodecListTest {
4334 BSSMAP_IE_SpeechCodecList codec_list,
4335 charstring id
4336}
4337type record of CodecListTest CodecListTests
4338
4339private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004340 f_assignment_codec(id);
4341}
4342
4343private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02004344 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02004345 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Harald Welte60aa5762018-03-21 19:33:13 +01004346
4347 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004348 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004349 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4350 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4351 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004352 if (isvalue(g_pars.expect_mr_s0_s7)) {
4353 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4354 g_pars.expect_mr_s0_s7;
4355 }
Harald Welte79f3f542018-05-25 20:02:37 +02004356 }
Harald Welte60aa5762018-03-21 19:33:13 +01004357 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4358 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004359 log("expecting ASS COMPL like this: ", exp_compl);
4360
4361 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004362
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004363 if (not g_pars.expect_channel_mode_modify) {
4364 /* Verify that the RSL-side activation actually matches our expectations */
4365 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004366
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004367 var RSL_IE_Body mode_ie;
4368 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4369 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004370 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004371 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004372 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4373 if (not match(mode_ie, t_mode_ie)) {
4374 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4375 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004376 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004377
4378 var RSL_IE_Body mr_conf;
4379 if (g_pars.expect_mr_conf_ie != omit) {
4380 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4381 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4382 mtc.stop;
4383 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004384 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004385
4386 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
Vadim Yanitskiy8b189372022-09-14 17:31:17 +07004387 setverdict(fail, "RSL MR CONFIG IE does not match expectation. ",
4388 "Expected: ", g_pars.expect_mr_conf_ie, ", got: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004389 }
4390 } else {
4391 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4392 log("found RSL MR CONFIG IE: ", mr_conf);
4393 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4394 mtc.stop;
4395 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004396 }
4397 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004398
4399 if (do_perform_clear) {
4400 f_perform_clear();
4401 }
Harald Welte60aa5762018-03-21 19:33:13 +01004402}
4403
Philipp Maierd0e64b02019-03-13 14:15:23 +01004404private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4405
4406 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4407 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4408
4409 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004410 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004411 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4412 }
4413 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4414 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4415 log("expecting ASS FAIL like this: ", exp_fail);
4416
4417 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004418 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004419}
4420
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004421const CounterNameVals counternames_bsc_bts_assignment := {
4422 { "assignment:attempted", 0 },
4423 { "assignment:completed", 0 },
4424 { "assignment:stopped", 0 },
4425 { "assignment:no_channel", 0 },
4426 { "assignment:timeout", 0 },
4427 { "assignment:failed", 0 },
4428 { "assignment:error", 0 }
4429};
4430
4431const CounterNameVals counternames_bts_assignment := {
4432 { "assignment:attempted_sign", 0 },
4433 { "assignment:attempted_speech", 0 },
4434 { "assignment:completed_sign", 0 },
4435 { "assignment:completed_speech", 0 },
4436 { "assignment:stopped_sign", 0 },
4437 { "assignment:stopped_speech", 0 },
4438 { "assignment:no_channel_sign", 0 },
4439 { "assignment:no_channel_speech", 0 },
4440 { "assignment:timeout_sign", 0 },
4441 { "assignment:timeout_speech", 0 },
4442 { "assignment:failed_sign", 0 },
4443 { "assignment:failed_speech", 0 },
4444 { "assignment:error_sign", 0 },
4445 { "assignment:error_speech", 0 }
4446};
4447
4448function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4449 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4450 f_ctrs_bts_init(bts_count, bts_names);
4451 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4452}
4453
Harald Welte60aa5762018-03-21 19:33:13 +01004454testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004455 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004456 var MSC_ConnHdlr vc_conn;
4457
4458 f_init(1, true);
4459 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004460 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004461
4462 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004463 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004464 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004465
4466 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4467 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4468 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4469 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4470 f_ctrs_bts_verify();
4471
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004472 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004473}
4474
4475testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004476 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004477 var MSC_ConnHdlr vc_conn;
4478
4479 f_init(1, true);
4480 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004481 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004482
4483 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004484 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004485 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004486
4487 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4488 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4489 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4490 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4491 f_ctrs_bts_verify();
4492
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004493 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004494}
4495
4496testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004497 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004498 var MSC_ConnHdlr vc_conn;
4499
4500 f_init(1, true);
4501 f_sleep(1.0);
4502
4503 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004504 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004505 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004506 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004507}
4508
Philipp Maierd0e64b02019-03-13 14:15:23 +01004509/* Allow 5,90k only (current default config) */
4510private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004511 f_vty_cfg_msc(BSCVTY, 0, {
4512 "amr-config 12_2k forbidden",
4513 "amr-config 10_2k forbidden",
4514 "amr-config 7_95k forbidden",
4515 "amr-config 7_40k forbidden",
4516 "amr-config 6_70k forbidden",
4517 "amr-config 5_90k allowed",
4518 "amr-config 5_15k forbidden",
4519 "amr-config 4_75k forbidden"
4520 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004521}
4522
4523/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4524 * ("Config-NB-Code = 1") */
4525private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004526 f_vty_cfg_msc(BSCVTY, 0, {
4527 "amr-config 12_2k allowed",
4528 "amr-config 10_2k forbidden",
4529 "amr-config 7_95k forbidden",
4530 "amr-config 7_40k allowed",
4531 "amr-config 6_70k forbidden",
4532 "amr-config 5_90k allowed",
4533 "amr-config 5_15k forbidden",
4534 "amr-config 4_75k allowed"
4535 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004536}
4537
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004538private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4539 var charstring tch;
4540 if (fr) {
4541 tch := "tch-f";
4542 } else {
4543 tch := "tch-h";
4544 }
4545 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4546}
4547
4548/* Set the AMR start-mode for this TCH back to the default configuration. */
4549private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4550 f_vty_amr_start_mode_set(fr, "auto");
4551}
4552
Harald Welte60aa5762018-03-21 19:33:13 +01004553testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004554 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004555 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004556
4557 /* Note: This setups the codec configuration. The parameter payload in
4558 * mr_conf must be consistant with the parameter codecElements in pars
4559 * and also must match the amr-config in osmo-bsc.cfg! */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004560 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004561 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004562 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004563 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004564
Harald Welte60aa5762018-03-21 19:33:13 +01004565 f_init(1, true);
4566 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004567 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004568 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004569
Harald Welte8863fa12018-05-10 20:15:27 +02004570 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004571 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004572
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004573 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4574 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4575 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4576 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4577 f_ctrs_bts_verify();
4578
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004579 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004580 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004581}
4582
4583testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004584 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004585 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004586
4587 /* See note above */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004588 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004589 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004590 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004591 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004592
Harald Welte60aa5762018-03-21 19:33:13 +01004593 f_init(1, true);
4594 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004595 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004596 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004597
Harald Welte8863fa12018-05-10 20:15:27 +02004598 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004599 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004600
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004601 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4602 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4603 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4604 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4605 f_ctrs_bts_verify();
4606
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004607 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004608 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004609}
4610
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004611/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4612testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4613 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4614 var MSC_ConnHdlr vc_conn;
4615
4616 f_init(1, true);
4617 f_sleep(1.0);
4618
4619 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4620 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4621 * expecting a Channel Mode Modify if the channel type is compatible. */
4622 f_disable_all_sdcch();
4623 f_disable_all_tch_h();
4624
4625 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4626 pars.expect_channel_mode_modify := true;
4627 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4628 vc_conn.done;
4629
4630 f_enable_all_sdcch();
4631 f_enable_all_tch();
4632 f_shutdown_helper();
4633}
4634
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004635/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4636testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4637 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4638 var MSC_ConnHdlr vc_conn;
4639
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004640 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4641 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4642 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy36fe9582022-09-14 15:25:04 +07004643 pars.expect_mr_conf_ie := c_mr_conf_5_90;
4644 pars.expect_mr_conf_ie.multirate_cfg.icmi := false; /* expect ICMI=0, smod=00: */
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004645
4646 f_init(1, true);
4647 f_sleep(1.0);
4648
4649 /* First set nonzero start mode bits */
4650 f_vty_amr_start_mode_set(true, "4");
4651 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4652 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4653 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4654 f_vty_amr_start_mode_set(true, "auto");
4655
4656 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4657 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004658
4659 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4660 f_vty_amr_start_mode_set(true, "1");
4661 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004662 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004663}
4664
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004665function f_TC_assignment_codec_amr(boolean fr, RSL_IE_MultirateCfg mr_cfg,
4666 bitstring s8_s0, bitstring exp_s8_s0,
4667 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004668runs on test_CT {
4669
4670 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4671 var MSC_ConnHdlr vc_conn;
4672
Philipp Maierd0e64b02019-03-13 14:15:23 +01004673 if (fr) {
4674 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4675 } else {
4676 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4677 }
4678 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4679 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004680 pars.expect_mr_conf_ie := { multirate_cfg := mr_cfg };
Philipp Maierd0e64b02019-03-13 14:15:23 +01004681 pars.expect_mr_s0_s7 := exp_s8_s0;
4682
4683 f_init(1, true);
4684 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004685 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004686 f_sleep(1.0);
4687
4688 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4689 vc_conn.done;
4690 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004691 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004692}
4693
4694function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4695runs on test_CT {
4696
4697 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4698 var MSC_ConnHdlr vc_conn;
4699
4700 if (fr) {
4701 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4702 } else {
4703 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4704 }
4705 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4706 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4707
4708 f_init(1, true);
4709 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004710 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004711 f_sleep(1.0);
4712
4713 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4714 vc_conn.done;
4715 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004716 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004717}
4718
Philipp Maierd0e64b02019-03-13 14:15:23 +01004719/* Set S1, we expect an AMR multirate configuration IE with all four rates
4720 * set. */
4721testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004722 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4723 params := '20882208'O));
4724 f_TC_assignment_codec_amr(true, mr_cfg, '00000011'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004725 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004726}
4727
4728/* Set S1, we expect an AMR multirate configuration IE with the lower three
4729 * rates set. */
4730testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004731 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4732 params := '208820'O));
4733 f_TC_assignment_codec_amr(false, mr_cfg, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004734 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004735}
4736
4737/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4738 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4739testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004740 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4741 params := '20882208'O));
4742 f_TC_assignment_codec_amr(true, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004743 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004744}
4745
4746/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4747 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4748testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004749 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4750 params := '208820'O));
4751 f_TC_assignment_codec_amr(false, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004752 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004753}
4754
4755/* The following block of tests selects more and more rates until all four
4756 * possible rates are in the active set (full rate) */
4757testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004758 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4759 f_TC_assignment_codec_amr(true, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004760 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004761}
4762
4763testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004764 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4765 params := '2080'O));
4766 f_TC_assignment_codec_amr(true, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004767 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004768}
4769
4770testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004771 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4772 params := '208820'O));
4773 f_TC_assignment_codec_amr(true, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004774 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004775}
4776
4777testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004778 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4779 params := '20882208'O));
4780 f_TC_assignment_codec_amr(true, mr_cfg, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004781 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004782}
4783
4784/* The following block of tests selects more and more rates until all three
4785 * possible rates are in the active set (half rate) */
4786testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004787 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4788 f_TC_assignment_codec_amr(false, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004789 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004790}
4791
4792testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004793 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4794 params := '2080'O));
4795 f_TC_assignment_codec_amr(false, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004796 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004797}
4798
4799testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004800 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4801 params := '208820'O));
4802 f_TC_assignment_codec_amr(false, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004803 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004804}
4805
4806/* The following block tests what happens when the MSC does offer rate
4807 * configurations that are not supported by the BSC. Normally such situations
4808 * should not happen because the MSC gets informed by the BSC in advance via
4809 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4810 * to offer rates that are not applicable anyway. */
4811
4812testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004813 /* Try to include 12,2k in into the active set even though the channel
4814 * is half rate only. The BSC is expected to remove the 12,0k */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004815 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4816 params := '208820'O));
4817 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'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_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004822 /* See what happens when all rates are selected at once. Since then
4823 * Also S1 is selected, this setting will be prefered and we should
4824 * get 12.2k, 7,40k, 5,90k, and 4,75k in 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, '11111111'B, '00000010'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_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004832 /* Same as above, but with S1 missing, the MSC is then expected to
4833 * select the currently supported rates, which are also 12.2k, 7,40k,
4834 * 5,90k, and 4,75k, into the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004835 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4836 params := '20882208'O));
4837 f_TC_assignment_codec_amr(true, mr_cfg, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004838 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004839}
4840
4841testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004842 /* Try to select no rates at all */
4843 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004844 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004845}
4846
4847testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004848 /* Try to select only unsupported rates */
4849 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004850 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004851}
4852
4853testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004854 /* Try to select 12,2k for half rate */
4855 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004856 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004857}
4858
Neels Hofmeyr21863562020-11-26 00:34:33 +00004859testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004860 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4861 codec_modes := '10010101'B,
4862 params := '20882208'O));
4863 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004864 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004865}
4866
4867testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004868 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4869 codec_modes := '00010101'B,
4870 params := '208820'O));
4871 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B,
Neels Hofmeyr21863562020-11-26 00:34:33 +00004872 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004873 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004874}
4875
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004876testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004877 /* "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 +07004878 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 3,
4879 codec_modes := '10010101'B,
4880 params := '20882208'O));
4881 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004882 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004883}
4884
4885testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004886 /* "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 +07004887 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 2,
4888 codec_modes := '00010101'B,
4889 params := '208820'O));
4890 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004891 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004892}
4893
Philipp Maierac09bfc2019-01-08 13:41:39 +01004894private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004895 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4896 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4897 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4898 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004899}
4900
4901private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004902 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4903 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004904}
4905
4906private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004907 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4908 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4909 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4910 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4911 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4912 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004913}
4914
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004915private function f_disable_all_sdcch() runs on test_CT {
4916 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4917 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4918 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4919 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4920}
4921
4922private function f_enable_all_sdcch() runs on test_CT {
4923 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4924 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4925 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4926 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4927}
4928
Philipp Maierac09bfc2019-01-08 13:41:39 +01004929/* Allow HR only */
4930private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4931 g_pars := f_gen_test_hdlr_pars();
4932 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4933 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4934 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4935 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4936 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4937 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4938 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004939 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004940}
4941
4942/* Allow FR only */
4943private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4944 g_pars := f_gen_test_hdlr_pars();
4945 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4946 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4947 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4948 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4949 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4950 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4951 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004952 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004953}
4954
4955/* Allow HR only (expect assignment failure) */
4956private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4957 g_pars := f_gen_test_hdlr_pars();
4958 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4959 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4960 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4961 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4962 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4963 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4964 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004965 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004966}
4967
4968/* Allow FR only (expect assignment failure) */
4969private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4970 g_pars := f_gen_test_hdlr_pars();
4971 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4972 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4973 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4974 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4975 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4976 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4977 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004978 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004979}
4980
4981/* Allow FR and HR, but prefer FR */
4982private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4983 g_pars := f_gen_test_hdlr_pars();
4984 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4985 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4986 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4987 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4988 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4989 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4990 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4991 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004992 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004993}
4994
4995/* Allow FR and HR, but prefer HR */
4996private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4997 g_pars := f_gen_test_hdlr_pars();
4998 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4999 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5000 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5001 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5002 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5003 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5004 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5005 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005006 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005007}
5008
5009/* Allow FR and HR, but prefer FR */
5010private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5011 g_pars := f_gen_test_hdlr_pars();
5012 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5013 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5014 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5015 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5016 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5017 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5018 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5019 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005020 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005021}
5022
5023/* Allow FR and HR, but prefer HR */
5024private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5025 g_pars := f_gen_test_hdlr_pars();
5026 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5027 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5028 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5029 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5030 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5031 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5032 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5033 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005034 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005035}
5036
5037/* Request a HR channel while all FR channels are exhausted, this is expected
5038 * to work without conflicts */
5039testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
5040 var MSC_ConnHdlr vc_conn;
5041 f_init(1, true);
5042 f_sleep(1.0);
5043 f_enable_all_tch();
5044 f_disable_all_tch_f();
5045 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
5046 vc_conn.done;
5047 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005048 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005049}
5050
5051/* Request a FR channel while all FR channels are exhausted, this is expected
5052 * to fail. */
5053testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
5054 var MSC_ConnHdlr vc_conn;
5055 f_init(1, true);
5056 f_sleep(1.0);
5057 f_enable_all_tch();
5058 f_disable_all_tch_f();
5059 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
5060 vc_conn.done;
5061 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005062 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005063}
5064
5065/* Request a FR (prefered) or alternatively a HR channel while all FR channels
5066 * are exhausted, this is expected to be resolved by selecting a HR channel. */
5067testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
5068 var MSC_ConnHdlr vc_conn;
5069 f_init(1, true);
5070 f_sleep(1.0);
5071 f_enable_all_tch();
5072 f_disable_all_tch_f();
5073 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
5074 vc_conn.done;
5075 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005076 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005077}
5078
5079/* Request a HR (prefered) or alternatively a FR channel while all FR channels
5080 * are exhausted, this is expected to work without conflicts. */
5081testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
5082 var MSC_ConnHdlr vc_conn;
5083 f_init(1, true);
5084 f_sleep(1.0);
5085 f_enable_all_tch();
5086 f_disable_all_tch_f();
5087 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
5088 vc_conn.done;
5089 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005090 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005091}
5092
5093/* Request a FR channel while all HR channels are exhausted, this is expected
5094 * to work without conflicts */
5095testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
5096 var MSC_ConnHdlr vc_conn;
5097 f_init(1, true);
5098 f_sleep(1.0);
5099 f_enable_all_tch();
5100 f_disable_all_tch_h();
5101 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
5102 vc_conn.done;
5103 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005104 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005105}
5106
5107/* Request a HR channel while all HR channels are exhausted, this is expected
5108 * to fail. */
5109testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
5110 var MSC_ConnHdlr vc_conn;
5111 f_init(1, true);
5112 f_sleep(1.0);
5113 f_enable_all_tch();
5114 f_disable_all_tch_h();
5115 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
5116 vc_conn.done;
5117 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005118 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005119}
5120
5121/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5122 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5123testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5124 var MSC_ConnHdlr vc_conn;
5125 f_init(1, true);
5126 f_sleep(1.0);
5127 f_enable_all_tch();
5128 f_disable_all_tch_h();
5129 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5130 vc_conn.done;
5131 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005132 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005133}
5134
5135/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5136 * are exhausted, this is expected to work without conflicts. */
5137testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5138 var MSC_ConnHdlr vc_conn;
5139 f_init(1, true);
5140 f_sleep(1.0);
5141 f_enable_all_tch();
5142 f_disable_all_tch_h();
5143 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5144 vc_conn.done;
5145 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005146 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005147}
5148
5149/* Allow FR and HR, but prefer HR */
5150private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5151 g_pars := f_gen_test_hdlr_pars();
5152 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5153 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5154 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5155 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5156 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5157 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5158 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5159 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005160 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005161}
5162
5163/* Allow FR and HR, but prefer FR */
5164private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5165 g_pars := f_gen_test_hdlr_pars();
5166 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5167 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5168 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5169 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5170 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5171 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5172 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5173 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005174 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005175}
5176
5177/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5178 * HR, which is the prefered type, is selected. */
5179testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5180 var MSC_ConnHdlr vc_conn;
5181 f_init(1, true);
5182 f_sleep(1.0);
5183 f_enable_all_tch();
5184 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5185 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005186 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005187}
5188
5189/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5190 * FR, which is the prefered type, is selected. */
5191testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5192 var MSC_ConnHdlr vc_conn;
5193 f_init(1, true);
5194 f_sleep(1.0);
5195 f_enable_all_tch();
5196 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5197 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005198 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005199}
5200
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005201/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5202private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5203 g_pars := f_gen_test_hdlr_pars();
5204 g_pars.ra := '02'O; /* RA containing reason=LU */
5205
5206 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5207 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5208 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5209 var template uint3_t tsc := ?;
5210
5211 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5212 f_create_bssmap_exp(l3_enc);
5213 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5214 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5215
5216 /* we should now have a COMPL_L3 at the MSC */
5217 timer T := 10.0;
5218 T.start;
5219 alt {
5220 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5221 [] T.timeout {
5222 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5223 }
5224 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005225
5226 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005227}
5228testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5229 var MSC_ConnHdlr vc_conn;
5230 f_init(1, true);
5231 f_sleep(1.0);
5232 f_disable_all_sdcch();
5233 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5234 vc_conn.done;
5235 f_enable_all_sdcch();
5236 f_shutdown_helper();
5237}
5238
5239/* Request a signalling channel with all SDCCH exhausted, it is
5240 expected that no TCH will be selected for signalling and assigment will fail
5241 because it's dictated by VTY config */
5242testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5243 var RSL_Message rsl_unused, rsl_msg;
5244 var GsmRrMessage rr;
5245 f_init(1, false);
5246 f_sleep(1.0);
5247 f_vty_allow_tch_for_signalling(false, 0);
5248 f_disable_all_sdcch();
5249
5250 /* RA containing reason=LU */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005251 f_ipa_tx(ts_RSL_CHAN_RQD('02'O, 2342));
5252 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005253 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5254 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5255 setverdict(fail, "Expected reject");
5256 }
5257
5258 f_vty_allow_tch_for_signalling(true, 0);
5259 f_enable_all_sdcch();
5260 f_shutdown_helper();
5261}
5262
5263/* Request a voice channel with all SDCCH exhausted, it is
5264 * expected that TCH channel will be allocated since the VTY option is only
5265 * aimed at signalling requests */
5266private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5267 g_pars := f_gen_test_hdlr_pars();
5268 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5269
5270 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5271 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5272 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5273 var template uint3_t tsc := ?;
5274
5275 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5276 f_create_bssmap_exp(l3_enc);
5277 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5278 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5279
5280 /* we should now have a COMPL_L3 at the MSC */
5281 timer T := 10.0;
5282 T.start;
5283 alt {
5284 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5285 [] T.timeout {
5286 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5287 }
5288 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005289 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005290}
5291testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5292 var MSC_ConnHdlr vc_conn;
5293 f_init(1, true);
5294 f_sleep(1.0);
5295 f_vty_allow_tch_for_signalling(false, 0);
5296 f_disable_all_sdcch();
5297
5298 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5299 vc_conn.done;
5300
5301 f_vty_allow_tch_for_signalling(true, 0);
5302 f_enable_all_sdcch();
5303 f_shutdown_helper();
5304}
5305
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005306/* Test Osmux setup BSC<->MSC */
5307testcase TC_assignment_osmux_cn() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005308 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5309 var MSC_ConnHdlr vc_conn;
5310
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005311 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5312 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5313 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiyb9bf00f2022-09-14 15:35:37 +07005314 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02005315 pars.use_osmux_cn := true;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005316
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02005317 g_osmux_enabled_cn := true;
5318 f_init(1, true);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005319 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005320 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005321
5322 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5323 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005324
5325 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005326 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005327}
5328
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005329/* Test Osmux setup BTS<->BSC */
5330testcase TC_assignment_osmux_bts() runs on test_CT {
5331 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5332 var MSC_ConnHdlr vc_conn;
5333
5334 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5335 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5336 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005337 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005338 pars.use_osmux_bts := true;
5339
5340 g_osmux_enabled_bts := true;
5341 f_init(1, true);
5342 f_sleep(1.0);
5343 f_vty_amr_start_mode_set(false, "1");
5344
5345 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5346 vc_conn.done;
5347
5348 f_vty_amr_start_mode_restore(false);
5349 f_shutdown_helper();
5350}
5351
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +02005352/* Test non-AMR codecs still work fine as RTP when Osmux is enabled BTS<->BSC<->MSC */
5353testcase TC_assignment_codec_hr_osmux_on() runs on test_CT {
5354 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5355 var MSC_ConnHdlr vc_conn;
5356
5357 g_osmux_enabled_cn := true;
5358 g_osmux_enabled_bts := true;
5359 f_init(1, true);
5360 f_sleep(1.0);
5361 f_ctrs_bsc_and_bts_assignment_init(1);
5362
5363 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5364 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5365 vc_conn.done;
5366
5367 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
5368 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
5369 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
5370 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
5371 f_ctrs_bts_verify();
5372
5373 f_shutdown_helper();
5374}
5375
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005376/* Test Osmux setup BTS<->BSC<->MSC */
5377testcase TC_assignment_osmux() runs on test_CT {
5378 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5379 var MSC_ConnHdlr vc_conn;
5380
5381 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5382 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5383 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005384 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005385 pars.use_osmux_cn := true;
5386 pars.use_osmux_bts := true;
5387
5388 g_osmux_enabled_cn := true;
5389 g_osmux_enabled_bts := true;
5390 f_init(1, true);
5391 f_sleep(1.0);
5392 f_vty_amr_start_mode_set(false, "1");
5393
5394 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5395 vc_conn.done;
5396
5397 f_vty_amr_start_mode_restore(false);
5398 f_shutdown_helper();
5399}
5400
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005401/* test the procedure of the MSC requesting a Classmark Update:
5402 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5403 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005404private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005405 g_pars := f_gen_test_hdlr_pars();
5406
Harald Weltea0630032018-03-20 21:09:55 +01005407 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005408 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005409
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005410 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5411 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5412
Harald Welte898113b2018-01-31 18:32:21 +01005413 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5414 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5415 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005416
5417 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005418}
5419testcase TC_classmark() runs on test_CT {
5420 var MSC_ConnHdlr vc_conn;
5421 f_init(1, true);
5422 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005423 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005424 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005425 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005426}
5427
Harald Welteeddf0e92020-06-21 19:42:15 +02005428/* Send a CommonID from the simulated MSC and verify that the information is used to
5429 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5430private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5431 g_pars := f_gen_test_hdlr_pars();
5432 f_MscConnHdlr_init_vty();
5433
5434 f_create_chan_and_exp();
5435 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005436
5437 /* Send CommonID */
5438 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5439
5440 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5441 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5442 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5443
5444 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005445
5446 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005447}
5448testcase TC_common_id() runs on test_CT {
5449 var MSC_ConnHdlr vc_conn;
5450 f_init(1, true);
5451 f_sleep(1.0);
5452 vc_conn := f_start_handler(refers(f_tc_common_id));
5453 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005454 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005455}
5456
Harald Weltee3bd6582018-01-31 22:51:25 +01005457private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005458 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005459 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005460 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005461
Harald Weltee3bd6582018-01-31 22:51:25 +01005462 /* send the single message we want to send */
5463 f_rsl_send_l3(l3);
5464}
5465
5466private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5467 timer T := sec;
5468 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005469 T.start;
5470 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005471 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5472 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005473 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005474 }
5475 [] T.timeout {
5476 setverdict(pass);
5477 }
5478 }
5479}
5480
Harald Weltee3bd6582018-01-31 22:51:25 +01005481/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5482private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5483 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5484 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005485 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005486}
Harald Welte898113b2018-01-31 18:32:21 +01005487testcase TC_unsol_ass_fail() runs on test_CT {
5488 var MSC_ConnHdlr vc_conn;
5489 f_init(1, true);
5490 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005491 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005492 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005493 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005494}
Harald Welte552620d2017-12-16 23:21:36 +01005495
Harald Welteea99a002018-01-31 20:46:43 +01005496
5497/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5498private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005499 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5500 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005501 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005502}
5503testcase TC_unsol_ass_compl() runs on test_CT {
5504 var MSC_ConnHdlr vc_conn;
5505 f_init(1, true);
5506 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005507 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005508 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005509 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005510}
5511
5512
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005513/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5514private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005515 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5516 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005517 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005518}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005519testcase TC_unsol_ho_fail() runs on test_CT {
5520 var MSC_ConnHdlr vc_conn;
5521 f_init(1, true);
5522 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005523 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005524 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005525 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005526}
5527
5528
Harald Weltee3bd6582018-01-31 22:51:25 +01005529/* short message from MS should be ignored */
5530private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005531 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005532 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005533 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005534
5535 /* send short message */
5536 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5537 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005538 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005539}
5540testcase TC_err_82_short_msg() runs on test_CT {
5541 var MSC_ConnHdlr vc_conn;
5542 f_init(1, true);
5543 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005544 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005545 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005546 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005547}
5548
5549
Harald Weltee9e02e42018-01-31 23:36:25 +01005550/* 24.008 8.4 Unknown message must trigger RR STATUS */
5551private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5552 f_est_single_l3(ts_RRM_UL_REL('00'O));
5553 timer T := 3.0
5554 alt {
5555 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5556 setverdict(pass);
5557 }
5558 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005559 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005560 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005561 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005562}
5563testcase TC_err_84_unknown_msg() runs on test_CT {
5564 var MSC_ConnHdlr vc_conn;
5565 f_init(1, true);
5566 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005567 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005568 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005569 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005570}
5571
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005572/***********************************************************************
5573 * Handover
5574 ***********************************************************************/
5575
Harald Welte94e0c342018-04-07 11:33:23 +02005576/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5577private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5578runs on test_CT {
5579 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5580 " timeslot "&int2str(ts_nr)&" ";
5581 f_vty_transceive(BSCVTY, cmd & suffix);
5582}
5583
Harald Welte261af4b2018-02-12 21:20:39 +01005584/* 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 +07005585private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5586 uint8_t bts_nr, uint8_t trx_nr,
5587 in RslChannelNr chan_nr)
5588{
Harald Welte261af4b2018-02-12 21:20:39 +01005589 /* FIXME: resolve those from component-global state */
5590 var integer ts_nr := chan_nr.tn;
5591 var integer ss_nr;
5592 if (ischosen(chan_nr.u.ch0)) {
5593 ss_nr := 0;
5594 } else if (ischosen(chan_nr.u.lm)) {
5595 ss_nr := chan_nr.u.lm.sub_chan;
5596 } else if (ischosen(chan_nr.u.sdcch4)) {
5597 ss_nr := chan_nr.u.sdcch4.sub_chan;
5598 } else if (ischosen(chan_nr.u.sdcch8)) {
5599 ss_nr := chan_nr.u.sdcch8.sub_chan;
5600 } else {
5601 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005602 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005603 }
5604
5605 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5606 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005607 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005608}
5609
Neels Hofmeyr91401012019-07-11 00:42:35 +02005610/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5611 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5612 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5613 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5614 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005615private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5616 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5617{
5618 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005619}
5620
5621/* intra-BSC hand-over between BTS0 and BTS1 */
5622private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005623 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5624 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005625
5626 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5627 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5628
Harald Weltea0630032018-03-20 21:09:55 +01005629 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005630 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005631
5632 var HandoverState hs := {
5633 rr_ho_cmpl_seen := false,
5634 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005635 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005636 expect_target_tsc := c_BtsParams[1].tsc
Harald Welte261af4b2018-02-12 21:20:39 +01005637 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005638 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005639 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005640 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5641 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005642
5643 /* From the MGW perspective, a handover is is characterized by
5644 * performing one MDCX operation with the MGW. So we expect to see
5645 * one more MDCX during handover. */
5646 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5647
Harald Welte261af4b2018-02-12 21:20:39 +01005648 alt {
5649 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005650 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005651
Philipp Maier4dae0652018-11-12 12:03:26 +01005652 /* Since this is an internal handover we expect the BSC to inform the
5653 * MSC about the event */
5654 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5655
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005656 /* Check the amount of MGCP transactions is still consistant with the
5657 * test expectation */
5658 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005659
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005660 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5661
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005662 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5663 * 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 +02005664 f_verify_encr_info(chan_act);
5665
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005666 f_chan_act_verify_tsc(chan_act, c_BtsParams[1].tsc);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005667
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005668 f_perform_clear(RSL1, RSL1_PROC);
5669
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005670 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005671}
5672
5673testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005674 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005675 var MSC_ConnHdlr vc_conn;
5676 f_init(2, true);
5677 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005678
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005679 pars.expect_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005680
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005681 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005682
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005683 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005684 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005685
5686 /* from f_establish_fully() */
5687 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5688 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5689 /* from handover */
5690 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5691 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5692 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5693 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005694 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5695 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005696 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005697 f_shutdown_helper(ho := true);
Harald Welte261af4b2018-02-12 21:20:39 +01005698}
Harald Weltee9e02e42018-01-31 23:36:25 +01005699
Oliver Smith7eabd312021-07-12 14:18:56 +02005700function 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 +02005701 var MSC_ConnHdlr vc_conn;
5702 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5703 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5704
5705 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005706 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005707 f_sleep(1.0);
5708
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005709 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005710
5711 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5712 vc_conn.done;
5713
5714 /* from f_establish_fully() */
5715 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5716 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5717 /* from handover */
5718 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5719 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5720 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5721 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005722 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5723 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005724 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005725 f_vty_encryption_a5_reset();
Oliver Smith39f53072022-10-27 14:44:04 +02005726 f_shutdown_helper(ho := true);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005727}
5728
5729testcase TC_ho_int_a5_0() runs on test_CT {
5730 f_tc_ho_int_a5('01'O);
5731}
5732
5733testcase TC_ho_int_a5_1() runs on test_CT {
5734 f_tc_ho_int_a5('02'O);
5735}
5736
5737testcase TC_ho_int_a5_3() runs on test_CT {
5738 f_tc_ho_int_a5('08'O);
5739}
5740
5741testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005742 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005743}
5744
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005745/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5746private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5747 g_pars := f_gen_test_hdlr_pars();
5748 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5749 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005750
5751 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5752 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5753
5754 f_establish_fully(ass_cmd, exp_compl);
5755 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5756
5757 var HandoverState hs := {
5758 rr_ho_cmpl_seen := false,
5759 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005760 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005761 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005762 };
5763 /* issue hand-over command on VTY */
5764 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5765 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5766 f_rslem_suspend(RSL1_PROC);
5767
5768 /* From the MGW perspective, a handover is is characterized by
5769 * performing one MDCX operation with the MGW. So we expect to see
5770 * one more MDCX during handover. */
5771 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5772
5773 var RSL_Message rsl;
5774 var PDU_ML3_NW_MS l3;
5775 var RslChannelNr new_chan_nr;
5776 var GsmArfcn arfcn;
5777 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5778 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5779 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5780 setverdict(fail, "Expected handoverCommand");
5781 mtc.stop;
5782 }
5783 }
5784 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5785 new_chan_nr, arfcn);
5786
5787 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5788
5789 /* resume processing of RSL DChan messages, which was temporarily suspended
5790 * before performing a hand-over */
5791 f_rslem_resume(RSL1_PROC);
5792 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5793
5794 f_sleep(1.0);
5795
5796 /* Handover fails because no HANDO DET appears on the new lchan,
5797 * and the old lchan reports a Radio Link Failure. */
5798 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5799
5800 var PDU_BSSAP rx_clear_request;
5801 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5802 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5803 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5804
5805 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5806
5807 var MgcpCommand mgcp;
5808 interleave {
5809 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5810 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005811 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005812 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005813 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005814 }
5815 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005816 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005817 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005818 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005819 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005820 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5821 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5822 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005823 }
5824
5825 f_sleep(0.5);
5826 setverdict(pass);
5827}
5828testcase TC_ho_int_radio_link_failure() runs on test_CT {
5829 var MSC_ConnHdlr vc_conn;
5830 f_init(2, true);
5831 f_sleep(1.0);
5832
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005833 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005834
5835 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5836 vc_conn.done;
5837
5838 /* from f_establish_fully() */
5839 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5840 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5841 /* from handover */
5842 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5843 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5844 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5845 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005846 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5847 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005848 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005849 f_shutdown_helper(ho := true);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005850}
5851
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005852/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005853private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005854 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005855 var template MgcpResponse mgcp_resp;
5856 var MGCP_RecvFrom mrf;
5857 var template MgcpMessage msg_resp;
5858 var template MgcpMessage msg_dlcx := {
5859 command := tr_DLCX()
5860 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005861
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005862 if (g_pars.aoip) {
5863 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005864 log("Got first DLCX: ", mgcp);
5865 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005866 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005867
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005868 MGCP.receive(tr_DLCX()) -> value mgcp {
5869 log("Got second DLCX: ", mgcp);
5870 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5871 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005872 } else {
5873 /* For SCCPLite, BSC doesn't handle the MSC-side */
5874 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5875 log("Got first DLCX: ", mrf.msg.command);
5876 msg_resp := {
5877 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5878 }
5879 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5880 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005881 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005882}
5883
Oliver Smithc9a5f532022-10-21 11:32:23 +02005884private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit,
5885 boolean skip_meas_rep := false) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005886
Oliver Smithc9a5f532022-10-21 11:32:23 +02005887 if (not skip_meas_rep) {
5888 var NcellReports neighbor_rep := {
5889 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5890 };
5891 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5892 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5893 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005894
Oliver Smithc9a5f532022-10-21 11:32:23 +02005895 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
5896 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005897
5898 f_sleep(0.5);
5899 /* The MSC negotiates Handover Request and Handover Request Ack with
5900 * the other BSS and comes back with a BSSMAP Handover Command
5901 * containing an RR Handover Command coming from the target BSS... */
5902
5903 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5904 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5905 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5906 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5907 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5908
5909 /* expect the Handover Command to go out on RR */
5910 var RSL_Message rsl_ho_cmd
5911 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5912 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5913 var RSL_IE_Body rsl_ho_cmd_l3;
5914 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5915 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5916 setverdict(fail);
5917 } else {
5918 log("Found L3 Info: ", rsl_ho_cmd_l3);
5919 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5920 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5921 setverdict(fail);
5922 } else {
5923 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5924 setverdict(pass);
5925 }
5926 }
5927
5928 /* When the other BSS has reported a completed handover, this side is
5929 * torn down. */
5930
5931 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5932 var BssmapCause cause := enum2int(cause_val);
5933 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5934
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005935 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005936
5937 interleave {
5938 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5939 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5940 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005941 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5942 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5943 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005944 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005945 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005946}
5947
5948private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5949 g_pars := f_gen_test_hdlr_pars();
5950 var PDU_BSSAP ass_req := f_gen_ass_req();
5951 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5952 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5953 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5954 f_establish_fully(ass_req, exp_compl);
5955
5956 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005957}
5958testcase TC_ho_out_of_this_bsc() runs on test_CT {
5959 var MSC_ConnHdlr vc_conn;
5960
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005961 f_init_vty();
5962 f_bts_0_cfg(BSCVTY,
5963 {"neighbor-list mode automatic",
5964 "handover 1",
5965 "handover algorithm 2",
5966 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005967 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005968 "neighbor lac 99 arfcn 123 bsic any"});
5969 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5970
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005971 f_init(1, true);
5972 f_sleep(1.0);
5973
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005974 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005975
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005976 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5977 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005978
5979 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5980 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5981 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5982 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5983 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5984 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5985 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005986 f_shutdown_helper(ho := true);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005987}
5988
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005989private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5990 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005991 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005992 octetstring l3 := '0123456789'O)
5993runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005994 /* The old lchan and conn should still be active. See that arbitrary L3
5995 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005996 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005997 var template PDU_BSSAP exp_data := {
5998 discriminator := '1'B,
5999 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07006000 dlci := dlci,
6001 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02006002 pdu := {
6003 dtap := l3
6004 }
6005 };
6006 BSSAP.receive(exp_data);
6007 setverdict(pass);
6008}
6009
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006010private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6011 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006012 template (value) OCT1 dlci := '00'O,
6013 octetstring l3 := '0123456789'O)
6014runs on MSC_ConnHdlr {
6015 BSSAP.send(PDU_BSSAP:{
6016 discriminator := '1'B,
6017 spare := '0000000'B,
6018 dlci := dlci,
6019 lengthIndicator := lengthof(l3),
6020 pdu := {
6021 dtap := l3
6022 }
6023 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006024 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006025 setverdict(pass);
6026}
6027
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006028/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
6029 * simply never sends a BSSMAP Handover Command. */
6030private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006031 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006032
6033 var PDU_BSSAP ass_req := f_gen_ass_req();
6034 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6035 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6036 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6037 f_establish_fully(ass_req, exp_compl);
6038
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006039 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006040 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6041
6042 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6043
6044 /* osmo-bsc should time out 10 seconds after the handover started.
6045 * Let's give it a bit extra. */
6046 f_sleep(15.0);
6047
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006048 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006049 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006050 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006051}
6052testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
6053 var MSC_ConnHdlr vc_conn;
6054
6055 f_init(1, true);
6056 f_sleep(1.0);
6057
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006058 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006059
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006060 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
6061 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006062
6063 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6064 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6065 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6066 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6067 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6068 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6069 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006070 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006071}
6072
6073/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
6074 * RR Handover Failure. */
6075private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006076 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006077
6078 var PDU_BSSAP ass_req := f_gen_ass_req();
6079 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6080 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6081 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6082 f_establish_fully(ass_req, exp_compl);
6083
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006084 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006085 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6086
6087 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6088
6089 f_sleep(0.5);
6090 /* The MSC negotiates Handover Request and Handover Request Ack with
6091 * the other BSS and comes back with a BSSMAP Handover Command
6092 * containing an RR Handover Command coming from the target BSS... */
6093
6094 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6095 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6096 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6097 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6098 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6099
6100 /* expect the Handover Command to go out on RR */
6101 var RSL_Message rsl_ho_cmd
6102 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6103 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6104 var RSL_IE_Body rsl_ho_cmd_l3;
6105 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6106 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6107 setverdict(fail);
6108 } else {
6109 log("Found L3 Info: ", rsl_ho_cmd_l3);
6110 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6111 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6112 setverdict(fail);
6113 } else {
6114 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6115 setverdict(pass);
6116 }
6117 }
6118
6119 f_sleep(0.2);
6120 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6121
6122 /* Should tell the MSC about the failure */
6123 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6124
6125 f_sleep(1.0);
6126
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006127 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006128 f_sleep(1.0);
6129
6130 setverdict(pass);
6131 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006132 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006133}
6134testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
6135 var MSC_ConnHdlr vc_conn;
6136
6137 f_init(1, true);
6138 f_sleep(1.0);
6139
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006140 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006141
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006142 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
6143 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006144
6145 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6146 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6147 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6148 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6149 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6150 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
6151 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006152 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006153}
6154
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006155/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
6156 * (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 +02006157 * and the lchan is released. */
6158private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006159 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006160
6161 var PDU_BSSAP ass_req := f_gen_ass_req();
6162 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6163 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6164 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6165 f_establish_fully(ass_req, exp_compl);
6166
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006167 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006168 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6169
6170 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6171
6172 f_sleep(0.5);
6173 /* The MSC negotiates Handover Request and Handover Request Ack with
6174 * the other BSS and comes back with a BSSMAP Handover Command
6175 * containing an RR Handover Command coming from the target BSS... */
6176
6177 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6178 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6179 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6180 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6181 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6182
6183 /* expect the Handover Command to go out on RR */
6184 var RSL_Message rsl_ho_cmd
6185 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6186 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6187 var RSL_IE_Body rsl_ho_cmd_l3;
6188 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6189 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6190 setverdict(fail);
6191 } else {
6192 log("Found L3 Info: ", rsl_ho_cmd_l3);
6193 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6194 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6195 setverdict(fail);
6196 } else {
6197 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6198 setverdict(pass);
6199 }
6200 }
6201
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006202 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6203 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6204 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006205
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006206 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006207 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6208 log("Got BSSMAP Clear Request");
6209 /* Instruct BSC to clear channel */
6210 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6211 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6212
6213 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006214 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006215 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6216 log("Got Deact SACCH");
6217 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006218 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006219 log("Got RR Release");
6220 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006221 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006222 log("Got RF Chan Rel");
6223 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006224 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006225 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006226 }
6227
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006228 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006229 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006230 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006231
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006232 setverdict(pass);
6233 f_sleep(1.0);
6234}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006235testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006236 var MSC_ConnHdlr vc_conn;
6237
6238 f_init(1, true);
6239 f_sleep(1.0);
6240
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006241 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006242
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006243 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006244 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006245
6246 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6247 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6248 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6249 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6250 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6251 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6252 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006253 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006254}
6255
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006256private 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 +01006257 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006258 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6259 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6260 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6261 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6262 * before we get started. */
6263 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6264 f_rslem_register(0, new_chan_nr);
6265 g_chan_nr := new_chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06006266 var uint3_t expect_target_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006267 f_sleep(1.0);
6268
6269 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6270 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006271 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006272
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006273 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6274 cell_id_source := g_pars.cell_id_source,
6275 oldToNewBSSIEs := oldToNewBSSIEs,
6276 enc := g_pars.encr);
6277 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6278 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6279 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6280 } else {
6281 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6282 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6283 BSSAP.send(ho_req);
6284 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006285
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006286 alt {
6287 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6288 if (g_pars.expect_ho_fail) {
6289 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6290 "Expected Handover Request to fail, but got Handover Request Ack")
6291 }
6292 }
6293 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6294 if (not g_pars.expect_ho_fail) {
6295 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6296 "Expected Handover Request to succeed, but got Handover Failure")
6297 }
6298 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6299 // For now just accept any cause.
6300 BSSAP.receive(tr_BSSMAP_ClearRequest);
6301 setverdict(pass);
6302 return;
6303 }
6304 }
6305
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006306 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6307
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006308 /* we're sure that the channel activation is done now, verify the parameters in it */
6309 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6310 f_verify_encr_info(chan_act);
6311 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006312
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006313 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6314 if (not g_pars.aoip) {
6315 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6316 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6317 }
6318 /* TODO: check actual codecs? */
6319 } else {
6320 if (g_pars.aoip) {
6321 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6322 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6323 }
6324 }
6325
6326 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6327 if (not g_pars.aoip) {
6328 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6329 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6330 }
6331 /* TODO: check actual codec? */
6332 } else {
6333 if (g_pars.aoip) {
6334 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6335 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6336 }
6337 }
6338
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006339 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006340 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6341 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6342 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6343 log("L3 Info in HO Request Ack is ", ho_command);
6344
6345 var GsmArfcn arfcn;
6346 var RslChannelNr actual_new_chan_nr;
6347 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6348 actual_new_chan_nr, arfcn);
6349
6350 if (actual_new_chan_nr != new_chan_nr) {
6351 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6352 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6353 setverdict(fail);
6354 return;
6355 }
6356 log("Handover Command chan_nr is", actual_new_chan_nr);
6357
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006358 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6359 if (not match(got_tsc, expect_target_tsc)) {
6360 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6361 expect_target_tsc, " got ", got_tsc);
6362 mtc.stop;
6363 } else {
6364 log("handoverCommand: verified TSC = ", got_tsc);
6365 }
6366
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006367 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6368 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6369 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6370 var template (present) CipherModeSetting_TV tr_cms := {
6371 sC := '0'B, /* no ciphering by default */
6372 algorithmIdentifier := '000'B,
6373 elementIdentifier := ?
6374 };
6375 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6376 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6377 tr_cms.sC := '1'B;
6378 }
6379 if (not match(cms, tr_cms)) {
6380 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6381 cms, ", expected: ", tr_cms);
6382 }
6383 } else {
6384 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6385 }
6386
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006387 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6388 * tells the MS to handover to the new lchan. Here comes the new MS on
6389 * the new lchan with a Handover RACH: */
6390
6391 /* send handover detect */
6392
6393 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6394
6395 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6396
6397 /* send handover complete over the new channel */
6398
6399 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6400 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6401 enc_PDU_ML3_MS_NW(l3_tx)));
6402
6403 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006404 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006405 setverdict(pass);
6406}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006407
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006408private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006409 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006410 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6411 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6412 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006413 }
6414 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006415 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006416 } else {
6417 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006418 }
6419 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006420 if (g_pars.expect_ho_fail) {
6421 f_perform_clear_no_lchan();
6422 } else {
6423 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6424 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006425 setverdict(pass);
6426}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006427function 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 +01006428 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006429
6430 f_init(1, true);
6431 f_sleep(1.0);
6432
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006433 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006434 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006435
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006436 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6437 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006438
6439 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6440 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006441
6442 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006443 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006444 if (pars.expect_ho_fail) {
6445 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6446 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6447 } else {
6448 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6449 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6450 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006451 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006452
6453 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006454}
6455
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006456testcase TC_ho_into_this_bsc() runs on test_CT {
6457 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6458 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006459 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006460}
6461
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006462function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6463 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006464 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006465 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006466 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006467 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Oliver Smith39f53072022-10-27 14:44:04 +02006468 f_shutdown_helper(ho := true);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006469}
6470
6471testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006472 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006473}
6474
6475testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006476 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006477}
6478
6479testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006480 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006481}
6482
6483testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006484 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006485}
6486
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006487/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6488 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6489 *
6490 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6491 * omitted.
6492 *
6493 * Related: SYS#5839
6494 */
6495testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6496 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6497}
6498
6499testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6500 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6501}
6502
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006503/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6504testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6505 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6506 expect_fail := true); // 0x18 = A5/3 and A5/4
6507}
6508
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006509testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6510 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6511 pars.host_aoip_tla := "::6";
6512 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006513 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006514}
6515
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006516/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006517 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006518 channel is later released (RR CHannel Release), should trigger inclusion of
6519 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6520 neighbors. */
6521testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6522 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6523 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006524 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006525 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006526
6527 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6528 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6529 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006530 f_shutdown_helper(ho := true);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006531}
6532
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006533/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6534testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6535 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6536 pars.encr := f_encr_params('08'O); /* only A5/3 */
6537 pars.last_used_eutran_plmn := '323454'O;
6538 pars.exp_fast_return := true;
6539 f_tc_ho_into_this_bsc_main(pars);
6540
6541 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6542 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6543 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006544 f_shutdown_helper(ho := true);
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006545}
6546
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006547/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6548 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6549 list when the channel is released. */
6550testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6551 f_init_vty();
6552 f_vty_allow_srvcc_fast_return(true, 0)
6553
6554 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6555 pars.last_used_eutran_plmn := '323454'O;
6556 pars.exp_fast_return := false;
6557 f_tc_ho_into_this_bsc_main(pars);
6558 f_vty_allow_srvcc_fast_return(false, 0);
6559 f_shutdown_helper();
6560}
6561
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006562/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6563testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6564 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6565 pars.last_used_eutran_plmn := '323454'O;
6566 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6567 f_tc_ho_into_this_bsc_main(pars);
6568
6569 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6570 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6571 f_ctrs_bsc_and_bts_verify();
6572 f_shutdown_helper();
6573}
6574
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006575private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6576 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6577 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6578 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6579 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6580 setverdict(pass);
6581}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006582
6583private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6584 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006585 var MSC_ConnHdlr vc_conn;
6586 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6587
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006588 f_init_vty();
6589 f_bts_0_cfg(BSCVTY,
6590 {"neighbor-list mode automatic",
6591 "handover 1",
6592 "handover algorithm 2",
6593 "handover2 window rxlev averaging 1",
6594 "no neighbors",
6595 "neighbor lac 99 arfcn 123 bsic any"});
6596 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6597
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006598 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006599 if (disable_fast_return) {
6600 f_vty_allow_srvcc_fast_return(true, 0);
6601 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006602 f_sleep(1.0);
6603
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006604 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006605
6606 pars.last_used_eutran_plmn := '323454'O;
6607 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6608 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6609
6610 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6611 vc_conn.done;
6612
6613 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6614 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6615 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6616 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6617 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6618 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006619
6620 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6621 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006622 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006623
6624 if (disable_fast_return) {
6625 f_vty_allow_srvcc_fast_return(false, 0);
6626 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006627 f_shutdown_helper();
6628}
6629
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006630/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6631 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6632 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6633 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6634testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6635 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6636}
6637/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6638 * independently of fast-reture allowed/forbidden in local BTS */
6639testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6640 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6641}
6642
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006643private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6644 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6645 f_rslem_register(0, new_chan_nr);
6646 g_chan_nr := new_chan_nr;
6647 f_sleep(1.0);
6648
6649 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6650 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6651 activate(as_Media());
6652
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006653 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006654 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006655 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006656
6657 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6658
6659 var PDU_BSSAP rx_bssap;
6660 var octetstring ho_command_str;
6661
6662 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6663
6664 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6665 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6666 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6667 log("L3 Info in HO Request Ack is ", ho_command);
6668
6669 var GsmArfcn arfcn;
6670 var RslChannelNr actual_new_chan_nr;
6671 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6672 actual_new_chan_nr, arfcn);
6673
6674 if (actual_new_chan_nr != new_chan_nr) {
6675 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6676 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6677 setverdict(fail);
6678 return;
6679 }
6680 log("Handover Command chan_nr is", actual_new_chan_nr);
6681
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006682 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6683 f_sleep(1.0);
6684
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006685 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6686 * tells the MS to handover to the new lchan. In this case, the MS
6687 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6688 * Handover Failure to the MSC. The procedure according to 3GPP TS
6689 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6690 * BSSMAP Clear Command: */
6691
6692 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6693 var BssmapCause cause := enum2int(cause_val);
6694 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6695
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006696 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006697 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006698 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006699
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006700 setverdict(pass);
6701 f_sleep(1.0);
6702
6703 setverdict(pass);
6704}
6705testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6706 var MSC_ConnHdlr vc_conn;
6707 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6708
6709 f_init(1, true);
6710 f_sleep(1.0);
6711
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006712 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006713
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006714 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6715 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006716
6717 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6718 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006719
6720 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6721 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6722 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6723 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6724 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006725 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006726}
6727
6728private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6729 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6730 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6731 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6732 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6733 * before we get started. */
6734 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6735 f_rslem_register(0, new_chan_nr);
6736 g_chan_nr := new_chan_nr;
6737 f_sleep(1.0);
6738
6739 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6740 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6741 activate(as_Media());
6742
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006743 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006744 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006745 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006746
6747 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6748
6749 var PDU_BSSAP rx_bssap;
6750 var octetstring ho_command_str;
6751
6752 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6753
6754 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6755 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6756 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6757 log("L3 Info in HO Request Ack is ", ho_command);
6758
6759 var GsmArfcn arfcn;
6760 var RslChannelNr actual_new_chan_nr;
6761 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6762 actual_new_chan_nr, arfcn);
6763
6764 if (actual_new_chan_nr != new_chan_nr) {
6765 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6766 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6767 setverdict(fail);
6768 return;
6769 }
6770 log("Handover Command chan_nr is", actual_new_chan_nr);
6771
6772 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6773 * tells the MS to handover to the new lchan. Here comes the new MS on
6774 * the new lchan with a Handover RACH: */
6775
6776 /* send handover detect */
6777
6778 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6779
6780 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6781
6782 /* The MSC chooses to clear the connection now, maybe we got the
6783 * Handover RACH on the new cell but the MS still signaled Handover
6784 * Failure to the old BSS? */
6785
6786 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6787 var BssmapCause cause := enum2int(cause_val);
6788 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6789
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006790 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006791 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006792 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006793
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006794 f_sleep(1.0);
6795}
6796testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6797 var MSC_ConnHdlr vc_conn;
6798 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6799
6800 f_init(1, true);
6801 f_sleep(1.0);
6802
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006803 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006804
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006805 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6806 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006807
6808 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6809 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006810
6811 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6812 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6813 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6814 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6815 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006816 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006817}
6818
6819/* The new BSS's lchan times out before the MSC decides that handover failed. */
6820private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6821 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6822 f_rslem_register(0, new_chan_nr);
6823 g_chan_nr := new_chan_nr;
6824 f_sleep(1.0);
6825
6826 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6827 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006828 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006829
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006830 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006831 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006832 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006833
6834 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6835
6836 var PDU_BSSAP rx_bssap;
6837 var octetstring ho_command_str;
6838
6839 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6840
6841 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6842 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6843 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6844 log("L3 Info in HO Request Ack is ", ho_command);
6845
6846 var GsmArfcn arfcn;
6847 var RslChannelNr actual_new_chan_nr;
6848 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6849 actual_new_chan_nr, arfcn);
6850
6851 if (actual_new_chan_nr != new_chan_nr) {
6852 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6853 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6854 setverdict(fail);
6855 return;
6856 }
6857 log("Handover Command chan_nr is", actual_new_chan_nr);
6858
6859 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6860 * tells the MS to handover to the new lchan. But the MS never shows up
6861 * on the new lchan. */
6862
6863 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6864
6865 /* Did osmo-bsc also send a Clear Request? */
6866 timer T := 0.5;
6867 T.start;
6868 alt {
6869 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6870 [] T.timeout { }
6871 }
6872
6873 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6874 * asked for it, this is a Handover Failure after all). */
6875
6876 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6877 var BssmapCause cause := enum2int(cause_val);
6878 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6879
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006880 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006881 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006882 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006883
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006884 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006885}
6886testcase TC_ho_in_fail_no_detect() runs on test_CT {
6887 var MSC_ConnHdlr vc_conn;
6888 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6889
6890 f_init(1, true);
6891 f_sleep(1.0);
6892
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006893 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006894
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006895 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6896 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006897
6898 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6899 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006900
6901 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6902 f_ctrs_bsc_and_bts_add(0, "handover:error");
6903 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6904 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6905 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006906 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006907}
6908
6909/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6910private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6911 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6912 f_rslem_register(0, new_chan_nr);
6913 g_chan_nr := new_chan_nr;
6914 f_sleep(1.0);
6915
6916 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6917 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006918 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006919
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006920 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006921 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006922 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006923
6924 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6925
6926 var PDU_BSSAP rx_bssap;
6927 var octetstring ho_command_str;
6928
6929 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6930
6931 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6932 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6933 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6934 log("L3 Info in HO Request Ack is ", ho_command);
6935
6936 var GsmArfcn arfcn;
6937 var RslChannelNr actual_new_chan_nr;
6938 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6939 actual_new_chan_nr, arfcn);
6940
6941 if (actual_new_chan_nr != new_chan_nr) {
6942 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6943 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6944 setverdict(fail);
6945 return;
6946 }
6947 log("Handover Command chan_nr is", actual_new_chan_nr);
6948
6949 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6950 * tells the MS to handover to the new lchan. But the MS never shows up
6951 * on the new lchan. */
6952
6953 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6954
6955 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006956 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006957
6958 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006959 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6960 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6961 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006962 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006963 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006964 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006965
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006966 f_sleep(1.0);
6967}
6968testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6969 var MSC_ConnHdlr vc_conn;
6970 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6971
6972 f_init(1, true);
6973 f_sleep(1.0);
6974
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006975 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006976
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006977 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6978 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006979
6980 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6981 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006982
6983 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6984 f_ctrs_bsc_and_bts_add(0, "handover:error");
6985 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6986 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6987 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006988 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006989}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006990
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006991/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6992 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6993 * empty N-Connect case. */
6994testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6995 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6996 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6997 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006998 f_shutdown_helper(ho := true);
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006999}
7000
Neels Hofmeyr91401012019-07-11 00:42:35 +02007001type record of charstring Commands;
7002
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007003private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02007004{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007005 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007006 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007007 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007008 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007009 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02007010}
7011
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01007012private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
7013{
7014 f_vty_enter_cfg_cs7_inst(pt, 0);
7015 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
7016 f_vty_transceive(pt, cmds[i]);
7017 }
7018 f_vty_transceive(pt, "end");
7019}
7020
Neels Hofmeyr91401012019-07-11 00:42:35 +02007021private function f_probe_for_handover(charstring log_label,
7022 charstring log_descr,
7023 charstring handover_vty_cmd,
7024 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007025 boolean is_inter_bsc_handover := false,
7026 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02007027runs on MSC_ConnHdlr
7028{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02007029 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
7030 * lchans to be established on bts 1 or bts 2. */
7031 f_rslem_suspend(RSL1_PROC);
7032 f_rslem_suspend(RSL2_PROC);
7033
Neels Hofmeyr91401012019-07-11 00:42:35 +02007034 var RSL_Message rsl;
7035
7036 var charstring log_msg := " (expecting handover)"
7037 if (not expect_handover) {
7038 log_msg := " (expecting NO handover)";
7039 }
7040 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
7041 f_vty_transceive(BSCVTY, handover_vty_cmd);
7042
Neels Hofmeyr91401012019-07-11 00:42:35 +02007043 timer T := 2.0;
7044 T.start;
7045
7046 alt {
7047 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
7048 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
7049 log("Rx L3 from net: ", l3);
7050 if (ischosen(l3.msgs.rrm.handoverCommand)) {
7051 var RslChannelNr new_chan_nr;
7052 var GsmArfcn arfcn;
7053 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
7054 new_chan_nr, arfcn);
7055 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
7056 log(l3.msgs.rrm.handoverCommand);
7057
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007058 /* Verify correct TSC in handoverCommand */
7059 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
7060 if (not match(got_tsc, expect_target_tsc)) {
7061 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
7062 expect_target_tsc, " got ", got_tsc);
7063 mtc.stop;
7064 } else {
7065 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
7066 expect_target_tsc, ")");
7067 }
7068
Neels Hofmeyr91401012019-07-11 00:42:35 +02007069 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
7070 * matter on which BTS it really is, we're not going to follow through an entire handover
7071 * anyway. */
7072 f_rslem_register(0, new_chan_nr, RSL1_PROC);
7073 f_rslem_resume(RSL1_PROC);
7074 f_rslem_register(0, new_chan_nr, RSL2_PROC);
7075 f_rslem_resume(RSL2_PROC);
7076
7077 if (expect_handover and not is_inter_bsc_handover) {
7078 setverdict(pass);
7079 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
7080 } else {
7081 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
7082 & log_label & ": " & log_descr);
7083 }
7084
7085 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
7086 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
7087 * Handover Failure. */
7088 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
7089
7090 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
7091 f_sleep(0.5);
7092 RSL1.clear;
7093 RSL2.clear;
7094 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
7095 break;
7096 } else {
7097 repeat;
7098 }
7099 }
7100 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
7101 if (expect_handover and is_inter_bsc_handover) {
7102 setverdict(pass);
7103 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
7104 } else {
7105 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
7106 & log_label & ": " & log_descr);
7107 }
7108
7109 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
7110
7111 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
7112 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
7113 * setting a short timeout and waiting is the only way. */
7114 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
7115 f_sleep(1.5);
7116 log("f_probe_for_handover(" & log_label & "): ...done");
7117
7118 break;
7119 }
7120 [] T.timeout {
7121 if (expect_handover) {
7122 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
7123 & log_label & ": " & log_descr);
7124 } else {
7125 setverdict(pass);
7126 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
7127 }
7128 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
7129 break;
7130 }
7131 }
7132
7133 f_rslem_resume(RSL1_PROC);
7134 f_rslem_resume(RSL2_PROC);
7135 f_sleep(3.0);
7136 RSL.clear;
7137
7138 log("f_probe_for_handover(" & log_label & "): done clearing");
7139}
7140
7141/* Test the effect of various neighbor configuration scenarios:
7142 *
7143 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
7144 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
7145 */
7146private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
7147 g_pars := f_gen_test_hdlr_pars();
7148 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
7149 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007150
7151 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
7152 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
7153
7154 /* Establish lchan at bts 0 */
7155 f_establish_fully(ass_cmd, exp_compl);
7156
7157 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
7158 f_vty_enter_cfg_network(BSCVTY);
7159 f_vty_transceive(BSCVTY, "timer T7 1");
7160 f_vty_transceive(BSCVTY, "end");
7161}
7162
7163private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
7164 f_tc_ho_neighbor_config_start();
7165
7166 /*
7167 * bts 0 ARFCN 871 BSIC 10
7168 * bts 1 ARFCN 871 BSIC 11
7169 * bts 2 ARFCN 871 BSIC 12
7170 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7171 */
7172
7173 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007174 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007175 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
7176 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007177 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007178
7179 f_probe_for_handover("1.b", "HO to unknown cell does not start",
7180 "handover any to arfcn 13 bsic 39",
7181 false);
7182
7183 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
7184 "handover any to arfcn 871 bsic 12",
7185 false);
7186
7187 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
7188 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007189 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007190
7191 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007192}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007193testcase TC_ho_neighbor_config_1() runs on test_CT {
7194 var MSC_ConnHdlr vc_conn;
7195 f_init(3, true, guard_timeout := 60.0);
7196 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007197 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007198 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7199 vc_conn.done;
7200
7201 /* f_tc_ho_neighbor_config_start() */
7202 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7203 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7204
7205 /* 1.a */
7206 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7207 * handover quickly by sending a Handover Failure message. */
7208 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7209 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7210 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7211 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007212 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7213 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007214
7215 /* 1.b */
7216 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7217 f_ctrs_bsc_and_bts_add(0, "handover:error");
7218
7219 /* 1.c */
7220 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7221 f_ctrs_bsc_and_bts_add(0, "handover:error");
7222
7223 /* 1.d */
7224 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7225 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7226 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7227 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007228 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7229 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007230
7231 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007232 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007233}
7234
Neels Hofmeyr91401012019-07-11 00:42:35 +02007235private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7236 f_tc_ho_neighbor_config_start();
7237
7238 /*
7239 * bts 0 ARFCN 871 BSIC 10
7240 * bts 1 ARFCN 871 BSIC 11
7241 * bts 2 ARFCN 871 BSIC 12
7242 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7243 */
7244
7245 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007246 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007247 f_sleep(0.5);
7248
7249 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7250 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007251 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007252
7253 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7254 "handover any to arfcn 871 bsic 12",
7255 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007256 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007257}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007258testcase TC_ho_neighbor_config_2() runs on test_CT {
7259 var MSC_ConnHdlr vc_conn;
7260 f_init(3, true, guard_timeout := 50.0);
7261 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007262 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007263 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7264 vc_conn.done;
7265
7266 /* f_tc_ho_neighbor_config_start() */
7267 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7268 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7269
7270 /* 2.a */
7271 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7272 * handover quickly by sending a Handover Failure message. */
7273 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7274 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7275 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7276 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007277 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7278 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007279
7280 /* 2.b */
7281 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7282 f_ctrs_bsc_and_bts_add(0, "handover:error");
7283
7284 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007285 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007286}
7287
Neels Hofmeyr91401012019-07-11 00:42:35 +02007288private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7289 f_tc_ho_neighbor_config_start();
7290
7291 /*
7292 * bts 0 ARFCN 871 BSIC 10
7293 * bts 1 ARFCN 871 BSIC 11
7294 * bts 2 ARFCN 871 BSIC 12
7295 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7296 */
7297
7298 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007299 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007300 f_sleep(0.5);
7301
7302 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7303 "handover any to arfcn 871 bsic 11",
7304 false);
7305 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",
7306 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007307 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007308 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007309}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007310testcase TC_ho_neighbor_config_3() runs on test_CT {
7311 var MSC_ConnHdlr vc_conn;
7312 f_init(3, true, guard_timeout := 50.0);
7313 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007314 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007315 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7316 vc_conn.done;
7317
7318 /* f_tc_ho_neighbor_config_start() */
7319 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7320 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7321
7322 /* 3.a */
7323 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7324 f_ctrs_bsc_and_bts_add(0, "handover:error");
7325
7326 /* 3.b */
7327 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7328 * handover quickly by sending a Handover Failure message. */
7329 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7330 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7331 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7332 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007333 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7334 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007335
7336 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007337 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007338}
7339
Neels Hofmeyr91401012019-07-11 00:42:35 +02007340private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7341 f_tc_ho_neighbor_config_start();
7342
7343 /*
7344 * bts 0 ARFCN 871 BSIC 10
7345 * bts 1 ARFCN 871 BSIC 11
7346 * bts 2 ARFCN 871 BSIC 12
7347 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7348 */
7349
7350 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007351 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007352 f_sleep(0.5);
7353
7354 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7355 "handover any to arfcn 871 bsic 11",
7356 false);
7357 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7358 "handover any to arfcn 871 bsic 12",
7359 false);
7360 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7361 "handover any to arfcn 123 bsic 45",
7362 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007363 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007364}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007365testcase TC_ho_neighbor_config_4() runs on test_CT {
7366 var MSC_ConnHdlr vc_conn;
7367 f_init(3, true, guard_timeout := 50.0);
7368 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007369 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007370 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7371 vc_conn.done;
7372
7373 /* f_tc_ho_neighbor_config_start() */
7374 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7375 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7376
7377 /* 4.a */
7378 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7379 f_ctrs_bsc_and_bts_add(0, "handover:error");
7380
7381 /* 4.b */
7382 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7383 f_ctrs_bsc_and_bts_add(0, "handover:error");
7384
7385 /* 4.c */
7386 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7387 * handover quickly by timing out after the Handover Required message */
7388 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7389 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7390 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7391 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7392
7393 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007394 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007395}
7396
Neels Hofmeyr91401012019-07-11 00:42:35 +02007397private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7398 f_tc_ho_neighbor_config_start();
7399
7400 /*
7401 * bts 0 ARFCN 871 BSIC 10
7402 * bts 1 ARFCN 871 BSIC 11
7403 * bts 2 ARFCN 871 BSIC 12
7404 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7405 */
7406
7407 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 +02007408 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007409 f_sleep(0.5);
7410
7411 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7412 "handover any to arfcn 871 bsic 12",
7413 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007414 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007415}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007416testcase TC_ho_neighbor_config_5() runs on test_CT {
7417 var MSC_ConnHdlr vc_conn;
7418 f_init(3, true);
7419 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007420 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007421 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7422 vc_conn.done;
7423
7424 /* f_tc_ho_neighbor_config_start() */
7425 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7426 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7427
7428 /* 5 */
7429 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7430 * handover quickly by timing out after the Handover Required message */
7431 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7432 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7433 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7434 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7435
7436 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007437 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007438}
7439
Neels Hofmeyr91401012019-07-11 00:42:35 +02007440private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7441 f_tc_ho_neighbor_config_start();
7442
7443 /*
7444 * bts 0 ARFCN 871 BSIC 10
7445 * bts 1 ARFCN 871 BSIC 11
7446 * bts 2 ARFCN 871 BSIC 12
7447 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7448 */
7449
7450 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7451 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007452 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007453 f_sleep(0.5);
7454
7455 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7456 "handover any to arfcn 871 bsic 12",
7457 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007458 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007459}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007460testcase TC_ho_neighbor_config_6() runs on test_CT {
7461 var MSC_ConnHdlr vc_conn;
7462 f_init(3, true);
7463 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007464 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007465 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7466 vc_conn.done;
7467
7468 /* f_tc_ho_neighbor_config_start() */
7469 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7470 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7471
7472 /* 6.a */
7473 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7474 * handover quickly by timing out after the Handover Required message */
7475 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7476 f_ctrs_bsc_and_bts_add(0, "handover:error");
7477
7478 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007479 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007480}
7481
Neels Hofmeyr91401012019-07-11 00:42:35 +02007482private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7483 f_tc_ho_neighbor_config_start();
7484
7485 /*
7486 * bts 0 ARFCN 871 BSIC 10
7487 * bts 1 ARFCN 871 BSIC 11
7488 * bts 2 ARFCN 871 BSIC 12
7489 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7490 */
7491
7492 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7493 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007494 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007495 f_sleep(0.5);
7496
7497 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7498 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007499 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007500 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7501 "handover any to arfcn 123 bsic 45",
7502 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007503 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007504}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007505testcase TC_ho_neighbor_config_7() runs on test_CT {
7506 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007507 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007508 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007509 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007510 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7511 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007512
7513 /* f_tc_ho_neighbor_config_start() */
7514 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7515 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7516
7517 /* 7.a */
7518 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7519 * handover quickly by sending a Handover Failure message. */
7520 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7521 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7522 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7523 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007524 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7525 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007526
7527 /* 7.b */
7528 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7529 * handover quickly by timing out after the Handover Required message */
7530 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7531 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7532 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7533 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7534
7535 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007536 f_shutdown_helper(ho := true);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007537}
7538
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007539/* OS#3041: Open and close N connections in a normal fashion, and expect no
7540 * BSSMAP Reset just because of that. */
7541testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7542 var default d;
7543 var integer i;
7544 var DchanTuple dt;
7545
7546 f_init();
7547
7548 /* Wait for initial BSSMAP Reset to pass */
7549 f_sleep(4.0);
7550
7551 d := activate(no_bssmap_reset());
7552
7553 /* Setup up a number of connections and RLSD them again from the MSC
7554 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7555 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007556 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007557 /* Since we're doing a lot of runs, give each one a fresh
7558 * T_guard from the top. */
7559 T_guard.start;
7560
7561 /* Setup a BSSAP connection and clear it right away. This is
7562 * the MSC telling the BSC about a planned release, it's not an
7563 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007564 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007565
7566 /* MSC disconnects (RLSD). */
7567 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7568 }
7569
7570 /* In the buggy behavior, a timeout of 2 seconds happens between above
7571 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7572 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7573 f_sleep(4.0);
7574
7575 deactivate(d);
7576 f_shutdown_helper();
7577}
Harald Welte552620d2017-12-16 23:21:36 +01007578
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007579/* OS#3041: Open and close N connections in a normal fashion, and expect no
7580 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7581 * the MSC. */
7582testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7583 var default d;
7584 var integer i;
7585 var DchanTuple dt;
7586 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007587 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7588 var BssmapCause cause := enum2int(cause_val);
7589
7590 f_init();
7591
7592 /* Wait for initial BSSMAP Reset to pass */
7593 f_sleep(4.0);
7594
7595 d := activate(no_bssmap_reset());
7596
7597 /* Setup up a number of connections and RLSD them again from the MSC
7598 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7599 * Let's do it some more times for good measure. */
7600 for (i := 0; i < 8; i := i+1) {
7601 /* Since we're doing a lot of runs, give each one a fresh
7602 * T_guard from the top. */
7603 T_guard.start;
7604
7605 /* Setup a BSSAP connection and clear it right away. This is
7606 * the MSC telling the BSC about a planned release, it's not an
7607 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007608 dt := f_est_dchan(int2oct(i,1), 23+i, gen_l3_valid_payload());
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007609
7610 /* Instruct BSC to clear channel */
7611 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7612
7613 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007614 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007615 }
7616
7617 /* In the buggy behavior, a timeout of 2 seconds happens between above
7618 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7619 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7620 f_sleep(4.0);
7621
7622 deactivate(d);
7623 f_shutdown_helper();
7624}
7625
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007626/* OS#3041: Open and close N connections in a normal fashion, and expect no
7627 * BSSMAP Reset just because of that. Close connections from the MS side with a
7628 * Release Ind on RSL. */
7629testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7630 var default d;
7631 var integer i;
7632 var DchanTuple dt;
7633 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007634 var integer j;
7635
7636 f_init();
7637
7638 /* Wait for initial BSSMAP Reset to pass */
7639 f_sleep(4.0);
7640
7641 d := activate(no_bssmap_reset());
7642
7643 /* Setup up a number of connections and RLSD them again from the MSC
7644 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7645 * Let's do it some more times for good measure. */
7646 for (i := 0; i < 8; i := i+1) {
7647 /* Since we're doing a lot of runs, give each one a fresh
7648 * T_guard from the top. */
7649 T_guard.start;
7650
7651 /* Setup a BSSAP connection and clear it right away. This is
7652 * the MSC telling the BSC about a planned release, it's not an
7653 * erratic loss of a connection. */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007654 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload());
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007655
7656 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007657 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007658
7659 /* expect Clear Request on MSC side */
7660 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7661
7662 /* Instruct BSC to clear channel */
7663 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7664 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7665
7666 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007667 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007668 }
7669
7670 /* In the buggy behavior, a timeout of 2 seconds happens between above
7671 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7672 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7673 f_sleep(4.0);
7674
7675 deactivate(d);
7676 f_shutdown_helper();
7677}
7678
Harald Welte94e0c342018-04-07 11:33:23 +02007679/***********************************************************************
7680 * IPA style dynamic PDCH
7681 ***********************************************************************/
7682
7683private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7684 template (omit) RSL_Cause nack := omit)
7685runs on test_CT {
7686 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7687 var RSL_Message rsl_unused;
7688 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7689 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7690 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007691 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007692 if (istemplatekind(nack, "omit")) {
7693 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007694 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007695 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007696 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007697 }
7698}
7699
7700private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7701 template (omit) RSL_Cause nack := omit)
7702runs on test_CT {
7703 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7704 var RSL_Message rsl_unused;
7705 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7706 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7707 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007708 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_DEACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007709 if (istemplatekind(nack, "omit")) {
7710 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007711 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007712 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007713 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007714 }
7715}
7716
7717private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7718runs on test_CT return charstring {
7719 var charstring cmd, resp;
7720 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007721 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007722}
7723
7724private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7725 template charstring exp)
7726runs on test_CT {
7727 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7728 if (not match(mode, exp)) {
7729 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007730 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007731 }
7732}
7733
7734private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7735runs on test_CT {
7736 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7737 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7738 f_vty_transceive(BSCVTY, "end");
7739}
7740
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007741
7742private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7743 var integer i;
7744 for (i := 0; i < 8; i := i + 1) {
7745 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7746 }
7747}
7748
Harald Welte94e0c342018-04-07 11:33:23 +02007749private const charstring TCHF_MODE := "TCH/F mode";
7750private const charstring TCHH_MODE := "TCH/H mode";
7751private const charstring PDCH_MODE := "PDCH mode";
7752private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007753private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007754
7755/* Test IPA PDCH activation / deactivation triggered by VTY */
7756testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7757 var RSL_Message rsl_unused;
7758
7759 /* change Timeslot 6 before f_init() starts RSL */
7760 f_init_vty();
7761 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7762 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7763
7764 f_init(1, false);
7765 f_sleep(1.0);
7766
7767 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7768
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007769 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007770 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7771 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007772 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7773 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007774 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007775 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007776 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7777
7778 /* De-activate it via VTY */
7779 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7780 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007781 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007782 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7783
7784 /* re-activate it via VTY */
7785 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7786 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007787 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007788 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7789
7790 /* and finally de-activate it again */
7791 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7792 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007793 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007794 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7795
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007796 /* clean up config */
7797 f_ts_set_chcomb(0, 0, 6, "PDCH");
7798
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007799 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007800}
7801
7802/* Test IPA PDCH activation NACK */
7803testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7804 var RSL_Message rsl_unused;
7805
7806 /* change Timeslot 6 before f_init() starts RSL */
7807 f_init_vty();
7808 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7809 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7810
7811 f_init(1, false);
7812 f_sleep(1.0);
7813
7814 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7815
7816 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7817 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007818 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7819 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007820 f_sleep(1.0);
7821 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7822
7823 /* De-activate it via VTY */
7824 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7825 f_sleep(1.0);
7826 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7827
7828 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7829 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7830 f_sleep(1.0);
7831 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7832
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007833 /* clean up config */
7834 f_ts_set_chcomb(0, 0, 6, "PDCH");
7835
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007836 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007837}
7838
7839
7840/***********************************************************************
7841 * Osmocom style dynamic PDCH
7842 ***********************************************************************/
7843
7844private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7845 template (omit) RSL_Cause nack := omit)
7846runs on test_CT {
7847 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7848 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007849 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007850 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7851 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007852 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT(chan_nr, ?));
Harald Welte94e0c342018-04-07 11:33:23 +02007853 if (istemplatekind(nack, "omit")) {
7854 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007855 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007856 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007857 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007858 }
7859}
7860
7861private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7862 template (omit) RSL_Cause nack := omit)
7863runs on test_CT {
7864 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7865 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007866 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007867 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7868 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007869 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007870 if (istemplatekind(nack, "omit")) {
7871 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007872 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007873 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007874 //f_ipa_tx(ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007875 }
7876}
7877
7878/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7879testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7880 var RSL_Message rsl_unused;
7881
7882 /* change Timeslot 6 before f_init() starts RSL */
7883 f_init_vty();
7884 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7885 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7886
7887 f_init(1, false);
7888 f_sleep(1.0);
7889
7890 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7891
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007892 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007893 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7894 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007895 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007896
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007897 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007898 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007899 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 +02007900 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7901
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007902 /* clean up config */
7903 f_ts_set_chcomb(0, 0, 6, "PDCH");
7904
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007905 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007906}
7907
7908/* Test Osmocom dyn PDCH activation NACK behavior */
7909testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7910 var RSL_Message rsl_unused;
7911
7912 /* change Timeslot 6 before f_init() starts RSL */
7913 f_init_vty();
7914 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7915 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7916
7917 f_init(1, false);
7918 f_sleep(1.0);
7919
7920 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7921
7922 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7923 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007924 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007925
7926 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007927 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte94e0c342018-04-07 11:33:23 +02007928 f_sleep(1.0);
7929 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7930
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007931 /* clean up config */
7932 f_ts_set_chcomb(0, 0, 6, "PDCH");
7933
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007934 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007935}
7936
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007937/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7938testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7939 var RSL_Message rsl_unused, rsl_msg;
7940 var DchanTuple dt;
7941 var BSSAP_N_CONNECT_ind rx_c_ind;
7942
7943 /* change Timeslot 6 before f_init() starts RSL */
7944 f_init_vty();
7945 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7946 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7947
7948 f_init(1, false);
7949 f_sleep(1.0);
7950
7951 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7952
7953 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7954 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7955 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007956 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007957
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007958 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007959 f_sleep(1.0);
7960 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7961 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7962
7963 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7964 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007965 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007966 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007967 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01007968 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007969 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007970 }
7971
7972 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007973 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7974 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7975 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007976
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007977 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007978 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007979 dt.idx := {0, 0};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007980
7981 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007982 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7983 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007984 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7985
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007986 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 +02007987 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7988 dt.sccp_conn_id := rx_c_ind.connectionId;
7989 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7990
7991 /* Instruct BSC to clear channel */
7992 var BssmapCause cause := 0;
7993 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007994 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007995
7996 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007997 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
7998 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007999 f_sleep(1.0);
8000 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8001
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008002 /* Clean up SDCCH lchans */
8003 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
8004 f_perform_clear_test_ct(sdcch_cleanup[i]);
8005 }
8006
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008007 /* clean up config */
8008 f_ts_set_chcomb(0, 0, 6, "PDCH");
8009
8010 f_shutdown_helper();
8011}
8012
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008013/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
8014testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
8015 var ASP_RSL_Unitdata rsl_ud;
8016 var integer i;
8017 var integer chreq_total, chreq_nochan;
8018
8019 f_init_vty();
8020 for (i := 1; i < 8; i := i + 1) {
8021 if (i == 2) {
8022 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8023 } else {
8024 f_ts_set_chcomb(0, 0, i, "PDCH");
8025 }
8026 }
8027 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8028
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008029 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008030
8031 /* The dyn TS want to activate PDCH mode, ACK that. */
8032 var RslChannelNr chan_nr;
8033 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008034 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
8035 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008036
8037 f_sleep(1.0);
8038
8039 /* Exhaust all dedicated SDCCH lchans.
8040 /* GSM 44.018 Table 9.1.8.2:
8041 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
8042 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008043 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008044 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008045 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008046 }
8047
8048 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008049 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008050 /* Also occupy the seven other SDCCH of the dyn TS */
8051 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008052 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008053 }
8054
8055 /* Clean up SDCCH lchans */
8056 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8057 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008058 }
8059
8060 /* clean up config */
8061 f_ts_reset_chcomb(0);
8062
8063 f_shutdown_helper();
8064}
8065
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008066/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
8067 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
8068 it as TCH directly instead. SYS#5309. */
8069testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
8070 var RSL_Message rsl_unused, rsl_msg;
8071 var DchanTuple dt;
8072 var BSSAP_N_CONNECT_ind rx_c_ind;
8073 var integer i;
8074
8075 /* change Timeslot 6 before f_init() starts RSL */
8076 f_init_vty();
8077 for (i := 1; i < 8; i := i + 1) {
8078 if (i == 6) {
8079 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8080 } else {
8081 f_ts_set_chcomb(0, 0, i, "PDCH");
8082 }
8083 }
8084 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8085
8086 f_init(1, false);
8087 f_sleep(1.0);
8088
8089 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8090
8091 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8092 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8093 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008094 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008095
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008096 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008097 f_sleep(1.0);
8098 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8099 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8100
8101 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8102 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008103 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008104 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008105 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008106 dt := f_est_dchan(ra, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008107 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008108 }
8109
8110 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008111 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
8112 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8113 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008114
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008115 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008116 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008117 dt.idx := {0, 0};
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008118
8119 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008120 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8121 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008122 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
8123
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008124 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 +02008125 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8126 dt.sccp_conn_id := rx_c_ind.connectionId;
8127 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8128
8129 /* Instruct BSC to clear channel */
8130 var BssmapCause cause := 0;
8131 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008132 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008133
8134 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008135 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8136 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008137 f_sleep(1.0);
8138 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8139
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008140 /* Clean up SDCCH lchans */
8141 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8142 f_perform_clear_test_ct(chan_cleanup[i]);
8143 }
8144
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008145 /* clean up config */
8146 f_ts_reset_chcomb(0);
8147 /* TODO: clean up other channels? */
8148
8149 f_shutdown_helper();
8150}
8151
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008152/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
8153testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
8154 var RSL_Message rsl_unused, rsl_msg;
8155 var DchanTuple dt;
8156 var BSSAP_N_CONNECT_ind rx_c_ind;
8157 var GsmRrMessage rr;
8158
8159 /* change Timeslot 6 before f_init() starts RSL */
8160 f_init_vty();
8161 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8162 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8163
8164 f_init(1, false);
8165 f_sleep(1.0);
8166
8167 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8168
8169 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8170 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8171 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008172 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008173
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008174 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008175 f_sleep(1.0);
8176 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8177 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8178
8179 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8180 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008181 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008182 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008183 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01008184 dt := f_est_dchan('23'O, i, gen_l3_valid_payload());
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008185 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008186 }
8187
8188 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008189 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8190 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8191 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008192
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008193 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008194 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008195 dt.idx := {0, 0};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008196
8197 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008198 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8199 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008200 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8201 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8202 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8203 }
8204
8205 /* FIXME? Currently the TS stays in state BORKEN: */
8206
8207 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008208 /* rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8209 * f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008210 * f_sleep(1.0);
8211 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8212 */
8213
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008214 /* Clean up SDCCH lchans */
8215 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8216 f_perform_clear_test_ct(chan_cleanup[i]);
8217 }
8218
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008219 /* clean up config */
8220 f_ts_set_chcomb(0, 0, 6, "PDCH");
8221
8222 f_shutdown_helper();
8223}
8224
Stefan Sperling0796a822018-10-05 13:01:39 +02008225testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008226 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008227 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8228 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8229 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008230 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008231}
8232
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008233testcase TC_chopped_ipa_payload() runs on test_CT {
8234 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8235 /* TODO: mp_bsc_ctrl_port does not work yet */};
8236 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8237 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8238 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008239 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008240}
8241
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008242/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8243 the BTS does autonomous MS power control loop */
8244testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8245 var MSC_ConnHdlr vc_conn;
8246 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8247 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8248 pars.exp_ms_power_params := true;
8249
8250 f_init(1, true);
8251 f_sleep(1.0);
8252 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8253 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008254 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008255}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008256
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008257/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8258testcase TC_c0_power_red_mode() runs on test_CT {
8259 f_init(1);
8260
8261 for (var integer red := 6; red >= 0; red := red - 2) {
8262 /* Configure BCCH carrier power reduction mode via the VTY */
8263 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8264
8265 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008266 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008267 chan_nr := t_RslChanNr_BCCH(0),
8268 bs_power := tr_RSL_IE_BS_Power(red / 2));
8269 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008270 var RSL_Message unused := f_exp_ipa_rx(tr_rsl_pdu);
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008271
8272 /* Additionally verify the applied value over the CTRL interface */
8273 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8274 if (cred != int2str(red)) {
8275 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8276 cred, " (expected ", red, ")");
8277 }
8278 }
8279
8280 f_shutdown_helper();
8281}
8282
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008283/***********************************************************************
8284 * MSC Pooling
8285 ***********************************************************************/
8286
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008287template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008288 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 +02008289
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008290private 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 +02008291runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008292 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008293 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008294 f_logp(BSCVTY, "Got RSL RR Release");
8295 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008296 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008297 f_logp(BSCVTY, "Got RSL Deact SACCH");
8298 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008299 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008300 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008301 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8302 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008303 break;
8304 }
8305 }
8306}
8307
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008308private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8309 var MgcpCommand mgcp_cmd;
8310 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8311 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8312 repeat;
8313 }
8314}
8315
8316private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8317 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8318 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8319 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8320 repeat;
8321 }
8322}
8323
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008324friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8325 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008326runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008327 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8328 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008329 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008330 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8331 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008332 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008333 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008334 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008335 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008336 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008337 }
8338 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008339 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008340 /* Also drop the SCCP connection */
8341 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8342 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008343 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008344 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008345 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8346 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008347 }
8348 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008349 deactivate(ack_dlcx);
8350 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008351}
8352
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008353friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8354runs on MSC_ConnHdlr {
8355 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8356 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8357 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8358 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8359 interleave {
8360 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8361 f_logp(BSCVTY, "Got RSL Deact SACCH");
8362 }
8363 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8364 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8365 /* Also drop the SCCP connection */
8366 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8367 }
8368 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8369 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8370 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8371 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8372 }
8373 }
8374 deactivate(ack_dlcx);
8375 deactivate(ack_rel_req);
8376}
8377
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008378friend function f_perform_clear_no_lchan()
8379runs on MSC_ConnHdlr {
8380 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8381 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8382 BSSAP.receive(tr_BSSMAP_ClearComplete);
8383 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8384 /* Also drop the SCCP connection */
8385 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8386}
8387
Vadim Yanitskiy65d879d2022-06-23 18:15:39 +07008388friend function f_perform_clear_test_ct(DchanTuple dt)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008389 runs on test_CT
8390{
8391 /* Instruct BSC to clear channel */
8392 var BssmapCause cause := 0;
8393 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008394 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008395}
8396
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008397private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8398 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008399runs on MSC_ConnHdlr {
8400 timer T := 10.0;
8401 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8402
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008403 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008404 f_create_bssmap_exp(l3_enc);
8405
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008406 /* RSL_Emulation.f_chan_est() on rsl_pt:
8407 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008408 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8409 */
8410 var RSL_Message rx_rsl;
8411 var GsmRrMessage rr;
8412
8413 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008414 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008415 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008416 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008417 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8418 */
8419 timer Tt := 10.0;
8420
8421 /* request a channel to be established */
8422 Tt.start;
8423 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008424 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008425 Tt.stop;
8426 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008427 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008428 setverdict(fail, "Unexpected RSL message on DCHAN");
8429 mtc.stop;
8430 }
8431 [] Tt.timeout {
8432 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8433 mtc.stop;
8434 }
8435 }
8436 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8437 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008438 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008439
8440
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008441 if (expect_bssmap_l3) {
8442 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8443 var template PDU_BSSAP exp_l3_compl;
8444 exp_l3_compl := tr_BSSMAP_ComplL3()
8445 if (g_pars.aoip == false) {
8446 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8447 } else {
8448 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8449 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008450
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008451 var PDU_BSSAP bssap;
8452 T.start;
8453 alt {
8454 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8455 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8456 log("rx exp_l3_compl = ", bssap);
8457 }
8458 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8459 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8460 }
8461 [] T.timeout {
8462 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8463 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008464 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008465
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008466 /* start ciphering, if requested */
8467 if (ispresent(g_pars.encr)) {
8468 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008469 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008470 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008471 }
8472
8473 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008474 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008475 }
8476 setverdict(pass);
8477 f_sleep(1.0);
8478}
8479
8480private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8481 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8482 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008483 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008484 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008485 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008486 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008487 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008488 }
8489}
8490
8491/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8492private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8493 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008494 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8495 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8496 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8497 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 +02008498}
8499testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8500
8501 f_init(1, true);
8502 f_sleep(1.0);
8503 var MSC_ConnHdlr vc_conn;
8504 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008505
8506 f_ctrs_msc_init();
8507
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008508 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8509 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008510
8511 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008512 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008513}
8514
8515/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8516/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8517 * just as well using only RSL. */
8518testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8519
8520 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8521 f_sleep(1.0);
8522
8523 /* Control which MSC gets chosen next by the round-robin, otherwise
8524 * would be randomly affected by which other tests ran before this. */
8525 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8526
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008527 f_ctrs_msc_init();
8528
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008529 var MSC_ConnHdlr vc_conn1;
8530 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8531 pars1.mscpool.rsl_idx := 0;
8532 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8533 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8534 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008535 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008536
8537 var MSC_ConnHdlr vc_conn2;
8538 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8539 pars2.mscpool.rsl_idx := 1;
8540 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8541 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8542 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008543 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008544
8545 /* Test round-robin wrap to the first MSC */
8546 var MSC_ConnHdlr vc_conn3;
8547 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8548 pars3.mscpool.rsl_idx := 2;
8549 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8550 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8551 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008552 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008553 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008554}
8555
8556/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8557 * (configured in osmo-bsc.cfg). */
8558/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8559 * just as well using only RSL. */
8560testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8561
8562 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8563 f_sleep(1.0);
8564
8565 /* Control which MSC gets chosen next by the round-robin, otherwise
8566 * would be randomly affected by which other tests ran before this. */
8567 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8568
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008569 f_ctrs_msc_init();
8570
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008571 var MSC_ConnHdlr vc_conn1;
8572 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8573 pars1.mscpool.rsl_idx := 0;
8574 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8575 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8576 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008577 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008578
8579 var MSC_ConnHdlr vc_conn2;
8580 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8581 pars2.mscpool.rsl_idx := 1;
8582 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8583 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8584 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008585 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008586
8587 /* Test round-robin wrap to the first MSC */
8588 var MSC_ConnHdlr vc_conn3;
8589 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8590 pars3.mscpool.rsl_idx := 2;
8591 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8592 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8593 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008594 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008595 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008596}
8597
8598/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8599 * (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
8600 * NULL-NRI setting is stronger than that. */
8601/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8602 * just as well using only RSL. */
8603testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8604
8605 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8606 f_sleep(1.0);
8607
8608 /* Control which MSC gets chosen next by the round-robin, otherwise
8609 * would be randomly affected by which other tests ran before this. */
8610 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8611
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008612 f_ctrs_msc_init();
8613
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008614 var MSC_ConnHdlr vc_conn1;
8615 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8616 pars1.mscpool.rsl_idx := 0;
8617 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8618 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8619 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008620 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008621
8622 var MSC_ConnHdlr vc_conn2;
8623 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8624 pars2.mscpool.rsl_idx := 1;
8625 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8626 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8627 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008628 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008629
8630 /* Test round-robin wrap to the first MSC */
8631 var MSC_ConnHdlr vc_conn3;
8632 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8633 pars3.mscpool.rsl_idx := 2;
8634 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8635 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8636 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008637 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008638 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008639}
8640
8641/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8642 * assigned to any MSC (configured in osmo-bsc.cfg). */
8643/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8644 * just as well using only RSL. */
8645testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8646
8647 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8648 f_sleep(1.0);
8649
8650 /* Control which MSC gets chosen next by the round-robin, otherwise
8651 * would be randomly affected by which other tests ran before this. */
8652 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8653
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008654 f_ctrs_msc_init();
8655
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008656 var MSC_ConnHdlr vc_conn1;
8657 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8658 pars1.mscpool.rsl_idx := 0;
8659 /* An NRI that is not assigned to any MSC */
8660 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8661 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8662 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008663 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008664
8665 var MSC_ConnHdlr vc_conn2;
8666 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8667 pars2.mscpool.rsl_idx := 1;
8668 /* An NRI that is not assigned to any MSC */
8669 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8670 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8671 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008672 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008673
8674 /* Test round-robin wrap to the first MSC */
8675 var MSC_ConnHdlr vc_conn3;
8676 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8677 pars3.mscpool.rsl_idx := 2;
8678 /* An NRI that is not assigned to any MSC */
8679 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8680 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8681 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008682 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008683 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008684}
8685
8686/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8687 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8688/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8689 * just as well using only RSL. */
8690testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8691
8692 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8693 f_sleep(1.0);
8694
8695 /* Control which MSC gets chosen next by the round-robin, otherwise
8696 * would be randomly affected by which other tests ran before this. */
8697 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8698
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008699 f_ctrs_msc_init();
8700
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008701 var MSC_ConnHdlr vc_conn1;
8702 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8703 pars1.mscpool.rsl_idx := 0;
8704 /* An NRI that is assigned to an unconnected MSC */
8705 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8706 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8707 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008708 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8709 f_ctrs_msc_add(0, "mscpool:subscr:new");
8710 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008711
8712 var MSC_ConnHdlr vc_conn2;
8713 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8714 pars2.mscpool.rsl_idx := 1;
8715 /* An NRI that is assigned to an unconnected MSC */
8716 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8717 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8718 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008719 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8720 f_ctrs_msc_add(1, "mscpool:subscr:new");
8721 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008722
8723 /* Test round-robin wrap to the first MSC */
8724 var MSC_ConnHdlr vc_conn3;
8725 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8726 pars3.mscpool.rsl_idx := 2;
8727 /* An NRI that is assigned to an unconnected MSC */
8728 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8729 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8730 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008731 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8732 f_ctrs_msc_add(0, "mscpool:subscr:new");
8733 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008734 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008735}
8736
8737/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8738 * osmo-bsc.cfg). */
8739/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8740 * just as well using only RSL. */
8741testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8742
8743 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8744 f_sleep(1.0);
8745
8746 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8747 * this is not using round-robin. */
8748 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8749
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008750 f_ctrs_msc_init();
8751
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008752 var MSC_ConnHdlr vc_conn1;
8753 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8754 pars1.mscpool.rsl_idx := 0;
8755 /* An NRI of the second MSC's range (256-511) */
8756 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8757 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8758 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008759 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008760
8761 var MSC_ConnHdlr vc_conn2;
8762 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8763 pars2.mscpool.rsl_idx := 1;
8764 /* An NRI of the second MSC's range (256-511) */
8765 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8766 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8767 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008768 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008769
8770 var MSC_ConnHdlr vc_conn3;
8771 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8772 pars3.mscpool.rsl_idx := 2;
8773 /* An NRI of the second MSC's range (256-511) */
8774 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8775 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8776 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008777 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008778 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008779}
8780
8781/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8782 * while a round-robin remains unaffected by that. */
8783/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8784 * just as well using only RSL. */
8785testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8786
8787 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8788 f_sleep(1.0);
8789
8790 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8791 * this is not using round-robin. */
8792 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8793
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008794 f_ctrs_msc_init();
8795
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008796 var MSC_ConnHdlr vc_conn1;
8797 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8798 pars1.mscpool.rsl_idx := 0;
8799 /* An NRI of the third MSC's range (512-767) */
8800 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8801 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8802 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008803 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008804
8805 var MSC_ConnHdlr vc_conn2;
8806 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8807 pars2.mscpool.rsl_idx := 1;
8808 /* An NRI of the third MSC's range (512-767) */
8809 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8810 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8811 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008812 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008813
8814 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8815 var MSC_ConnHdlr vc_conn3;
8816 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8817 pars3.mscpool.rsl_idx := 2;
8818 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8819 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8820 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008821 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008822 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008823}
8824
8825/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8826/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8827 * just as well using only RSL. */
8828testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8829
8830 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8831 f_sleep(1.0);
8832
8833 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8834 * instead, and hits msc 0. */
8835 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8836
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008837 f_ctrs_msc_init();
8838
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008839 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8840 var MSC_ConnHdlr vc_conn1;
8841 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8842 pars1.mscpool.rsl_idx := 0;
8843 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8844 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8845 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008846 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008847
8848 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8849 var MSC_ConnHdlr vc_conn2;
8850 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8851 pars2.mscpool.rsl_idx := 1;
8852 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8853 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8854 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008855 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008856 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008857}
8858
8859/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8860 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8861private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8862 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8863 //cid_list := { cIl_allInBSS := ''O };
8864 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8865 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8866 var BSSAP_N_UNITDATA_req paging;
8867 var hexstring imsi := '001010000000123'H;
8868
8869 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8870
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008871 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008872 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8873 BSSAP.send(paging);
8874
8875 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8876 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8877 * channel number is picked here. */
8878 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8879 f_rslem_register(0, new_chan_nr);
8880 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8881 f_rslem_unregister(0, new_chan_nr);
8882
8883 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8884 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008885 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008886 f_sleep(1.0);
8887}
8888testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8889 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8890 f_sleep(1.0);
8891
8892 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8893 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8894 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8895
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008896 f_ctrs_msc_init();
8897
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008898 var MSC_ConnHdlr vc_conn1;
8899 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8900 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008901 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8902 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008903 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8904 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008905 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008906 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008907}
8908
8909/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8910 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8911private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8912 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8913 //cid_list := { cIl_allInBSS := ''O };
8914 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8915 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8916 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008917 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008918 var BSSAP_N_UNITDATA_req paging;
8919
8920 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8921
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008922 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008923 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8924 BSSAP.send(paging);
8925
8926 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8927 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8928 * channel number is picked here. */
8929 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8930 f_rslem_register(0, new_chan_nr);
8931 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8932 f_rslem_unregister(0, new_chan_nr);
8933
8934 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8935 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8936 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008937 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 +02008938 f_sleep(1.0);
8939}
8940testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8941 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8942 f_sleep(1.0);
8943
8944 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8945 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8946 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8947
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008948 f_ctrs_msc_init();
8949
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008950 var MSC_ConnHdlr vc_conn1;
8951 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8952 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008953 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8954 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008955 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8956 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008957 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008958 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008959}
8960
8961/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8962/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8963 * just as well using only RSL. */
8964testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8965
8966 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8967 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008968 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8969 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008970
8971 /* Control which MSC gets chosen next by the round-robin, otherwise
8972 * would be randomly affected by which other tests ran before this. */
8973 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8974
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008975 f_ctrs_msc_init();
8976
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008977 var MSC_ConnHdlr vc_conn1;
8978 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8979 pars1.mscpool.rsl_idx := 0;
8980 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8981 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8982 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008983 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008984
8985 var MSC_ConnHdlr vc_conn2;
8986 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8987 pars2.mscpool.rsl_idx := 1;
8988 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8989 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8990 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008991 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008992
8993 var MSC_ConnHdlr vc_conn3;
8994 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8995 pars3.mscpool.rsl_idx := 2;
8996 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8997 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8998 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008999 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009000 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009001}
9002
9003/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
9004 * TMSI NRI. */
9005testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
9006
9007 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9008 f_sleep(1.0);
9009
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009010 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9011 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
9012
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009013 /* Control which MSC gets chosen next by the round-robin, otherwise
9014 * would be randomly affected by which other tests ran before this. */
9015 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9016
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009017 f_ctrs_msc_init();
9018
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009019 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
9020 var MSC_ConnHdlr vc_conn1;
9021 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
9022 pars1.mscpool.rsl_idx := 0;
9023 /* An NRI of the second MSC's range (256-511) */
9024 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
9025 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9026 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009027 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009028
9029 var MSC_ConnHdlr vc_conn2;
9030 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
9031 pars2.mscpool.rsl_idx := 1;
9032 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9033 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9034 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009035 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009036
9037 var MSC_ConnHdlr vc_conn3;
9038 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
9039 pars3.mscpool.rsl_idx := 2;
9040 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
9041 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9042 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009043 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009044 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009045}
9046
Philipp Maier783681c2020-07-16 16:47:06 +02009047/* Allow/Deny emergency calls globally via VTY */
9048private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
9049 f_vty_enter_cfg_msc(BSCVTY, 0);
9050 if (allow) {
9051 f_vty_transceive(BSCVTY, "allow-emergency allow");
9052 } else {
9053 f_vty_transceive(BSCVTY, "allow-emergency deny");
9054 }
9055 f_vty_transceive(BSCVTY, "exit");
9056 f_vty_transceive(BSCVTY, "exit");
9057}
9058
9059/* Allow/Deny emergency calls per BTS via VTY */
9060private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
9061 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9062 if (allow) {
9063 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
9064 } else {
9065 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
9066 }
9067 f_vty_transceive(BSCVTY, "exit");
9068 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00009069 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02009070}
9071
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02009072/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
9073private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
9074 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9075 if (allow) {
9076 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
9077 } else {
9078 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
9079 }
9080 f_vty_transceive(BSCVTY, "exit");
9081 f_vty_transceive(BSCVTY, "exit");
9082 f_vty_transceive(BSCVTY, "exit");
9083}
9084
Pau Espin Pedrol14475352021-07-22 15:48:16 +02009085/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
9086private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
9087 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9088 if (allow) {
9089 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
9090 } else {
9091 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
9092 }
9093 f_vty_transceive(BSCVTY, "exit");
9094 f_vty_transceive(BSCVTY, "exit");
9095 f_vty_transceive(BSCVTY, "exit");
9096}
9097
Philipp Maier783681c2020-07-16 16:47:06 +02009098/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
9099private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
9100 var PDU_ML3_MS_NW emerg_setup;
9101 var octetstring emerg_setup_enc;
9102 var RSL_Message emerg_setup_data_ind;
9103
9104 f_establish_fully(omit, omit);
9105
9106 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
9107 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
9108 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
9109
9110 RSL.send(emerg_setup_data_ind);
9111}
9112
9113/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
9114 * CALLS are permitted by the BSC config. */
9115private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
9116 var PDU_BSSAP emerg_setup_data_ind_bssap;
9117 var PDU_ML3_MS_NW emerg_setup;
9118 timer T := 3.0;
9119
9120 f_assignment_emerg_setup()
9121
9122 T.start;
9123 alt {
9124 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
9125 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
9126 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
9127 setverdict(fail, "no emergency setup");
9128 }
9129 }
9130 [] BSSAP.receive {
9131 setverdict(fail, "unexpected BSSAP message!");
9132 }
9133 [] T.timeout {
9134 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
9135 }
9136 }
9137
9138 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009139 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02009140}
9141
9142/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
9143 * forbidden by the BSC config. */
9144private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
9145 var PDU_BSSAP emerg_setup_data_ind_bssap;
9146 timer T := 3.0;
9147
9148 f_assignment_emerg_setup()
9149
9150 T.start;
9151 alt {
9152 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9153 setverdict(pass);
9154 }
9155 [] RSL.receive {
9156 setverdict(fail, "unexpected RSL message!");
9157 }
9158 [] T.timeout {
9159 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
9160 }
9161 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009162 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01009163 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02009164}
9165
9166/* EMERGENCY CALL situation #1, allowed globally and by BTS */
9167testcase TC_assignment_emerg_setup_allow() runs on test_CT {
9168 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9169 var MSC_ConnHdlr vc_conn;
9170
9171 f_init(1, true);
9172 f_sleep(1.0);
9173
9174 f_vty_allow_emerg_msc(true);
9175 f_vty_allow_emerg_bts(true, 0);
9176 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9177 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009178 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009179}
9180
9181/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
9182testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
9183 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9184 var MSC_ConnHdlr vc_conn;
9185
9186 f_init(1, true);
9187 f_sleep(1.0);
9188
9189 f_vty_allow_emerg_msc(false);
9190 f_vty_allow_emerg_bts(true, 0);
9191 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9192 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009193 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009194}
9195
9196/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
9197testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9198 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9199 var MSC_ConnHdlr vc_conn;
9200
9201 /* Note: This simulates a spec violation by the MS, correct MS
9202 * implementations would not try to establish an emergency call because
9203 * the system information tells in advance that emergency calls are
9204 * not forbidden */
9205
9206 f_init(1, true);
9207 f_sleep(1.0);
9208
9209 f_vty_allow_emerg_msc(true);
9210 f_vty_allow_emerg_bts(false, 0);
9211 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9212 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009213 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009214}
9215
Philipp Maier82812002020-08-13 18:48:27 +02009216/* Test what happens when an emergency call arrives while all TCH channels are
9217 * busy, the BSC is expected to terminate one call in favor of the incoming
9218 * emergency call */
9219testcase TC_emerg_premption() runs on test_CT {
9220 var ASP_RSL_Unitdata rsl_ud;
9221 var integer i;
9222 var integer chreq_total, chreq_nochan;
9223 var RSL_Message rx_rsl;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009224 var octetstring l3_payload := gen_l3_valid_payload();
Philipp Maier82812002020-08-13 18:48:27 +02009225
9226 f_init(1);
9227 f_sleep(1.0);
9228
9229 f_vty_allow_emerg_msc(true);
9230 f_vty_allow_emerg_bts(true, 0);
9231
9232 /* Fill up all channels on the BTS */
9233 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9234 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9235 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 +02009236 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009237 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009238 IPA_RSL[0][0].clear;
Philipp Maier82812002020-08-13 18:48:27 +02009239 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9240 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9241
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009242 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9243 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009244 f_ipa_tx(ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009245
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009246 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9247 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009248 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009249 var integer sccp_conn_id := rx_c_ind.connectionId;
9250 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9251
Philipp Maier82812002020-08-13 18:48:27 +02009252 /* Send Channel request for emegergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009253 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier82812002020-08-13 18:48:27 +02009254
9255 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009256 f_expect_chan_rel(first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009257 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009258
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009259 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9260 var BSSAP_N_DATA_ind rx_clear_req;
9261 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9262 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9263 log("XXX ", rx_clear_req);
9264 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9265 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9266 }
9267
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009268 /* Expect the BSC to send activate/assign the channel for the emergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009269 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009270 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9271 setverdict(fail, "different TCH lchan activated than expected");
9272 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009273 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(first_tch, 33));
9274 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009275
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009276 /* complete the BSSMAP Clear to satisfy the conn leak check */
9277 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9278 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9279 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9280 }
9281
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009282 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009283}
9284
9285/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009286private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009287private type record FHParamsTs {
9288 boolean enabled,
9289 uint6_t hsn,
9290 uint6_t maio,
9291 ArfcnList ma
9292};
9293
9294/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009295private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009296 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009297 FHParamsTs ts[8]
9298};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009299
9300/* Randomly generate the hopping parameters for the given timeslot numbers */
9301private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9302runs on test_CT return FHParamsTrx {
9303 var FHParamsTrx fhp;
9304
Philipp Maier798d8952021-10-19 14:43:19 +02009305 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9306 * fall in the GSM900 band. */
9307 fhp.arfcn.arfcn := f_rnd_int(3);
9308 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009309
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009310 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9311 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009312 fhp.ts[tn].enabled := false;
9313 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009314 continue;
9315 }
9316
9317 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009318 fhp.ts[tn].hsn := f_rnd_int(64);
9319 fhp.ts[tn].maio := f_rnd_int(64);
9320 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009321
9322 /* Random Mobile Allocation (hopping channels) */
9323 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9324 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9325 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009326 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009327 }
9328
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009329 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009330 }
9331
9332 log("f_TC_fh_params_gen(): ", fhp);
9333 return fhp;
9334}
9335
9336/* Make sure that the given Channel Description IE matches the hopping configuration */
9337private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9338{
9339 var template (present) ChannelDescription tr_cd;
9340 var template (present) MaioHsn tr_maio_hsn;
9341 var uint3_t tn := cd.chan_nr.tn;
9342
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009343 if (fhp.ts[tn].enabled) {
9344 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009345 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9346 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009347 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009348 }
9349
9350 if (not match(cd, tr_cd)) {
9351 setverdict(fail, "Channel Description IE does not match: ",
9352 cd, " vs expected ", tr_cd);
9353 }
9354}
9355
9356/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9357private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9358 in MobileAllocationLV ma)
9359{
9360 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9361
9362 if (not match(ma, tr_ma)) {
9363 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9364 tn, "): ", ma, " vs expected: ", tr_ma);
9365 } else {
9366 setverdict(pass);
9367 }
9368}
9369
9370private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9371 in MobileAllocationLV ma)
9372return template MobileAllocationLV {
9373 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009374 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009375 return { len := 0, ma := ''B };
9376 }
9377
9378 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9379 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9380 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009381
9382 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009383 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9384 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9385 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009386 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009387 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009388 }
9389 }
9390
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009391 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009392 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009393
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009394 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009395 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9396 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009397 }
9398
9399 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009400 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009401 if (full_mask[i] != '1'B)
9402 { continue; }
9403
9404 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9405 if (slot_mask[i] == '1'B) {
9406 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009407 } else {
9408 ma_mask := ma_mask & '0'B;
9409 }
9410 }
9411
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009412 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9413 if (full_mask[0] == '1'B) {
9414 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9415 if (slot_mask[0] == '1'B) {
9416 ma_mask := ma_mask & '1'B;
9417 } else {
9418 ma_mask := ma_mask & '0'B;
9419 }
9420 }
9421
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009422 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009423 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009424 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9425
9426 return { len := ma_mask_len, ma := ma_mask };
9427}
9428
Philipp Maier798d8952021-10-19 14:43:19 +02009429/* Configure the appropriate band for a given arfcn, exc */
9430private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9431{
9432 var charstring band;
9433 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9434
9435 select (arfcn_) {
9436 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9437 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9438 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9439 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9440 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9441 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9442 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9443 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9444 case else { return; }
9445 }
9446
9447 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9448 f_vty_transceive(BSCVTY, "band " & band);
9449 f_vty_transceive(BSCVTY, "end");
9450}
9451
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009452/* Configure the hopping parameters in accordance with the given record */
9453private function f_TC_fh_params_set(in FHParamsTrx fhp,
9454 uint8_t bts_nr := 0,
9455 uint8_t trx_nr := 0)
9456runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009457
9458 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9459
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009460 /* Enter the configuration node for the given BTS/TRX numbers */
9461 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9462
Philipp Maier798d8952021-10-19 14:43:19 +02009463 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009464
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009465 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009466 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9467
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009468 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009469 f_vty_transceive(BSCVTY, "hopping enabled 0");
9470 f_vty_transceive(BSCVTY, "exit"); /* go back */
9471 continue;
9472 }
9473
9474 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009475 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9476 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009477
9478 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009479 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9480 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009481 }
9482
9483 f_vty_transceive(BSCVTY, "hopping enabled 1");
9484 f_vty_transceive(BSCVTY, "exit"); /* go back */
9485 }
9486
9487 f_vty_transceive(BSCVTY, "end");
9488}
9489
9490/* Disable frequency hopping on all timeslots */
9491private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9492 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009493 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009494 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009495runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009496
9497 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9498
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009499 /* Enter the configuration node for the given BTS/TRX numbers */
9500 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9501
Philipp Maier798d8952021-10-19 14:43:19 +02009502 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009503
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009504 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009505 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9506
9507 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009508 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9509 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009510 }
9511
9512 f_vty_transceive(BSCVTY, "hopping enabled 0");
9513 f_vty_transceive(BSCVTY, "exit"); /* go back */
9514 }
9515
9516 f_vty_transceive(BSCVTY, "end");
9517 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9518}
9519
9520/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9521 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9522testcase TC_fh_params_chan_activ() runs on test_CT {
9523 var FHParamsTrx fhp := f_TC_fh_params_gen();
9524 var RSL_Message rsl_msg;
9525 var RSL_IE_Body ie;
9526
9527 f_init_vty();
9528
9529 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9530 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9531
9532 f_init(1);
9533
9534 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9535 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009536 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9537 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009538
9539 /* Make sure that Channel Identification IE is present */
9540 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9541 setverdict(fail, "RSL Channel Identification IE is absent");
9542 continue;
9543 }
9544
9545 /* Make sure that hopping parameters (HSN/MAIO) match */
9546 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9547
9548 /* "Mobile Allocation shall be included but empty" - let's check this */
9549 if (ie.chan_ident.ma.v.len != 0) {
9550 setverdict(fail, "Mobile Allocation IE is not empty: ",
9551 ie.chan_ident.ma, ", despite it shall be");
9552 continue;
9553 }
9554 }
9555
9556 /* Disable frequency hopping */
9557 f_TC_fh_params_unset(fhp);
9558
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009559 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009560}
9561
9562/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9563testcase TC_fh_params_imm_ass() runs on test_CT {
9564 var FHParamsTrx fhp := f_TC_fh_params_gen();
9565 var RSL_Message rsl_msg;
9566 var RSL_IE_Body ie;
9567
9568 f_init_vty();
9569
9570 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9571 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9572
9573 f_init(1);
9574
9575 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9576 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009577 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9578 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009579
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009580 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9581 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009582
9583 /* Make sure that Full Immediate Assign Info IE is present */
9584 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9585 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9586 continue;
9587 }
9588
9589 /* Decode the actual Immediate Assignment message */
9590 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9591 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9592 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9593 continue;
9594 }
9595
9596 /* Make sure that hopping parameters (HSN/MAIO) match */
9597 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9598
9599 /* Make sure that the Mobile Allocation IE matches */
9600 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9601 rr_msg.payload.imm_ass.mobile_allocation);
9602 }
9603
9604 /* Disable frequency hopping */
9605 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009606
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009607 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009608}
9609
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009610/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9611testcase TC_fh_params_assignment_cmd() runs on test_CT {
9612 var FHParamsTrx fhp := f_TC_fh_params_gen();
9613 var RSL_Message rsl_msg;
9614 var RSL_IE_Body ie;
9615
9616 f_init_vty();
9617
9618 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9619 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9620
9621 f_init(1);
9622
9623 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02009624 vc_MGCP[0].stop;
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009625
9626 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9627 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9628
9629 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9630 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9631 for (var integer i := 0; i < 3; i := i + 1) {
9632 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009633 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009634
9635 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9636 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009637 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009638
9639 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009640 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9641 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009642
9643 /* Make sure that L3 Information IE is present */
9644 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9645 setverdict(fail, "RSL L3 Information IE is absent");
9646 continue;
9647 }
9648
9649 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9650 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9651 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9652 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9653 continue;
9654 }
9655
9656 /* Make sure that hopping parameters (HSN/MAIO) match */
9657 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9658 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9659
9660 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9661 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009662 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009663 continue;
9664 }
9665
9666 /* Make sure that the Mobile Allocation IE matches (if present) */
9667 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9668 if (chan_desc.h and ma_present) {
9669 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9670 l3_msg.payload.ass_cmd.mobile_allocation.v);
9671 } else if (chan_desc.h and not ma_present) {
9672 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9673 continue;
9674 } else if (not chan_desc.h and ma_present) {
9675 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9676 continue;
9677 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009678
9679 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009680 }
9681
9682 /* Give the IUT some time to release all channels */
9683 f_sleep(3.0);
9684
9685 /* Disable frequency hopping */
9686 f_TC_fh_params_unset(fhp);
9687
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009688 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009689}
9690
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009691/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9692private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9693runs on test_CT {
9694 var RSL_Message rsl_msg;
9695 var RSL_IE_Body ie;
9696 var DchanTuple dt;
9697
9698 /* Establish a dedicated channel, so we can trigger handover */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +01009699 dt := f_est_dchan(f_rnd_ra_cs(), 23, gen_l3_valid_payload());
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009700 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009701
9702 /* Trigger handover from BTS0 to BTS1 */
9703 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9704 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9705
9706 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009707 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx := {1, 0});
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009708
9709 /* ACKnowledge channel activation and expect (RR) Handover Command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009710 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33), idx := {1, 0});
9711 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009712
9713 /* Make sure that L3 Information IE is present */
9714 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9715 setverdict(fail, "RSL L3 Information IE is absent");
9716 return;
9717 }
9718
9719 /* Decode the L3 message and make sure it is (RR) Handover Command */
9720 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9721 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9722 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9723 return;
9724 }
9725
9726 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9727 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9728 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9729 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9730 return;
9731 }
9732
9733 /* Make sure that hopping parameters (HSN/MAIO) match */
9734 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9735
9736 /* Make sure that Cell Channel Description IE is present */
9737 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9738 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9739 return;
9740 }
9741
9742 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9743 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9744 if (ma_present) {
9745 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9746 l3_msg.payload.ho_cmd.mobile_allocation.v);
9747 } else {
9748 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9749 return;
9750 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009751
9752 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009753}
9754testcase TC_fh_params_handover_cmd() runs on test_CT {
9755 var FHParamsTrx fhp := f_TC_fh_params_gen();
9756
9757 f_init_vty();
9758
9759 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9760 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9761
9762 f_vty_transceive(BSCVTY, "timeslot 0");
9763 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9764 f_vty_transceive(BSCVTY, "exit"); /* go back */
9765
9766 f_vty_transceive(BSCVTY, "timeslot 1");
9767 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9768 f_vty_transceive(BSCVTY, "end"); /* we're done */
9769
9770 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9771 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9772
9773 f_init(2);
9774
9775 f_TC_fh_params_handover_cmd(fhp);
9776
9777 /* Disable frequency hopping on BTS1 */
9778 f_TC_fh_params_unset(fhp, 1);
9779
9780 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9781 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9782
9783 f_vty_transceive(BSCVTY, "timeslot 0");
9784 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9785 f_vty_transceive(BSCVTY, "exit"); /* go back */
9786
9787 f_vty_transceive(BSCVTY, "timeslot 1");
9788 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9789 f_vty_transceive(BSCVTY, "end"); /* we're done */
9790
9791 f_shutdown_helper();
9792}
9793
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009794/* Verify the hopping parameters in System Information Type 4 */
9795testcase TC_fh_params_si4_cbch() runs on test_CT {
9796 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9797 var ASP_RSL_Unitdata rx_rsl_ud;
9798 timer T := 5.0;
9799
9800 f_init_vty();
9801
9802 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9803 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9804
9805 f_vty_transceive(BSCVTY, "timeslot 0");
9806 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9807 f_vty_transceive(BSCVTY, "exit"); /* go back */
9808
9809 f_vty_transceive(BSCVTY, "timeslot 1");
9810 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9811 f_vty_transceive(BSCVTY, "end"); /* we're done */
9812
9813 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9814 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9815
9816 f_init(1);
9817
9818 T.start;
9819 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009820 [] 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 +07009821 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9822 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9823
9824 /* Make sure that what we decoded is System Information Type 4 */
9825 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9826 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9827 repeat;
9828 }
9829
9830 /* Make sure that CBCH Channel Description IE is present */
9831 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9832 setverdict(fail, "CBCH Channel Description IE is absent");
9833 break;
9834 }
9835
9836 /* Finally, check the hopping parameters (HSN, MAIO) */
9837 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9838 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9839
9840 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9841 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9842 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9843 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9844 break;
9845 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9846 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9847 si.payload.si4.cbch_mobile_alloc.v);
9848 }
9849 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009850 [] IPA_RSL[0][0].receive { repeat; }
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009851 [] T.timeout {
9852 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9853 }
9854 }
9855
9856 /* Disable frequency hopping */
9857 f_TC_fh_params_unset(fhp);
9858
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009859 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009860 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9861
9862 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009863 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009864 f_vty_transceive(BSCVTY, "exit"); /* go back */
9865
9866 f_vty_transceive(BSCVTY, "timeslot 1");
9867 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9868 f_vty_transceive(BSCVTY, "end"); /* we're done */
9869
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009870 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009871}
9872
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009873template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9874 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9875
9876private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9877 template (present) BSSLAP_PDU expect_bsslap)
9878{
9879 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9880 if (not match(bsslap, expect_bsslap)) {
9881 log("EXPECTING BSSLAP: ", expect_bsslap);
9882 log("GOT BSSLAP: ", bsslap);
9883 setverdict(fail, "BSSLAP is not as expected");
9884 mtc.stop;
9885 }
9886 setverdict(pass);
9887}
9888
9889/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9890const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9891
9892private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9893 var PDU_BSSAP_LE rx_bsslap;
9894 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9895 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9896}
9897
9898/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9899 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9900private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9901 f_sleep(1.0);
9902
9903 f_establish_fully(omit, omit);
9904 f_bssap_le_register_imsi(g_pars.imsi, omit);
9905
9906 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9907 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9908
9909 var PDU_BSSAP_LE plr;
9910 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9911
9912 if (not do_ta_request) {
9913 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9914 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9915 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9916 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9917 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9918 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9919 mtc.stop;
9920 }
9921 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9922 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9923 if (not match(bsslap, expect_ta_layer3)) {
9924 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9925 log("GOT BSSLAP: ", bsslap);
9926 setverdict(fail, "BSSLAP is not as expected");
9927 mtc.stop;
9928 }
9929 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9930 * has no need to request the TA from the BSC and directly responds. */
9931 } else {
9932 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9933 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9934 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9935 }
9936
9937 /* SMLC got the TA from the BSC, now responds with geo information data. */
9938 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9939 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9940 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9941
9942 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9943 f_mo_l3_transceive();
9944
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009945 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009946
9947 f_sleep(2.0);
9948 setverdict(pass);
9949}
9950
9951/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9952 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9953private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9954 f_lcs_loc_req_for_active_ms(false);
9955}
9956testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9957 var MSC_ConnHdlr vc_conn;
9958 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9959
9960 f_init(1, true);
9961 f_sleep(1.0);
9962 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9963 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009964 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009965}
9966
9967/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9968 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9969private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9970 f_lcs_loc_req_for_active_ms(true);
9971}
9972testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9973 var MSC_ConnHdlr vc_conn;
9974 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9975
9976 f_init(1, true);
9977 f_sleep(1.0);
9978 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9979 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009980 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009981}
9982
9983/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9984 * conn without an active lchan. */
9985private function f_clear_A_conn() runs on MSC_ConnHdlr
9986{
9987 var BssmapCause cause := 0;
9988 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9989 BSSAP.receive(tr_BSSMAP_ClearComplete);
9990 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9991
9992 timer no_more_bssap := 5.0;
9993 no_more_bssap.start;
9994 alt {
9995 [] no_more_bssap.timeout { break; }
9996 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9997 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9998 mtc.stop;
9999 }
10000 }
10001 setverdict(pass);
10002}
10003
10004/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
10005 * for LCS, for cases where there is only an A conn without an active lchan. */
10006private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
10007{
10008 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
10009
10010 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
10011 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
10012 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
10013 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10014 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10015 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10016
10017 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
10018 f_clear_A_conn();
10019 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10020 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10021}
10022
10023/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10024 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
10025 */
10026private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
10027 f_sleep(1.0);
10028
10029 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10030 f_bssap_le_register_imsi(g_pars.imsi, omit);
10031
10032 /* Register to receive the Paging Command */
10033 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10034 g_chan_nr := new_chan_nr;
10035 f_rslem_register(0, g_chan_nr);
10036
10037 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10038 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10039 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10040 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10041
10042 var PDU_BSSAP_LE plr;
10043 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10044
10045 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10046 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10047
10048 /* OsmoBSC needs to Page */
10049 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
10050 f_logp(BSCVTY, "got Paging Command");
10051
10052 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
10053 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010054 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);
10055 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010056
10057 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
10058
10059 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10060
10061 /* SMLC got the TA from the BSC, now responds with geo information data. */
10062 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10063 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10064
10065 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10066
10067 /* The lchan is gone, the A-interface conn was created for the LCS only.
10068 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
10069 f_verify_active_A_conn_and_clear();
10070
10071 f_sleep(2.0);
10072 setverdict(pass);
10073}
10074testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
10075 var MSC_ConnHdlr vc_conn;
10076 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10077
10078 f_init(1, true);
10079 f_sleep(1.0);
10080
10081 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10082 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10083
10084 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
10085 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010086 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010087}
10088
10089/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
10090 */
10091private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
10092 f_sleep(1.0);
10093
10094 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10095 f_bssap_le_register_imsi(g_pars.imsi, omit);
10096
10097 /* provoke an abort by omitting both IMSI and IMEI */
10098 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10099 valueof(ts_BSSMAP_Perform_Location_Request(omit,
10100 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
10101 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10102
10103 /* BSC tells MSC about failure */
10104 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10105 locationEstimate := omit, positioningData := omit,
10106 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
10107
10108 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10109 f_verify_active_A_conn_and_clear();
10110
10111 f_sleep(2.0);
10112 setverdict(pass);
10113}
10114testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
10115 var MSC_ConnHdlr vc_conn;
10116 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10117
10118 f_init(1, true);
10119 f_sleep(1.0);
10120
10121 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10122 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10123
10124 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
10125 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010126 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010127}
10128
10129/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10130 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
10131private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
10132 f_sleep(1.0);
10133
10134 f_establish_fully(omit, omit);
10135 f_bssap_le_register_imsi(g_pars.imsi, omit);
10136
10137 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10138 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10139
10140 var PDU_BSSAP_LE plr;
10141 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10142
10143 if (do_ta) {
10144 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10145 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10146 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10147 }
10148
10149 /* SMLC fails to respond, BSC runs into timeout */
10150 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
10151 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10152
10153 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10154 locationEstimate := omit, positioningData := omit,
10155 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
10156
10157 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10158 f_verify_active_A_conn_and_clear();
10159
10160 f_sleep(2.0);
10161 setverdict(pass);
10162}
10163
10164/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10165 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
10166private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
10167 f_lcs_loc_req_for_active_ms_le_timeout(false);
10168}
10169
10170testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
10171 var MSC_ConnHdlr vc_conn;
10172 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10173
10174 f_init(1, true);
10175 f_sleep(1.0);
10176 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
10177 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010178 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010179}
10180
10181/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10182 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
10183private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
10184 f_lcs_loc_req_for_active_ms_le_timeout(true);
10185}
10186
10187testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
10188 var MSC_ConnHdlr vc_conn;
10189 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10190
10191 f_init(1, true);
10192 f_sleep(1.0);
10193 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10194 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010195 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010196}
10197
10198/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10199private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10200 f_sleep(1.0);
10201
10202 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10203 f_bssap_le_register_imsi(g_pars.imsi, omit);
10204
10205 /* Register to receive the Paging Command */
10206 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10207 g_chan_nr := new_chan_nr;
10208 f_rslem_register(0, g_chan_nr);
10209
10210 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10211 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10212 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10213 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10214
10215 var PDU_BSSAP_LE plr;
10216 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10217
10218 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10219 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10220
10221 /* OsmoBSC needs to Page */
10222 var PDU_BSSAP_LE rx_bsslap;
10223 alt {
10224 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10225 f_logp(BSCVTY, "got Paging Command");
10226 repeat;
10227 }
10228 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10229 /* MS does not respond to Paging, TA Req runs into timeout. */
10230 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10231 }
10232 }
10233
10234 /* SMLC responds with failure */
10235 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10236 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10237
10238 /* BSC tells MSC about failure */
10239 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10240 locationEstimate := omit, positioningData := omit,
10241 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10242
10243 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10244 f_verify_active_A_conn_and_clear();
10245
10246 f_sleep(2.0);
10247 setverdict(pass);
10248}
10249testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10250 var MSC_ConnHdlr vc_conn;
10251 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10252
10253 f_init(1, true);
10254 f_sleep(1.0);
10255
10256 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10257 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10258
10259 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10260 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010261 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010262}
10263
10264/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10265 * over. */
10266private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10267 f_sleep(1.0);
10268
10269 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10270 f_bssap_le_register_imsi(g_pars.imsi, omit);
10271
10272 /* Register to receive the Paging Command */
10273 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10274 g_chan_nr := new_chan_nr;
10275 f_rslem_register(0, g_chan_nr);
10276
10277 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10278 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10279 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10280 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10281
10282 var PDU_BSSAP_LE plr;
10283 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10284
10285 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10286 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010287 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 +020010288 do_clear := false, expect_bssmap_l3 := true);
10289
10290 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10291 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10292
10293 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10294 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10295
10296 /* SMLC got the TA from the BSC, now responds with geo information data. */
10297 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10298 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10299 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10300
10301 /* The lchan should still exist, it was from a CM Service Request. */
10302 f_mo_l3_transceive();
10303
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010304 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010305
10306 f_sleep(2.0);
10307 setverdict(pass);
10308}
10309testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10310 var MSC_ConnHdlr vc_conn;
10311 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10312
10313 f_init(1, true);
10314 f_sleep(1.0);
10315
10316 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10317 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10318
10319 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10320 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010321 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010322}
10323
10324/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10325 * the new lchan after handover. */
10326private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10327 f_sleep(1.0);
10328
10329 f_establish_fully(omit, omit);
10330 f_bssap_le_register_imsi(g_pars.imsi, omit);
10331
10332 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10333 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10334
10335 var PDU_BSSAP_LE plr;
10336 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10337
10338 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10339 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10340
10341 var HandoverState hs := {
10342 rr_ho_cmpl_seen := false,
10343 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010344 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010345 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010346 };
10347 /* issue hand-over command on VTY */
10348 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10349 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10350 f_rslem_suspend(RSL1_PROC);
10351
10352 /* From the MGW perspective, a handover is is characterized by
10353 * performing one MDCX operation with the MGW. So we expect to see
10354 * one more MDCX during handover. */
10355 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10356
10357 alt {
10358 [] as_handover(hs);
10359 }
10360
10361 var PDU_BSSAP_LE rx_bsslap;
10362
10363 interleave {
10364 /* Expect the BSC to inform the MSC about the handover */
10365 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10366
10367 /* Expect the BSC to inform the SMLC about the handover */
10368 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10369 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10370 }
10371 }
10372
10373 /* SMLC now responds with geo information data. */
10374 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10375 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10376 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10377
10378 /* lchan still active */
10379 f_mo_l3_transceive(RSL1);
10380
10381 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010382 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010383
10384 f_sleep(2.0);
10385 setverdict(pass);
10386}
10387testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10388 var MSC_ConnHdlr vc_conn;
10389 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10390
10391 f_init(2, true);
10392 f_sleep(1.0);
10393 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10394 vc_conn.done;
Oliver Smith39f53072022-10-27 14:44:04 +020010395 f_shutdown_helper(ho := true);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010396}
10397
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010398private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10399{
10400 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10401 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10402 * another lchan. */
10403 g_pars.ra := 'b7'O;
10404 f_assignment_emerg_setup();
10405
10406 var PDU_BSSAP emerg_setup_data_ind_bssap;
10407 timer T := 3.0;
10408 T.start;
10409 alt {
10410 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10411 var PDU_ML3_MS_NW verify_emerg_setup;
10412 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10413 if (not isbound(verify_emerg_setup.msgs.cc.emergencySetup)) {
10414 setverdict(fail, "no emergency setup");
10415 }
10416 }
10417 [] BSSAP.receive {
10418 setverdict(fail, "unexpected BSSAP message!");
10419 }
10420 [] T.timeout {
10421 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10422 }
10423 }
10424
10425 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10426
10427 /* Do a Location Request in-between the CC call setup */
10428 f_bssap_le_register_imsi(g_pars.imsi, omit);
10429 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10430 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10431 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10432 /* SMLC got the TA from the BSC, now responds with geo information data. */
10433 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10434 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10435 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10436
10437 /* Go on with voice call assignment */
10438 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10439 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10440
10441 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
10442 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
10443 * seems a good idea to see how osmo-bsc reacts to this. */
10444 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
10445 elementIdentifier := '0B'O, /* overwritten */
10446 lengthIndicator := 0, /* overwritten */
10447 speechOrDataIndicator := '0001'B, /* speech */
10448 spare1_4 := '0000'B,
10449 channelRateAndType := ChRate_TCHForH_Fpref,
10450 speechId_DataIndicator := 'c2918105'O
10451 };
10452 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
10453 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
10454
10455 f_rslem_dchan_queue_enable();
10456
10457 var ExpectCriteria mgcpcrit := {
10458 connid := omit,
10459 endpoint := omit,
10460 transid := omit
10461 };
10462 f_create_mgcp_expect(mgcpcrit);
10463
10464 BSSAP.send(ass_cmd);
10465
10466 var AssignmentState st := valueof(ts_AssignmentStateInit);
10467 st.voice_call := true;
10468 st.is_assignment := false;
10469 alt {
10470 [] as_modify(st);
10471 [] as_Media();
10472 [st.modify_done] BSSAP.receive(exp_compl) {
10473 setverdict(pass);
10474 }
10475 }
10476
10477 /* Voice call carries on ... */
10478 f_sleep(2.0);
10479
10480 setverdict(pass);
10481 f_perform_clear();
10482}
10483
10484testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10485 var MSC_ConnHdlr vc_conn;
10486 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10487
10488 f_init(1, true);
10489 f_sleep(1.0);
10490 f_vty_allow_emerg_msc(true);
10491 f_vty_allow_emerg_bts(true, 0);
10492 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10493 vc_conn.done;
10494 f_shutdown_helper();
10495}
10496
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010497private altstep no_bssmap_clear_req() runs on MSC_ConnHdlr {
10498 [] BSSAP.receive(tr_BSSMAP_ClearRequest) {
10499 setverdict(fail, "unexpected BSSMAP Clear Request");
10500 mtc.stop;
10501 }
10502}
10503
10504private type enumerated RslRel {
10505 RSLREL_REL_IND,
10506 RSLREL_CONN_FAIL
10507};
10508
10509private function f_emerg_call_and_lcs_loc_req_early_lchan_release(RslRel rsl_rel) runs on MSC_ConnHdlr
10510{
10511 g_pars.ra := f_rnd_ra_emerg();
10512 f_assignment_emerg_setup();
10513
10514 var PDU_BSSAP emerg_setup_data_ind_bssap;
10515 timer T := 3.0;
10516 T.start;
10517 alt {
10518 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10519 var PDU_ML3_MS_NW verify_emerg_setup;
10520 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10521 if (not ischosen(verify_emerg_setup.msgs.cc.emergencySetup)) {
10522 setverdict(fail, "no emergency setup");
10523 }
10524 }
10525 [] BSSAP.receive {
10526 setverdict(fail, "unexpected BSSAP message!");
10527 }
10528 [] T.timeout {
10529 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10530 }
10531 }
10532
10533 /* Start a Location Request to locate the emergency */
10534 f_bssap_le_register_imsi(g_pars.imsi, omit);
10535 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10536 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10537 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10538
10539 /* 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
10540 * do a Clear Command when the Location Response arrives. */
10541 activate(no_bssmap_clear_req());
10542
10543 /* the lchan gets interrupted while the Location Request has no response */
10544 select (rsl_rel) {
10545 case (RSLREL_REL_IND) {
10546 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10547 f_expect_lchan_rel(RSL, RSL_PROC);
10548 }
10549 case (RSLREL_CONN_FAIL) {
10550 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
10551 }
10552 case else {
10553 setverdict(fail, "Unknown RslRel type");
10554 mtc.stop;
10555 }
10556 }
10557
10558 /* Still expect the Location Response to find its way to the MSC. */
10559 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10560 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10561 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10562
10563 setverdict(pass);
10564
10565 select (rsl_rel) {
10566 case (RSLREL_REL_IND) {
10567 f_perform_clear_no_lchan();
10568 }
10569 case (RSLREL_CONN_FAIL) {
10570 f_perform_clear();
10571 }
10572 }
10573}
10574
10575private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind(charstring id) runs on MSC_ConnHdlr
10576{
10577 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_REL_IND);
10578}
10579
10580testcase TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() runs on test_CT {
10581 var MSC_ConnHdlr vc_conn;
10582 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10583
10584 f_init(1, true);
10585 f_sleep(1.0);
10586 f_vty_allow_emerg_msc(true);
10587 f_vty_allow_emerg_bts(true, 0);
10588 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind), pars);
10589 vc_conn.done;
10590 f_shutdown_helper();
10591}
10592
10593private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail(charstring id) runs on MSC_ConnHdlr
10594{
10595 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_CONN_FAIL);
10596}
10597
10598testcase TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() runs on test_CT {
10599 var MSC_ConnHdlr vc_conn;
10600 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10601
10602 f_init(1, true);
10603 f_sleep(1.0);
10604 f_vty_allow_emerg_msc(true);
10605 f_vty_allow_emerg_bts(true, 0);
10606 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail), pars);
10607 vc_conn.done;
10608 f_shutdown_helper();
10609}
10610
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010611/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10612private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10613 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10614
10615 /* Also disable attach for the single connected MSC */
10616 f_vty_msc_allow_attach(BSCVTY, { false });
10617
10618 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) ));
10619 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10620
10621 /* No MSC is found, expecting a proper release on RSL */
10622 interleave {
10623 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10624 f_logp(BSCVTY, "Got RSL RR Release");
10625 }
10626 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10627 f_logp(BSCVTY, "Got RSL Deact SACCH");
10628 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010629 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010630 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10631 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010632 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010633 }
10634 }
10635 setverdict(pass);
10636}
10637testcase TC_no_msc() runs on test_CT {
10638
10639 f_init(1, true);
10640 f_sleep(1.0);
10641 var MSC_ConnHdlr vc_conn;
10642 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10643
10644 f_ctrs_bsc_init(counternames_bsc_mscpool);
10645
10646 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10647 vc_conn.done;
10648
10649 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10650 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010651 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010652}
10653
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010654/* Dyn PDCH todo:
10655 * activate OSMO as TCH/F
10656 * activate OSMO as TCH/H
10657 * does the BSC-located PCU socket get the updated INFO?
10658 * what if no PCU is connected at the time?
10659 * is the info correct on delayed PCU (re)connect?
10660 */
Harald Welte94e0c342018-04-07 11:33:23 +020010661
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010662private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +020010663 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020010664 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010665
10666 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10667 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10668 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10669 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10670 g_pars.ass_codec_list.codecElements[0];
10671 if (isvalue(g_pars.expect_mr_s0_s7)) {
10672 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10673 g_pars.expect_mr_s0_s7;
10674 }
10675 }
10676 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10677 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10678 log("expecting ASS COMPL like this: ", exp_compl);
10679
10680 f_establish_fully(ass_cmd, exp_compl);
10681
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010682 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 +000010683
10684 var RSL_Message rsl;
10685
10686 timer T := 5.0;
10687 T.start;
10688 alt {
10689 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10690 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10691 log("Rx L3 from net: ", l3);
10692 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10693 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10694 mtc.stop;
10695 }
10696 }
10697 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10698 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10699 mtc.stop;
10700 }
10701 [] T.timeout {
10702 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10703 setverdict(pass);
10704 }
10705 }
10706 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010707
10708 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010709}
10710
10711/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10712 * osmo-bsc. */
10713testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10714 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10715 var MSC_ConnHdlr vc_conn;
10716
10717 f_init(1, true);
10718 f_sleep(1.0);
10719
10720 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10721 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10722 vc_conn.done;
10723 f_shutdown_helper();
10724}
10725
10726/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10727 */
10728testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10729 f_init_vty();
10730
10731 f_init(1, false);
10732 f_sleep(1.0);
10733
10734 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10735
10736 var ASP_RSL_Unitdata rx_rsl_ud;
10737 timer T := 5.0;
10738
10739 T.start;
10740 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010741 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010742 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10743 T.stop;
10744 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10745 mtc.stop;
10746 }
10747 repeat;
10748 }
10749 [] T.timeout {
10750 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10751 setverdict(pass);
10752 }
10753 }
10754}
10755
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010756private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10757 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010758 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010759
10760 /* Trigger re-assignment to another lchan */
10761 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10762
10763 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10764 * one MDCX on MGCP. */
10765 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10766
10767 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10768 * as the old lchan used. */
10769 g_media.bts.ipa_crcx_seen := false;
10770 g_media.bts.ipa_mdcx_seen := false;
10771
10772 /* Send different BTS side RTP port number for the new lchan */
10773 g_media.bts.bts.port_nr := 4223;
10774
10775 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10776
10777 /* Trigger re-assignment. */
10778 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10779
10780 timer T := 5.0;
10781 T.start;
10782 alt {
10783 [] as_assignment(assignment_st);
10784 [] as_Media();
10785 [] T.timeout {
10786 break;
10787 }
10788 }
10789
10790 if (not assignment_st.assignment_done) {
10791 setverdict(fail, "Assignment did not complete");
10792 mtc.stop;
10793 }
10794
10795 f_check_mgcp_expectations()
10796 setverdict(pass);
10797
10798 f_sleep(2.0);
10799 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10800
10801 /* Instruct BSC to clear channel */
10802 var BssmapCause cause := 0;
10803 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10804 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010805 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10806 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010807 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010808 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010809 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010810 }
10811 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10812 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10813 }
10814 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010815 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010816
10817 f_sleep(0.5);
10818}
10819
10820testcase TC_reassignment_fr() runs on test_CT {
10821 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10822 var MSC_ConnHdlr vc_conn;
10823
10824 f_init(1, true);
10825 f_sleep(1.0);
10826
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010827 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010828
10829 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10830 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10831 vc_conn.done;
10832
10833 /* from f_establish_fully() */
10834 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10835 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10836 /* from re-assignment */
10837 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10838 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10839 f_ctrs_bsc_and_bts_verify();
10840 f_shutdown_helper();
10841}
10842
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010843const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10844const charstring REEST_CLEAR := "REEST_CLEAR";
10845const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10846
10847/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10848 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10849 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10850 * the MSC as the CM Re-Establishment is handled.
10851 *
10852 * MS bts0 bts1 bsc msc test-component
10853 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10854 * | | _1 wait a bit, to settle down
10855 * |<-x x--| | _1 "lose connection"
10856 * | | REEST_LOST_CONNECTION
10857 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10858 * | | REEST_CLEAR
10859 * | |<-0---| _1 Clear Command on first A-conn
10860 * | |--0-->| _1 Clear Complete
10861 * | |<----------------->| | _1 Release first channel
10862 * | | REEST_CLEAR_DONE
10863 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10864 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10865 *
10866 */
10867private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10868 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10869 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10870
10871 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10872 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10873
10874 f_establish_fully(ass_cmd, exp_compl);
10875
10876 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10877 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10878 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10879 f_sleep(2.0);
10880 COORD.send(REEST_LOST_CONNECTION);
10881
10882 alt {
10883 [] COORD.receive(REEST_CLEAR);
10884 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10885 setverdict(fail, "Unexpected channel release");
10886 mtc.stop;
10887 }
10888 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10889 setverdict(fail, "Unexpected channel release");
10890 mtc.stop;
10891 }
10892 }
10893 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010894 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010895 COORD.send(REEST_CLEAR_DONE);
10896}
10897
10898private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10899 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10900
10901 /* The MS lost the connection on the first channel, now establishes another one */
10902 COORD.receive(REEST_LOST_CONNECTION);
10903
10904 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10905 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10906 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10907
10908 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010909 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 +020010910 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10911
10912 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10913 COORD.send(REEST_CLEAR);
10914 COORD.receive(REEST_CLEAR_DONE);
10915
10916 f_sleep(2.0);
10917
10918 /* Answer the CM Re-Establishment with an Assignment Command. */
10919 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10920 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10921 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10922 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10923
10924 var AssignmentState st := valueof(ts_AssignmentStateInit);
10925 st.voice_call := true;
10926 st.is_assignment := true;
10927
10928 var ExpectCriteria mgcpcrit := {
10929 connid := omit,
10930 endpoint := omit,
10931 transid := omit
10932 };
10933 f_create_mgcp_expect(mgcpcrit);
10934
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010935 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010936
10937 BSSAP.send(ass_cmd);
10938
10939 var PDU_BSSAP bssap;
10940
10941 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010942 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10943 [] as_Media_ipacc(RSL1, RSL2);
10944 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010945 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10946 break;
10947 }
10948 }
10949
10950 f_sleep(3.0);
10951
10952 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010953 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010954}
10955
10956testcase TC_cm_reestablishment() runs on test_CT {
10957 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10958 var MSC_ConnHdlr vc_conn1;
10959
10960 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10961 var MSC_ConnHdlr vc_conn2;
10962 pars2.imsi := pars1.imsi;
10963 pars2.media_nr := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010964 pars2.expect_tsc := c_BtsParams[1].tsc;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010965
10966 f_init(2, true, guard_timeout := 40.0);
10967 f_sleep(1.0);
10968
10969 vc_conn1 := f_start_handler_create(pars1);
10970 vc_conn2 := f_start_handler_create(pars2);
10971 connect(vc_conn1:COORD, vc_conn2:COORD);
10972 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10973 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10974 vc_conn1.done;
10975 vc_conn2.done;
10976
10977 f_shutdown_helper();
10978}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010979
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010980function f_exp_ipa_rx_nonfatal(template (present) RSL_Message t_rx,
10981 boolean ignore_other_rx := true,
10982 BtsTrxIdx idx := {0, 0},
10983 float Tval := 2.0)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010984runs on test_CT return template (omit) RSL_Message {
10985 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010986 timer T := Tval;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010987
10988 T.start;
10989 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010990 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010991 T.stop;
10992 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010993 [ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
10994 [not ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010995 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10996 T.stop;
10997 return omit;
10998 }
10999 [] T.timeout {
11000 return omit;
11001 }
11002 }
11003 return rx_rsl_ud.rsl;
11004}
11005
11006private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
11007 f_vty_enter_cfg_bts(pt, bts_nr);
11008 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
11009 f_vty_transceive(pt, "exit");
11010 f_vty_transceive(pt, "exit");
11011 f_vty_transceive(pt, "exit");
11012}
11013
11014private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030011015 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011016 template (present) uint12_t arfcn := ?,
11017 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011018{
11019 var RSL_IE_Body full_imm_ass_info;
11020 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
11021 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
11022 mtc.stop;
11023 }
11024
11025 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
11026 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
11027 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011028 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011029 page_mode := ?);
11030 if (not match(rr_imm_ass, expect_imm_ass)) {
11031 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
11032 setverdict(fail, "Failed to match Immediate Assignment");
11033 mtc.stop;
11034 }
11035}
11036
11037testcase TC_imm_ass_post_chan_ack() runs on test_CT {
11038 var RSL_Message chan_act;
11039 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011040 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011041
11042 f_init(1, false);
11043 f_sleep(1.0);
11044
11045 /* (should be the default anyway, just to make things clear) */
11046 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
11047
11048 /* RA containing reason=LU */
11049 var GsmFrameNumber fn := 2342;
11050 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011051 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011052
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011053 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011054
11055 /* First send the Chan Act ACK */
11056 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011057 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011058 var RSL_IE_Body chan_ident_ie;
11059 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11060 setverdict(fail, "RSL Channel Identification IE is absent");
11061 mtc.stop;
11062 }
11063
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011064 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011065
11066 /* Then expect the Immediate Assignment, after we ACKed the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011067 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011068
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011069 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11070 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011071
11072 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011073 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011074
11075 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011076 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011077 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011078 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11079
11080 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011081 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011082 f_shutdown_helper();
11083}
11084
11085testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
11086 var RSL_Message chan_act;
11087 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011088 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011089
11090 f_init(1, false);
11091 f_sleep(1.0);
11092
11093 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11094
11095 /* RA containing reason=LU */
11096 var GsmFrameNumber fn := 2342;
11097 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011098 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011099
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011100 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011101 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011102 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011103 var RSL_IE_Body chan_ident_ie;
11104 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11105 setverdict(fail, "RSL Channel Identification IE is absent");
11106 mtc.stop;
11107 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011108
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011109 /* (set bts 0 cfg back to default) */
11110 f_vty_set_imm_ass(BSCVTY);
11111
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011112 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011113 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011114 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11115 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011116
11117 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011118 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011119
11120 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011121 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011122
11123 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011124 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011125 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011126 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11127
11128 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011129 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011130 f_shutdown_helper();
11131}
11132
Neels Hofmeyr23158742021-09-07 19:08:07 +020011133testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
11134 var RSL_Message chan_act;
11135 var RSL_Message imm_ass;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011136 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr23158742021-09-07 19:08:07 +020011137
11138 f_init(1, false);
11139 f_sleep(1.0);
11140
11141 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11142
11143 /* RA containing reason=LU */
11144 var GsmFrameNumber fn := 2342;
11145 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011146 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011147
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011148 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011149 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011150 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr23158742021-09-07 19:08:07 +020011151 var RSL_IE_Body chan_ident_ie;
11152 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11153 setverdict(fail, "RSL Channel Identification IE is absent");
11154 mtc.stop;
11155 }
11156
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011157 /* (set bts 0 cfg back to default) */
11158 f_vty_set_imm_ass(BSCVTY);
11159
Neels Hofmeyr23158742021-09-07 19:08:07 +020011160 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011161 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011162 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11163 chan_ident_ie.chan_ident.ch_desc.v.tsc);
11164
11165 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011166 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011167
11168 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011169 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011170
11171 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011172 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011173 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020011174 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11175
11176 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011177 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020011178 f_shutdown_helper();
11179}
11180
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011181testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
11182 /* change Timeslot 6 before f_init() starts RSL */
11183 f_init_vty();
11184 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11185 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11186
11187 f_init(1, false);
11188 f_sleep(1.0);
11189
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011190 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011191 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11192 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011193 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11194 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011195
11196 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11197 f_ts_set_chcomb(0, 0, 6, "PDCH");
11198
11199 /* block all static timeslots so that the dyn TS will be used */
11200 f_disable_all_tch_f();
11201 f_disable_all_tch_h();
11202 f_disable_all_sdcch();
11203
11204 var RSL_Message chan_act;
11205 var RSL_Message imm_ass;
11206
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011207 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11208
11209 /* RA containing reason=LU */
11210 var GsmFrameNumber fn := 2342;
11211 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011212 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011213
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011214 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011215 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
11216 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011217
11218 /* Now activation as SDCCH8 */
11219 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011220 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011221
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011222 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011223 var RSL_IE_Body chan_ident_ie;
11224 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11225 setverdict(fail, "RSL Channel Identification IE is absent");
11226 mtc.stop;
11227 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011228
11229 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011230 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011231 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11232 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011233
11234 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011235 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011236
11237 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011238 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011239
11240 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011241 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011242 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011243 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11244
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011245 /* (set bts 0 cfg back to default) */
11246 f_vty_set_imm_ass(BSCVTY);
11247
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011248 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011249 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011250 f_shutdown_helper();
11251}
11252
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011253testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
11254 /* change Timeslot 6 before f_init() starts RSL */
11255 f_init_vty();
11256 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11257 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11258
11259 f_init(1, false);
11260 f_sleep(1.0);
11261
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011262 var octetstring l3_payload := gen_l3_valid_payload();
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011263 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11264 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011265 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11266 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011267
11268 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11269 f_ts_set_chcomb(0, 0, 6, "PDCH");
11270
11271 /* block all static timeslots so that the dyn TS will be used */
11272 f_disable_all_tch_f();
11273 f_disable_all_tch_h();
11274 f_disable_all_sdcch();
11275
11276 var RSL_Message chan_act;
11277 var RSL_Message imm_ass;
11278
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011279 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11280
11281 /* RA containing reason=LU */
11282 var GsmFrameNumber fn := 2342;
11283 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011284 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011285
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011286 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011287 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011288
11289 /* And already the Immediate Assignment even before the PDCH Deact ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011290 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011291
11292 /* continue the Osmo style PDCH Deact (usual chan rel) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011293 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011294
11295 /* Now activation as SDCCH8 */
11296 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011297 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011298
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011299 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011300 var RSL_IE_Body chan_ident_ie;
11301 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11302 setverdict(fail, "RSL Channel Identification IE is absent");
11303 mtc.stop;
11304 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011305 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011306
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011307 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11308 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011309
11310 /* Check that the lchan is working */
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011311 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_payload));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011312
11313 var BSSAP_N_CONNECT_ind rx_c_ind;
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011314 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3_payload))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011315 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011316 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11317
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011318 /* (set bts 0 cfg back to default) */
11319 f_vty_set_imm_ass(BSCVTY);
11320
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011321 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011322 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011323 f_shutdown_helper();
11324}
11325
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011326/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11327testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11328 var MSC_ConnHdlr vc_conn;
11329
11330 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11331 f_sleep(1.0);
11332
11333 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11334 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11335 "0,0,operational,unlocked,on,rsl-up;" &
11336 "1,0,operational,unlocked,on,rsl-up;" &
11337 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011338 "2,1,operational,unlocked,on,rsl-down;" &
11339 "2,2,operational,unlocked,on,rsl-down;" &
11340 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011341 "3,0,inoperational,locked,on,rsl-down;");
11342
11343 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11344 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11345 /* give it a moment to settle the FSM status */
11346 f_sleep(1.0);
11347
11348 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11349 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11350 * of "off"? But that's for a future patch if at all. */
11351 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11352 "0,0,operational,unlocked,on,rsl-up;" &
11353 "1,0,operational,locked,on,rsl-up;" &
11354 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011355 "2,1,operational,unlocked,on,rsl-down;" &
11356 "2,2,operational,unlocked,on,rsl-down;" &
11357 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011358 "3,0,inoperational,locked,on,rsl-down;");
11359
11360 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11361 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11362 f_sleep(1.0);
11363 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11364 "0,0,operational,unlocked,on,rsl-up;" &
11365 "1,0,operational,locked,on,rsl-up;" &
11366 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011367 "2,1,operational,unlocked,on,rsl-down;" &
11368 "2,2,operational,unlocked,on,rsl-down;" &
11369 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011370 "3,0,inoperational,locked,on,rsl-down;");
11371
11372 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11373 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11374 f_sleep(1.0);
11375 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11376 "0,0,operational,unlocked,on,rsl-up;" &
11377 "1,0,operational,unlocked,on,rsl-up;" &
11378 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011379 "2,1,operational,unlocked,on,rsl-down;" &
11380 "2,2,operational,unlocked,on,rsl-down;" &
11381 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011382 "3,0,inoperational,locked,on,rsl-down;");
11383
11384 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11385 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11386 f_sleep(1.0);
11387 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11388 "0,0,operational,unlocked,on,rsl-up;" &
11389 "1,0,operational,unlocked,on,rsl-up;" &
11390 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011391 "2,1,operational,unlocked,on,rsl-down;" &
11392 "2,2,operational,unlocked,on,rsl-down;" &
11393 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011394 "3,0,inoperational,locked,on,rsl-down;");
11395
11396 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11397 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11398 f_sleep(1.0);
11399 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11400 "0,0,operational,unlocked,on,rsl-up;" &
11401 "1,0,operational,unlocked,on,rsl-up;" &
11402 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011403 "2,1,operational,unlocked,on,rsl-down;" &
11404 "2,2,operational,unlocked,on,rsl-down;" &
11405 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011406 "3,0,inoperational,locked,on,rsl-down;");
11407
11408 f_shutdown_helper();
11409}
11410
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011411const CounterNameVals counternames_cm_serv_rej := {
11412 { "cm_serv_rej", 0 },
11413 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11414 { "cm_serv_rej:illegal_ms", 0 },
11415 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11416 { "cm_serv_rej:imei_not_accepted", 0 },
11417 { "cm_serv_rej:illegal_me", 0 },
11418 { "cm_serv_rej:plmn_not_allowed", 0 },
11419 { "cm_serv_rej:loc_not_allowed", 0 },
11420 { "cm_serv_rej:roaming_not_allowed", 0 },
11421 { "cm_serv_rej:network_failure", 0 },
11422 { "cm_serv_rej:synch_failure", 0 },
11423 { "cm_serv_rej:congestion", 0 },
11424 { "cm_serv_rej:srv_opt_not_supported", 0 },
11425 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11426 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11427 { "cm_serv_rej:call_can_not_be_identified", 0 },
11428 { "cm_serv_rej:incorrect_message", 0 },
11429 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11430 { "cm_serv_rej:msg_type_not_implemented", 0 },
11431 { "cm_serv_rej:msg_type_not_compatible", 0 },
11432 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11433 { "cm_serv_rej:condtional_ie_error", 0 },
11434 { "cm_serv_rej:msg_not_compatible", 0 },
11435 { "cm_serv_rej:protocol_error", 0 },
11436 { "cm_serv_rej:retry_in_new_cell", 0 }
11437};
11438
11439private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11440{
11441 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011442 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011443 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011444 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11445 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011446 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011447}
11448testcase TC_cm_serv_rej() runs on test_CT {
11449 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11450 var MSC_ConnHdlr vc_conn;
11451
11452 f_init(1, true);
11453 f_sleep(1.0);
11454
11455 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11456
11457 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11458 vc_conn.done;
11459
11460 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11461 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11462 f_ctrs_bts_verify();
11463
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011464 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011465 f_shutdown_helper();
11466}
11467
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011468/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11469 * Activ Ack (SYS#5627). */
11470private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11471 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011472
11473 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11474 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011475
11476 var BSSMAP_FIELD_CodecType codecType;
11477 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11478
11479 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11480
11481 /* First establish a signalling lchan */
11482 f_create_chan_and_exp();
11483 f_rslem_dchan_queue_enable();
11484
11485 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011486
11487 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011488 activate(as_Media_mgw(fail_on_dlcx := false));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011489
11490 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11491 f_rslem_register(0, chan_nr);
11492
11493 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11494 BSSAP.send(ass_cmd);
11495
11496
11497 /* Wait for the Channel Activ for the TCH channel */
11498 var ASP_RSL_Unitdata rx_rsl_ud;
11499 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11500
11501 /* make the original SDCCH disappear */
11502 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11503
11504 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11505 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11506
11507 interleave {
11508 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11509 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11510 }
11511
11512 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11513 BSSAP.receive(tr_BSSMAP_ClearComplete);
11514 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11515
11516 var MgcpCommand mgcp;
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011517 var MGCP_RecvFrom mrf;
11518 var template MgcpMessage msg_dlcx := { command := tr_DLCX };
11519 alt {
11520 [g_pars.aoip] MGCP.receive(tr_DLCX) -> value mgcp {
11521 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11522 }
11523 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
11524 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
11525 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
11526 }));
11527 }
11528 }
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011529
11530 f_sleep(0.5);
11531}
11532testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11533 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11534 var MSC_ConnHdlr vc_conn;
11535
11536 f_init(1, true);
11537 f_sleep(1.0);
11538
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011539 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11540 vc_conn.done;
11541
11542 f_shutdown_helper();
11543}
11544
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011545const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11546 { "all_allocated:sdcch", 0 },
11547 { "all_allocated:static_sdcch", 0 },
11548 { "all_allocated:tch", 0 },
11549 { "all_allocated:static_tch", 0 }
11550}
11551
11552private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11553{
11554 /* Make sure counters settle first */
11555 f_sleep(1.0);
11556
11557 /* Take a baseline of counters */
11558 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11559
11560 /* Elapse some time so that we see changes in counters, hopefully where expected */
11561 f_sleep(2.0);
11562
11563 /* Get new counters */
11564 var charstring_list all_changed := {};
11565 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11566 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11567
11568 /* Compare with expectations */
11569 var charstring_list all_expect_changed := {};
11570 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11571 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11572 }
11573 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11574}
11575
11576testcase TC_ratectr_all_available_allocated() runs on test_CT {
11577 var ASP_RSL_Unitdata rsl_ud;
11578 var integer i;
11579 var integer chreq_total, chreq_nochan;
11580
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011581 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011582 f_sleep(1.0);
11583
11584 /* Exhaust all dedicated SDCCH lchans.
11585 /* GSM 44.018 Table 9.1.8.2:
11586 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11587 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011588 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011589 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011590 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011591 }
11592
11593 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11594 * level.
11595 * All SDCCH are now occupied. */
11596 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11597
11598 /* Also fill up all remaining (TCH) channels */
11599 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011600 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011601 }
11602
11603 /* All TCH are now also occupied */
11604 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11605 "all_allocated:tch", "all_allocated:static_tch"});
11606
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011607 /* Clean up SDCCH lchans */
11608 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11609 f_perform_clear_test_ct(chan_cleanup[i]);
11610 }
11611
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011612 f_shutdown_helper();
11613}
11614
11615testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11616 var ASP_RSL_Unitdata rsl_ud;
11617 var integer i;
11618 var integer chreq_total, chreq_nochan;
11619
11620 f_init_vty();
11621 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11622 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11623 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11624
11625 f_init(1, guard_timeout := 60.0);
11626 f_sleep(1.0);
11627
11628 /* The dyn TS wants to activate PDCH mode, ACK that. */
11629 var RslChannelNr chan_nr;
11630 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011631 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11632 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011633
11634 /* Exhaust all dedicated SDCCH lchans.
11635 /* GSM 44.018 Table 9.1.8.2:
11636 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11637 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011638 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011639 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011640 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011641 }
11642
11643 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11644 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11645 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11646
11647 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11648 * Will release them later, so remember all the DchanTuples. */
11649 var DchanTuples dyn_sddch := {};
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011650 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011651
11652 /* Also occupy the seven other SDCCH of the dyn TS */
11653 for (i := 0; i < 7; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011654 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011655 }
11656
11657 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11658 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11659
11660 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11661 for (i := 0; i < 5; i := i+1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011662 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, gen_l3_valid_payload()) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011663 }
11664
11665 /* All TCH lchans are now also occupied, both static and dynamic */
11666 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11667 "all_allocated:tch", "all_allocated:static_tch"});
11668
11669 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11670 * incrementing. */
11671 var BssmapCause cause := 0;
11672 var DchanTuple dt := dyn_sddch[0];
11673 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011674 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011675
11676 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11677 * count as occupied, so those still both increment. */
11678 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11679 "all_allocated:tch", "all_allocated:static_tch"});
11680
11681 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11682 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11683 dt := dyn_sddch[i];
11684 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011685 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011686 }
11687
11688 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11689 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011690 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11691 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011692
11693 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11694 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11695
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011696 /* Clean up SDCCH lchans */
11697 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11698 f_perform_clear_test_ct(chan_cleanup[i]);
11699 }
11700
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011701 /* clean up config */
11702 f_ts_reset_chcomb(0);
11703
11704 f_shutdown_helper();
11705}
11706
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011707private function f_TC_chan_alloc_algo(DchanTuple dt, BtsTrxIdx idx)
11708runs on test_CT {
11709 /* MSC sends an Assignment Request */
11710 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11711 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11712 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11713 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
11714
11715 /* Expect the BSC to allocate a TCH channel on the given BTS/TRX */
11716 var RSL_Message rsl_chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
11717 /* Send CHAN ACT NACK, so that the requested TCH channel becomes BORKEN */
11718 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(rsl_chan_act.ies[0].body.chan_nr, RSL_ERR_EQUIPMENT_FAIL), idx);
11719 /* Expect to receive an Assignment Failure */
11720 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail));
11721}
11722
11723testcase TC_chan_alloc_algo_ascending() runs on test_CT {
11724 /* We need to access BTS2, which has 4 TRXs */
11725 f_init(nr_bts := 3);
11726
11727 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011728 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011729
11730 f_vty_enter_cfg_bts(BSCVTY, 2);
11731 f_vty_transceive(BSCVTY, "channel allocator ascending");
11732 f_vty_transceive(BSCVTY, "end");
11733
11734 /* Expect the BSC to allocate 4 x TCH/F channels on BTS2/TRX0 */
11735 for (var integer i := 0; i < 4; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011736 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011737 f_TC_chan_alloc_algo(dt, {2, 0});
11738 f_perform_clear_test_ct(dt);
11739 }
11740
11741 /* At this point all 4 x TCH/F channels are BORKEN, but they will be
11742 * resurrected upon the A-bis/OML link re-establishment. */
11743 f_shutdown_helper();
11744}
11745
11746testcase TC_chan_alloc_algo_descending() runs on test_CT {
11747 /* We need to access BTS2, which has 4 TRXs */
11748 f_init(nr_bts := 3);
11749
11750 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011751 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011752
11753 f_vty_enter_cfg_bts(BSCVTY, 2);
11754 f_vty_transceive(BSCVTY, "channel allocator descending");
11755 f_vty_transceive(BSCVTY, "end");
11756
11757 /* Expect the BSC to allocate 5 x TCH/F channels on BTS2/TRX3 */
11758 for (var integer i := 0; i < 5; i := i + 1) {
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011759 var DchanTuple dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), {2, 0});
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011760 f_TC_chan_alloc_algo(dt, {2, 3});
11761 f_perform_clear_test_ct(dt);
11762 }
11763
11764 /* At this point all 5 x TCH/F channels are BORKEN, but they will be
11765 * resurrected upon the A-bis/OML link re-establishment. */
11766 f_shutdown_helper();
11767}
11768
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011769testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
11770 const BtsTrxIdx TRX0 := {2, 0};
11771 const BtsTrxIdx TRX3 := {2, 3};
11772
11773 /* We need to access BTS2, which has 4 TRXs */
11774 f_init(nr_bts := 3);
11775
11776 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011777 vc_MGCP[0].stop;
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011778
11779 f_vty_enter_cfg_bts(BSCVTY, 2);
11780 f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
11781 f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
11782 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
11783 f_vty_transceive(BSCVTY, "end");
11784
11785 var DchanTuple dt;
11786
11787 f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011788 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011789 f_TC_chan_alloc_algo(dt, TRX0);
11790 f_perform_clear_test_ct(dt);
11791
11792 f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011793 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011794 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11795 ts_RSL_IE_UplinkMeas(30, 0),
11796 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011797 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011798 f_TC_chan_alloc_algo(dt, TRX0);
11799 f_perform_clear_test_ct(dt);
11800
11801 f_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011802 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011803 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11804 ts_RSL_IE_UplinkMeas(45, 0),
11805 ts_RSL_IE_BS_Power(0)), TRX0);
11806 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11807 ts_RSL_IE_UplinkMeas(48, 0),
11808 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011809 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011810 f_TC_chan_alloc_algo(dt, TRX0);
11811 f_perform_clear_test_ct(dt);
11812
11813 f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011814 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011815 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11816 ts_RSL_IE_UplinkMeas(50, 0),
11817 ts_RSL_IE_BS_Power(0)), TRX0);
11818 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11819 ts_RSL_IE_UplinkMeas(58, 0),
11820 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011821 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011822 f_TC_chan_alloc_algo(dt, TRX3);
11823 f_perform_clear_test_ct(dt);
11824
11825 f_vty_enter_cfg_bts(BSCVTY, 2);
11826 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
11827 f_vty_transceive(BSCVTY, "end");
11828
11829 f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
Pau Espin Pedrolcc77b492023-01-02 18:56:37 +010011830 dt := f_est_dchan('23'O, 23, gen_l3_valid_payload(), TRX0);
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011831 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11832 ts_RSL_IE_UplinkMeas(50, 0),
11833 ts_RSL_IE_BS_Power(0)), TRX0);
11834 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11835 ts_RSL_IE_UplinkMeas(58, 0),
11836 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011837 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011838 f_TC_chan_alloc_algo(dt, TRX0);
11839 f_perform_clear_test_ct(dt);
11840
11841 f_vty_enter_cfg_bts(BSCVTY, 2);
11842 f_vty_transceive(BSCVTY, "channel allocator ascending");
11843 f_vty_transceive(BSCVTY, "end");
11844
11845 /* At this point some TCH/F channels are BORKEN, but they will be
11846 * resurrected upon the A-bis/OML link re-establishment. */
11847 f_shutdown_helper();
11848}
11849
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020011850private function f_vty_mgw_enable(integer mgw_nr := 1) runs on test_CT {
11851 var rof_charstring cmds := {
11852 "remote-ip " & mp_test_ip,
11853 "remote-port " & int2str(2427 + mgw_nr)
11854 };
11855 f_vty_config3(BSCVTY, {"network", "mgw " & int2str(mgw_nr)}, cmds);
11856 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " reconnect")
11857}
11858private function f_vty_mgw_disable(integer mgw_nr := 1) runs on test_CT {
11859 f_vty_config3(BSCVTY, {"network"}, { "no mgw " &int2str(mgw_nr) });
11860}
11861private function f_vty_mgw_block(integer mgw_nr := 1, boolean blocked := true) runs on test_CT {
11862 var charstring arg;
11863 if (blocked) {
11864 arg := "block";
11865 } else {
11866 arg := "unblock";
11867 }
11868 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " " & arg);
11869}
11870private const charstring COORD_CMD_ESTABLISHED := "COORD_CMD_ESTABLISHED";
11871private function f_TC_mgwpool_call_seq_1(charstring id) runs on MSC_ConnHdlr {
11872 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11873 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11874 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11875 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11876
11877 f_establish_fully(ass_cmd, exp_compl);
11878 COORD.send(COORD_CMD_ESTABLISHED);
11879
11880 COORD.receive(COORD_CMD_ESTABLISHED);
11881 f_perform_clear()
11882 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11883}
11884private function f_TC_mgwpool_call_seq_2(charstring id) runs on MSC_ConnHdlr {
11885 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11886 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11887 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11888 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11889
11890
11891 COORD.receive(COORD_CMD_ESTABLISHED);
11892 f_establish_fully(ass_cmd, exp_compl);
11893 COORD.send(COORD_CMD_ESTABLISHED);
11894
11895 f_perform_clear()
11896 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11897}
11898/* Test load is spread around 2 available MGWs */
11899testcase TC_mgwpool_all_used() runs on test_CT {
11900 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11901 var MSC_ConnHdlr vc_conn1;
11902 pars1.mgwpool_idx := 0;
11903
11904 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11905 var MSC_ConnHdlr vc_conn2;
11906 pars2.mgwpool_idx := 1;
11907
11908 f_init(1, true, nr_mgw := 2);
11909 f_sleep(1.0);
11910
11911 f_vty_mgw_enable(1);
11912
11913 vc_conn1 := f_start_handler_create(pars1);
11914 vc_conn2 := f_start_handler_create(pars2);
11915 connect(vc_conn1:COORD, vc_conn2:COORD);
11916 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11917 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11918 vc_conn1.done;
11919 vc_conn2.done;
11920
11921 f_vty_mgw_disable(1);
11922
11923 f_shutdown_helper();
11924}
11925
11926/* Test blocked MGW in the pool are not selected */
11927testcase TC_mgwpool_blocked_not_used() runs on test_CT {
11928 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11929 var MSC_ConnHdlr vc_conn1;
11930 pars1.mgwpool_idx := 0;
11931
11932 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11933 var MSC_ConnHdlr vc_conn2;
11934 pars2.mgwpool_idx := 0; /* expect it in the first one, since the second will be blocked */
11935 pars2.media_nr := 2;
11936
11937 f_init(1, true, nr_mgw := 2);
11938 f_sleep(1.0);
11939
11940 f_vty_mgw_enable(1);
11941 f_vty_mgw_block(1, true);
11942
11943 vc_conn1 := f_start_handler_create(pars1);
11944 vc_conn2 := f_start_handler_create(pars2);
11945 connect(vc_conn1:COORD, vc_conn2:COORD);
11946 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11947 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11948 vc_conn1.done;
11949 vc_conn2.done;
11950
11951 f_vty_mgw_disable(1);
11952
11953 f_shutdown_helper();
11954}
11955
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020011956/* Test BTS pinning to an MGW is applied */
11957testcase TC_mgwpool_pin_bts() runs on test_CT {
11958 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11959 var MSC_ConnHdlr vc_conn1;
11960 pars1.mgwpool_idx := 0;
11961
11962 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11963 var MSC_ConnHdlr vc_conn2;
11964 pars2.mgwpool_idx := 0; /* expect it in the first one, since the BTS is pinned to the first MGW */
11965 pars2.media_nr := 2;
11966
11967 f_init(1, true, nr_mgw := 2);
11968 f_sleep(1.0);
11969
11970 f_vty_mgw_enable(1);
11971 f_vty_cfg_bts(BSCVTY, 0, { "mgw pool-target 0" });
11972
11973 vc_conn1 := f_start_handler_create(pars1);
11974 vc_conn2 := f_start_handler_create(pars2);
11975 connect(vc_conn1:COORD, vc_conn2:COORD);
11976 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11977 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11978 vc_conn1.done;
11979 vc_conn2.done;
11980
11981 f_vty_cfg_bts(BSCVTY, 0, { "no mgw pool-target" } );
Vadim Yanitskiy389d7e02022-10-25 17:44:05 +070011982 f_vty_mgw_disable(1);
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020011983
11984 f_shutdown_helper();
11985}
11986
Oliver Smithc9a5f532022-10-21 11:32:23 +020011987private function f_tc_ho_meas_rep_multi_band(charstring id) runs on MSC_ConnHdlr {
11988 g_pars := f_gen_test_hdlr_pars();
11989 var PDU_BSSAP ass_req := f_gen_ass_req();
11990 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11991 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11992 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11993 f_establish_fully(ass_req, exp_compl);
11994
11995 /* Send a measurement report with bad rxlev except on 3rd entry. The
11996 * measurement report is divided into two sub lists, as described in
11997 * 3GPP TS 04.08 § 10.5.2.20. */
11998 var NcellReports neighbor_rep := {
11999 /* Sub list 1: same band */
Oliver Smitha6773042022-10-24 12:56:30 +020012000 { rxlev := 0, bcch_freq := 0, bsic := 12 }, /* ARFCN 800, band 1800, LAC 98 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012001 /* Sub list 2: different band */
Oliver Smitha6773042022-10-24 12:56:30 +020012002 { rxlev := 0, bcch_freq := 1, bsic := 13 }, /* ARFCN 200, band 850, LAC 97 */
12003 { rxlev := 40, bcch_freq := 2, bsic := 14 }, /* ARFCN 1000, band 900, LAC 99 */
12004 { rxlev := 0, bcch_freq := 3, bsic := 11 } /* ARFCN 0, band 900, LAC 96 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012005 };
12006 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
12007 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
12008 l3_mr, 0));
12009
12010 /* Expect a handover to the third entry. If the BSC parsed the report
Oliver Smitha6773042022-10-24 12:56:30 +020012011 * correctly, the third entry has LAC 99. */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012012 var template BSSMAP_FIELD_CellIdentificationList cid_list := {
Oliver Smitha6773042022-10-24 12:56:30 +020012013 cIl_LAC := { ts_BSSMAP_CI_LAC(99) }
Oliver Smithc9a5f532022-10-21 11:32:23 +020012014 };
12015 alt {
12016 [] BSSAP.receive(tr_BSSMAP_HandoverRequired(cid_list := cid_list)) {
12017 setverdict(pass);
12018 }
12019 [] BSSAP.receive(tr_BSSMAP_HandoverRequired()) {
12020 setverdict(fail, "Handover has unexpected LAC in Cell Identification List. The BSC probably"
12021 & " didn't parse the multi-band measurement report correctly.");
12022 }
12023 }
12024
12025 f_ho_out_of_this_bsc(skip_meas_rep := true);
12026}
12027testcase TC_ho_meas_rep_multi_band() runs on test_CT {
12028 /* Verify that the BSC parses the measurement report correctly when
12029 * neighbors in multiple bands are configured (OS#5717). See
12030 * gsm_arfcn2band_rc() in libosmocore src/gsm/gsm_utils.c for the
12031 * ARFCN -> band mapping. The MS is connected to band 1800. */
12032 var MSC_ConnHdlr vc_conn;
12033
12034 f_init_vty();
12035 f_bts_0_cfg(BSCVTY,
12036 {"neighbor-list mode automatic",
12037 "handover 1",
12038 "handover algorithm 2",
12039 "handover2 window rxlev averaging 1",
12040 "no neighbors",
12041 "neighbor lac 99 arfcn 1000 bsic any", /* band 900 */
12042 "neighbor lac 98 arfcn 800 bsic any", /* band 1800 */
12043 "neighbor lac 97 arfcn 200 bsic any", /* band 850 */
Oliver Smitha6773042022-10-24 12:56:30 +020012044 "neighbor lac 96 arfcn 0 bsic any"}); /* band 900 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012045 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
12046
12047 f_init(1, true);
12048 f_sleep(1.0);
12049
12050 f_ctrs_bsc_and_bts_handover_init();
12051
12052 vc_conn := f_start_handler(refers(f_tc_ho_meas_rep_multi_band));
12053 vc_conn.done;
12054
12055 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
12056 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
12057 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
12058 f_ctrs_bsc_and_bts_add(0, "handover:completed");
12059 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
12060 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
12061 f_ctrs_bsc_and_bts_verify();
12062 f_shutdown_helper(ho := true);
12063}
12064
Harald Welte28d943e2017-11-25 15:00:50 +010012065control {
Harald Welte898113b2018-01-31 18:32:21 +010012066 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010012067 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010012068 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020012069 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
12070 * these in the AoIP test suite. */
12071 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12072 execute( TC_stat_num_msc_connected_1() );
12073 execute( TC_stat_num_msc_connected_2() );
12074 execute( TC_stat_num_msc_connected_3() );
12075 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020012076 execute( TC_stat_num_bts_connected_1() );
12077 execute( TC_stat_num_bts_connected_2() );
12078 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010012079 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012080 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020012081 execute( TC_ctrl_location() );
12082 }
Harald Welte898113b2018-01-31 18:32:21 +010012083
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012084 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020012085 execute( TC_si2quater_2_earfcns() );
12086 execute( TC_si2quater_3_earfcns() );
12087 execute( TC_si2quater_4_earfcns() );
12088 execute( TC_si2quater_5_earfcns() );
12089 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020012090 execute( TC_si2quater_12_earfcns() );
12091 execute( TC_si2quater_23_earfcns() );
12092 execute( TC_si2quater_32_earfcns() );
12093 execute( TC_si2quater_33_earfcns() );
12094 execute( TC_si2quater_42_earfcns() );
12095 execute( TC_si2quater_48_earfcns() );
12096 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020012097 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020012098 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012099
Harald Welte898113b2018-01-31 18:32:21 +010012100 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010012101 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010012102 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010012103 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020012104 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020012105 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010012106 execute( TC_chan_act_ack_est_ind_noreply() );
12107 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010012108 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010012109 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070012110 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010012111 execute( TC_chan_rel_rll_rel_ind() );
12112 execute( TC_chan_rel_conn_fail() );
12113 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020012114 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
12115 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010012116 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010012117 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020012118 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010012119 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010012120 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020012121 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010012122
Harald Weltecfe2c962017-12-15 12:09:32 +010012123 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010012124
12125 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010012126 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010012127 execute( TC_assignment_csd() );
12128 execute( TC_assignment_ctm() );
12129 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012130 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12131 execute( TC_assignment_aoip_tla_v6() );
12132 }
Harald Welte235ebf12017-12-15 14:18:16 +010012133 execute( TC_assignment_fr_a5_0() );
12134 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012135 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020012136 execute( TC_assignment_fr_a5_1_codec_missing() );
12137 }
Harald Welte235ebf12017-12-15 14:18:16 +010012138 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020012139 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020012140 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020012141 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012142 execute( TC_ciph_mode_a5_0() );
12143 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020012144 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020012145 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012146 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020012147 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010012148
Harald Welte60aa5762018-03-21 19:33:13 +010012149 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020012150 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010012151 execute( TC_assignment_codec_hr() );
12152 execute( TC_assignment_codec_efr() );
12153 execute( TC_assignment_codec_amr_f() );
12154 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012155
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012156 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010012157 execute( TC_assignment_codec_amr_f_S1() );
12158 execute( TC_assignment_codec_amr_h_S1() );
12159 execute( TC_assignment_codec_amr_f_S124() );
12160 execute( TC_assignment_codec_amr_h_S124() );
12161 execute( TC_assignment_codec_amr_f_S0() );
12162 execute( TC_assignment_codec_amr_f_S02() );
12163 execute( TC_assignment_codec_amr_f_S024() );
12164 execute( TC_assignment_codec_amr_f_S0247() );
12165 execute( TC_assignment_codec_amr_h_S0() );
12166 execute( TC_assignment_codec_amr_h_S02() );
12167 execute( TC_assignment_codec_amr_h_S024() );
12168 execute( TC_assignment_codec_amr_h_S0247() );
12169 execute( TC_assignment_codec_amr_f_S01234567() );
12170 execute( TC_assignment_codec_amr_f_S0234567() );
12171 execute( TC_assignment_codec_amr_f_zero() );
12172 execute( TC_assignment_codec_amr_f_unsupp() );
12173 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000012174 execute( TC_assignment_codec_amr_f_start_mode_auto() );
12175 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000012176 execute( TC_assignment_codec_amr_f_start_mode_4() );
12177 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000012178 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012179 }
Harald Welte60aa5762018-03-21 19:33:13 +010012180
Philipp Maierac09bfc2019-01-08 13:41:39 +010012181 execute( TC_assignment_codec_fr_exhausted_req_hr() );
12182 execute( TC_assignment_codec_fr_exhausted_req_fr() );
12183 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
12184 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
12185 execute( TC_assignment_codec_hr_exhausted_req_fr() );
12186 execute( TC_assignment_codec_hr_exhausted_req_hr() );
12187 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
12188 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
12189 execute( TC_assignment_codec_req_hr_fr() );
12190 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020012191 execute( TC_assignment_sdcch_exhausted_req_signalling() );
12192 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
12193 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010012194
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +020012195 execute( TC_assignment_codec_hr_osmux_on() );
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020012196 execute( TC_assignment_osmux() );
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020012197 execute( TC_assignment_osmux_cn() );
12198 execute( TC_assignment_osmux_bts() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020012199
Harald Welte898113b2018-01-31 18:32:21 +010012200 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010012201 execute( TC_rll_est_ind_inact_lchan() );
12202 execute( TC_rll_est_ind_inval_sapi1() );
12203 execute( TC_rll_est_ind_inval_sapi3() );
12204 execute( TC_rll_est_ind_inval_sacch() );
12205
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070012206 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
12207 execute( TC_tch_dlci_link_id_sapi() );
12208
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012209 /* SAPI N Reject triggered by RLL establishment failures */
12210 execute( TC_rll_rel_ind_sapi_n_reject() );
12211 execute( TC_rll_err_ind_sapi_n_reject() );
12212 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070012213 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012214
Harald Welte898113b2018-01-31 18:32:21 +010012215 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010012216 execute( TC_paging_imsi_nochan() );
12217 execute( TC_paging_tmsi_nochan() );
12218 execute( TC_paging_tmsi_any() );
12219 execute( TC_paging_tmsi_sdcch() );
12220 execute( TC_paging_tmsi_tch_f() );
12221 execute( TC_paging_tmsi_tch_hf() );
12222 execute( TC_paging_imsi_nochan_cgi() );
12223 execute( TC_paging_imsi_nochan_lac_ci() );
12224 execute( TC_paging_imsi_nochan_ci() );
12225 execute( TC_paging_imsi_nochan_lai() );
12226 execute( TC_paging_imsi_nochan_lac() );
12227 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010012228 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
12229 execute( TC_paging_imsi_nochan_rnc() );
12230 execute( TC_paging_imsi_nochan_lac_rnc() );
12231 execute( TC_paging_imsi_nochan_lacs() );
12232 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010012233 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010012234 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010012235 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010012236 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010012237 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020012238 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020012239 execute( TC_paging_450req_no_paging_load_ind() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010012240
12241 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010012242 execute( TC_rsl_unknown_unit_id() );
12243
12244 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012245
12246 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020012247 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012248 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010012249 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010012250 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010012251 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010012252 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012253
Harald Welte261af4b2018-02-12 21:20:39 +010012254 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020012255 execute( TC_ho_int_a5_0() );
12256 execute( TC_ho_int_a5_1() );
12257 execute( TC_ho_int_a5_3() );
12258 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000012259 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012260
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012261 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020012262 execute( TC_ho_out_fail_no_msc_response() );
12263 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020012264 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012265
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012266 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020012267 execute( TC_ho_into_this_bsc_a5_0() );
12268 execute( TC_ho_into_this_bsc_a5_1() );
12269 execute( TC_ho_into_this_bsc_a5_3() );
12270 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010012271 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
12272 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010012273 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012274 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12275 execute( TC_ho_into_this_bsc_tla_v6() );
12276 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020012277 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030012278 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010012279 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020012280 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020012281 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
12282 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012283 execute( TC_ho_in_fail_msc_clears() );
12284 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
12285 execute( TC_ho_in_fail_no_detect() );
12286 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010012287 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012288
Neels Hofmeyr91401012019-07-11 00:42:35 +020012289 execute( TC_ho_neighbor_config_1() );
12290 execute( TC_ho_neighbor_config_2() );
12291 execute( TC_ho_neighbor_config_3() );
12292 execute( TC_ho_neighbor_config_4() );
12293 execute( TC_ho_neighbor_config_5() );
12294 execute( TC_ho_neighbor_config_6() );
12295 execute( TC_ho_neighbor_config_7() );
12296
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012297 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010012298 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010012299 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020012300
12301 execute( TC_dyn_pdch_ipa_act_deact() );
12302 execute( TC_dyn_pdch_ipa_act_nack() );
12303 execute( TC_dyn_pdch_osmo_act_deact() );
12304 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010012305 execute( TC_dyn_ts_sdcch8_act_deact() );
12306 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
12307 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
12308 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012309
Stefan Sperling0796a822018-10-05 13:01:39 +020012310 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020012311 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020012312
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010012313 /* Power control related */
12314 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020012315 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020012316
12317 /* MSC pooling */
12318 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
12319 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
12320 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
12321 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
12322 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12323 execute( TC_mscpool_L3Compl_on_1_msc() );
12324 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
12325 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
12326 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
12327 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
12328 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
12329 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
12330 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
12331 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
12332 execute( TC_mscpool_paging_and_response_imsi() );
12333 execute( TC_mscpool_paging_and_response_tmsi() );
12334 execute( TC_mscpool_no_allow_attach_round_robin() );
12335 execute( TC_mscpool_no_allow_attach_valid_nri() );
12336 }
12337
Harald Welte99f3ca02018-06-14 13:40:29 +020012338 execute( TC_early_conn_fail() );
12339 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020012340 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012341
Philipp Maier783681c2020-07-16 16:47:06 +020012342 /* Emergency call handling (deny / allow) */
12343 execute( TC_assignment_emerg_setup_allow() );
12344 execute( TC_assignment_emerg_setup_deny_msc() );
12345 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020012346 execute( TC_emerg_premption() );
12347
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070012348 /* Frequency hopping parameters handling */
12349 execute( TC_fh_params_chan_activ() );
12350 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070012351 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070012352 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070012353 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012354
12355 if (mp_enable_lcs_tests) {
12356 execute( TC_lcs_loc_req_for_active_ms() );
12357 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
12358 execute( TC_lcs_loc_req_for_idle_ms() );
12359 execute( TC_lcs_loc_req_no_subscriber() );
12360 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
12361 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
12362 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
12363 execute( TC_cm_service_during_lcs_loc_req() );
12364 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020012365 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020012366 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() );
12367 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012368 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000012369
12370 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000012371
12372 execute( TC_refuse_chan_act_to_vamos() );
12373 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000012374
12375 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020012376
12377 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020012378
12379 execute( TC_imm_ass_post_chan_ack() );
12380 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020012381 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020012382 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020012383 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020012384
12385 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012386
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020012387 execute( TC_ratectr_all_available_allocated() );
12388 execute( TC_ratectr_all_available_allocated_dyn() );
12389
Neels Hofmeyrb7581872021-11-07 14:02:49 +010012390 execute( TC_cm_serv_rej() );
12391
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012392 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012393
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012394 /* Channel allocator */
12395 execute( TC_chan_alloc_algo_ascending() );
12396 execute( TC_chan_alloc_algo_descending() );
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012397 execute( TC_chan_alloc_algo_ass_dynamic() );
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012398
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012399 /* MGW pool */
12400 /* TODO: this conditional canbe dropped once osmo-bsc >1.10.0 is released: */
12401 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
12402 execute( TC_mgwpool_all_used() );
12403 execute( TC_mgwpool_blocked_not_used() );
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012404 execute( TC_mgwpool_pin_bts() );
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012405 }
12406
Oliver Smithc9a5f532022-10-21 11:32:23 +020012407 execute( TC_ho_meas_rep_multi_band() );
12408
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012409 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
12410 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
12411 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010012412}
12413
12414}