blob: 501b3e9384f74405cca6fb4414d54587d80c8ceb [file] [log] [blame]
Harald Welte28d943e2017-11-25 15:00:50 +01001module BSC_Tests {
2
Harald Welte21b46bd2017-12-17 19:46:32 +01003/* Integration Tests for OsmoBSC
Harald Weltea0630032018-03-20 21:09:55 +01004 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
Harald Welte21b46bd2017-12-17 19:46:32 +01005 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
Harald Welte34b5a952019-05-27 11:54:11 +020010 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
Harald Welte21b46bd2017-12-17 19:46:32 +010012 * This test suite tests OsmoBSC while emulating both multiple BTS + MS as
13 * well as the MSC. See README for more details.
14 *
15 * There are test cases that run in so-called 'handler mode' and test cases
16 * that run directly on top of the BSSAP and RSL CodecPorts. The "handler mode"
17 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
18 * and/or RSL channels and are hence suitable for higher-level test cases, while
19 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
20 * level testing.
21 */
22
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020023friend module BSC_Tests_VAMOS;
Vadim Yanitskiy5eb06a32022-06-23 18:39:46 +070024friend module BSC_Tests_CBSP;
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020025
Neels Hofmeyr4f118412020-06-04 15:25:10 +020026import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010027import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010028import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010029import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010030import from IPL4asp_Types all;
31
Harald Welte6f521d82017-12-11 19:52:02 +010032import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020033import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020034import from BSSAP_LE_Adapter all;
35import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020036import from BSSAP_LE_Types all;
37import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010038import from BSSAP_CodecPort all;
39import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010040import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010041import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010042import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020043import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010044import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010045import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010046import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010047import from MGCP_Templates all;
48import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020049import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010050
Harald Welte96c94412017-12-09 03:12:45 +010051import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010052import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010053import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010054
Daniel Willmannebdecc02020-08-12 15:30:17 +020055import from StatsD_Types all;
56import from StatsD_CodecPort all;
57import from StatsD_CodecPort_CtrlFunct all;
58import from StatsD_Checker all;
59
Harald Weltebc03c762018-02-12 18:09:38 +010060import from Osmocom_VTY_Functions all;
61import from TELNETasp_PortType all;
62
Harald Welte6f521d82017-12-11 19:52:02 +010063import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010064import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010065import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010066import from L3_Templates all;
67import from GSM_RR_Types all;
68
Stefan Sperlingc307e682018-06-14 15:15:46 +020069import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010070import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020071import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010072
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010073import from SCCPasp_Types all;
74
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020075import from GSM_SystemInformation all;
76import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020077import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020078
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060079const integer NUM_TRX := 4;
Harald Welte5d1a2202017-12-13 19:51:29 +010080const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020081const integer NUM_BTS_CFG := 4; /* we have 4 BTS in the osmo-bsc.cfg (for inter-BSC HO tests) but use only 3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060082const integer NUM_TRX_CFG := 1; /* we support up to 4 TRX per BTS, but have only 1 TRX per BTS in osmo-bsc.cfg */
Neels Hofmeyrf246a922020-05-13 02:27:10 +020083const integer NUM_MSC := 3;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020084const integer NUM_MGW := 2;
Harald Welteae026692017-12-09 01:03:01 +010085const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010086
Harald Welte799c97b2017-12-14 17:50:30 +010087/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020088const integer NUM_TCHH_PER_BTS := 2;
89const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020090const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010091
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060092friend type record BtsTrxIdx {
93 uint8_t bts,
94 uint8_t trx
95}
96
97private type record BtsParams {
98 integer trx_num,
99 integer tsc
100}
101
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200102/* Default Training Sequence Code expected for bts[i]:
103 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
104 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
105 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
106 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
107 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600108private const BtsParams c_BtsParams[NUM_BTS_CFG] := {
109 /* BTS0 */ { trx_num := 1, tsc := 2 },
110 /* BTS1 */ { trx_num := 1, tsc := 3 },
Vadim Yanitskiy7a3d2932022-05-29 20:37:46 +0600111 /* BTS2 */ { trx_num := 4, tsc := 4 },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600112 /* BTS3 */ { trx_num := 1, tsc := 4 }
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200113}
Harald Welte4003d112017-12-09 22:35:39 +0100114
Vadim Yanitskiy59494702022-09-14 15:29:04 +0700115private const RSL_IE_Body c_mr_conf_5_90 :=
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +0200116 valueof(RSL_IE_Body:{multirate_cfg := ts_RSL_MultirateCfg(true, 0, '00000100'B /* 5,90k */)});
117
Harald Welte21b46bd2017-12-17 19:46:32 +0100118/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100119type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100120 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100121 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100122}
123
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200124/* Default list of counters for an 'msc' entity. */
125const CounterNameVals counternames_msc_mscpool := {
126 { "mscpool:subscr:new", 0 },
127 { "mscpool:subscr:known", 0 },
128 { "mscpool:subscr:reattach", 0 },
129 { "mscpool:subscr:attach_lost", 0 },
130 { "mscpool:subscr:paged", 0 }
131};
132
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000133/* List of global mscpool counters, not related to a specific 'msc' entity. */
134const CounterNameVals counternames_bsc_mscpool := {
135 { "mscpool:subscr:no_msc", 0 }
136};
137
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000138/* Default list of counters for 'bsc' and 'bts' entities. */
139const CounterNameVals counternames_bsc_bts_handover := {
140 { "assignment:attempted", 0 },
141 { "assignment:completed", 0 },
142 { "assignment:stopped", 0 },
143 { "assignment:no_channel", 0 },
144 { "assignment:timeout", 0 },
145 { "assignment:failed", 0 },
146 { "assignment:error", 0 },
147
148 { "handover:attempted", 0 },
149 { "handover:completed", 0 },
150 { "handover:stopped", 0 },
151 { "handover:no_channel", 0 },
152 { "handover:timeout", 0 },
153 { "handover:failed", 0 },
154 { "handover:error", 0 },
155
156 { "intra_cell_ho:attempted", 0 },
157 { "intra_cell_ho:completed", 0 },
158 { "intra_cell_ho:stopped", 0 },
159 { "intra_cell_ho:no_channel", 0 },
160 { "intra_cell_ho:timeout", 0 },
161 { "intra_cell_ho:failed", 0 },
162 { "intra_cell_ho:error", 0 },
163
164 { "intra_bsc_ho:attempted", 0 },
165 { "intra_bsc_ho:completed", 0 },
166 { "intra_bsc_ho:stopped", 0 },
167 { "intra_bsc_ho:no_channel", 0 },
168 { "intra_bsc_ho:timeout", 0 },
169 { "intra_bsc_ho:failed", 0 },
170 { "intra_bsc_ho:error", 0 },
171
172 { "interbsc_ho_out:attempted", 0 },
173 { "interbsc_ho_out:completed", 0 },
174 { "interbsc_ho_out:stopped", 0 },
175 { "interbsc_ho_out:timeout", 0 },
176 { "interbsc_ho_out:failed", 0 },
177 { "interbsc_ho_out:error", 0 },
178
179 { "interbsc_ho_in:attempted", 0 },
180 { "interbsc_ho_in:completed", 0 },
181 { "interbsc_ho_in:stopped", 0 },
182 { "interbsc_ho_in:no_channel", 0 },
183 { "interbsc_ho_in:timeout", 0 },
184 { "interbsc_ho_in:failed", 0 },
185 { "interbsc_ho_in:error", 0 }
186};
187
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100188const CounterNameVals counternames_bts_handover := {
189 { "incoming_intra_bsc_ho:attempted", 0 },
190 { "incoming_intra_bsc_ho:completed", 0 },
191 { "incoming_intra_bsc_ho:stopped", 0 },
192 { "incoming_intra_bsc_ho:no_channel", 0 },
193 { "incoming_intra_bsc_ho:timeout", 0 },
194 { "incoming_intra_bsc_ho:failed", 0 },
195 { "incoming_intra_bsc_ho:error", 0 }
196};
197
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200198/* Set of all System Information received during one RSL port's startup.
199 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
200 * broadcast that SI type. That will be reflected as 'omit' here.
201 */
202type record SystemInformationConfig {
203 SystemInformationType1 si1 optional,
204 SystemInformationType2 si2 optional,
205 SystemInformationType2bis si2bis optional,
206 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200207 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200208 SystemInformationType3 si3 optional,
209 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100210 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200211 SystemInformationType5 si5 optional,
212 SystemInformationType5bis si5bis optional,
213 SystemInformationType5ter si5ter optional,
214 SystemInformationType6 si6 optional
215};
216
217const SystemInformationConfig SystemInformationConfig_omit := {
218 si1 := omit,
219 si2 := omit,
220 si2bis := omit,
221 si2ter := omit,
222 si2quater := omit,
223 si3 := omit,
224 si4 := omit,
225 si13 := omit,
226 si5 := omit,
227 si5bis := omit,
228 si5ter := omit,
229 si6 := omit
230};
231
232/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
233template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
234 template uint3_t meas_bw := 3)
235:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
236 meas_bw_presence := '1'B,
237 meas_bw := meas_bw);
238
239/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200240template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200241 template uint3_t prio := 3,
242 template (present) uint5_t thresh_high := 20,
243 template uint5_t thresh_low := 10,
244 template uint5_t qrxlevmin := 22)
245:= tr_EUTRAN_NeighbourCells(
246 cell_desc_list := cell_desc_list,
247 prio_presence := '1'B,
248 prio := prio,
249 thresh_high := thresh_high,
250 thresh_low_presence := '1'B,
251 thresh_low := thresh_low,
252 qrxlevmin_presence := '1'B,
253 qrxlevmin := qrxlevmin);
254
255template SystemInformationConfig SystemInformationConfig_default := {
256 si1 := {
257 cell_chan_desc := '8FB38000000000000000000000000000'O,
258 rach_control := {
259 max_retrans := RACH_MAX_RETRANS_7,
260 tx_integer := '1001'B,
261 cell_barr_access := false,
262 re_not_allowed := true,
263 acc := '0000010000000000'B
264 },
265 rest_octets := ?
266 },
267 si2 := {
268 bcch_freq_list := '00000000000000000000000000000000'O,
269 ncc_permitted := '11111111'B,
270 rach_control := {
271 max_retrans := RACH_MAX_RETRANS_7,
272 tx_integer := '1001'B,
273 cell_barr_access := false,
274 re_not_allowed := true,
275 acc := '0000010000000000'B
276 }
277 },
278 si2bis := omit,
279 si2ter := {
280 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
281 rest_octets := ?
282 },
283 si2quater := {
284 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
285 },
286 si3 := {
287 cell_id := 0,
288 lai := {
289 mcc_mnc := '001F01'H,
290 lac := 1
291 },
292 ctrl_chan_desc := {
293 msc_r99 := true,
294 att := true,
295 bs_ag_blks_res := 1,
296 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
297 si22ind := false,
298 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
299 spare := '00'B,
300 bs_pa_mfrms := 3,
301 t3212 := 30
302 },
303 cell_options := {
304 dn_ind := false,
305 pwrc := false,
306 dtx := MS_SHALL_USE_UL_DTX,
307 radio_link_tout_div4 := 7
308 },
309 cell_sel_par := {
310 cell_resel_hyst_2dB := 2,
311 ms_txpwr_max_cch := 7,
312 acs := '0'B,
313 neci := true,
314 rxlev_access_min := 0
315 },
316 rach_control := {
317 max_retrans := RACH_MAX_RETRANS_7,
318 tx_integer := '1001'B,
319 cell_barr_access := false,
320 re_not_allowed := true,
321 acc := '0000010000000000'B
322 },
323 rest_octets := {
324 sel_params := {
325 presence := '0'B,
326 params := omit
327 },
328 pwr_offset := {
329 presence := '0'B,
330 offset := omit
331 },
332 si_2ter_ind := '1'B,
333 early_cm_ind := '0'B,
334 sched_where := {
335 presence := '0'B,
336 where := omit
337 },
338 gprs_ind := {
339 presence := '1'B,
340 ind := {
341 ra_colour := 0,
342 si13_pos := '0'B
343 }
344 },
345 umts_early_cm_ind := '1'B,
346 si2_quater_ind := {
347 presence := '1'B,
348 ind := '0'B
349 },
350 iu_mode_ind := omit,
351 si21_ind := {
352 presence := '0'B,
353 pos := omit
354 }
355 }
356 },
357 si4 := {
358 lai := {
359 mcc_mnc := '001F01'H,
360 lac := 1
361 },
362 cell_sel_par := {
363 cell_resel_hyst_2dB := 2,
364 ms_txpwr_max_cch := 7,
365 acs := '0'B,
366 neci := true,
367 rxlev_access_min := 0
368 },
369 rach_control := {
370 max_retrans := RACH_MAX_RETRANS_7,
371 tx_integer := '1001'B,
372 cell_barr_access := false,
373 re_not_allowed := true,
374 acc := '0000010000000000'B
375 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200376 cbch_chan_desc := {
377 iei := '64'O,
378 v := {
379 chan_nr := {
380 u := {
381 sdcch4 := {
382 tag := '001'B,
383 sub_chan := 2
384 }
385 },
386 tn := 0
387 },
388 tsc := 2,
389 h := false,
390 arfcn := 871,
391 maio_hsn := omit
392 }
393 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200394 cbch_mobile_alloc := omit,
395 rest_octets := {
396 sel_params := {
397 presence := '0'B,
398 params := omit
399 },
400 pwr_offset := {
401 presence := '0'B,
402 offset := omit
403 },
404 gprs_ind := {
405 presence := '1'B,
406 ind := {
407 ra_colour := 0,
408 si13_pos := '0'B
409 }
410 },
411 s_presence := '0'B,
412 s := omit
413 }
414 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100415 si13 := {
416 rest_octets := {
417 presence := '1'B,
418 bcch_change_mark := ?,
419 si_change_field := '0000'B,
420 presence2 := '0'B,
421 si13_change_mark := omit,
422 gprs_ma := omit,
423 zero := '0'B, /* PBCCH not present in cell */
424 rac := 0,
425 spgc_ccch_sup := '0'B,
426 priority_access_thr := '110'B,
427 network_control_order := '00'B,
428 gprs_cell_opts := {
429 nmo := '01'B,
430 t3168 := '011'B,
431 t3192 := '010'B,
432 drx_timer_max := '011'B,
433 access_burst_type := '0'B,
434 control_ack_type := '1'B,
435 bs_cv_max := 15,
436 pan_presence := '1'B,
437 pan_dec := 1,
438 pan_inc := 1,
439 pan_max := '111'B,
440 ext_info_presence := ?,
441 ext_info_length := *,
442 ext_info := *
443 },
444 gprs_pwr_ctrl_params := {
445 alpha := 0,
446 t_avg_w := '10000'B,
447 t_avg_t := '10000'B,
448 pc_meas_chan := '0'B,
449 n_avg_i := '1000'B
450 }
451 }
452 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200453 si5 := {
454 bcch_freq_list := '10000000000000000000000000000000'O
455 },
456 si5bis := omit,
457 si5ter := {
458 extd_bcch_freq_list := '9E050020000000000000000000000000'O
459 },
460 si6 := {
461 cell_id := 0,
462 lai := {
463 mcc_mnc := '001F01'H,
464 lac := 1
465 },
466 cell_options := {
467 dtx_ext := '1'B,
468 pwrc := false,
469 dtx := '01'B,
470 radio_link_timeout := '0111'B
471 },
472 ncc_permitted := '11111111'B,
Vadim Yanitskiy348b07c2022-03-10 17:11:22 +0300473 rest_octets := {
474 pch_nch_info := ?,
475 vbs_vgcs_options := ?,
476 dtm_support := '0'B,
477 rac := omit,
478 max_lapdm := omit,
479 band_ind := '0'B /* C0 ARFCN indicates 1800 band */
480 }
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200481 }
482 };
483
484
485/* List of all the System Information received on all RSL ports */
486type record of SystemInformationConfig SystemInformationConfig_list;
487
488function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
489{
490 var RSL_IE_Body sysinfo_type_ie;
491 var RSL_IE_SysinfoType si_type;
492 var octetstring data;
493
494 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
495 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
496 mtc.stop;
497 }
498 si_type := sysinfo_type_ie.sysinfo_type;
499
500 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
501 var RSL_IE_Body bcch_ie;
502 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
503 data := bcch_ie.other.payload;
504 }
505 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
506 var RSL_IE_Body l3_ie;
507 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
508 data := l3_ie.l3_info.payload;
509 }
510 } else {
511 setverdict(fail, "Don't understand this System Information message");
512 mtc.stop;
513 }
514
515 var boolean handled := false;
516
517 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
518 handled := true;
519
520 if (si_type == RSL_SYSTEM_INFO_1) {
521 if (not isbound(data)) {
522 si.si1 := omit;
523 } else {
524 si.si1 := dec_SystemInformation(data).payload.si1;
525 }
526 } else if (si_type == RSL_SYSTEM_INFO_2) {
527 if (not isbound(data)) {
528 si.si2 := omit;
529 } else {
530 si.si2 := dec_SystemInformation(data).payload.si2;
531 }
532 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
533 if (not isbound(data)) {
534 si.si2bis := omit;
535 } else {
536 si.si2bis := dec_SystemInformation(data).payload.si2bis;
537 }
538 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
539 if (not isbound(data)) {
540 si.si2ter := omit;
541 } else {
542 si.si2ter := dec_SystemInformation(data).payload.si2ter;
543 }
544 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
545 if (not isbound(data)) {
546 si.si2quater := {};
547 } else {
548 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
549 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
550 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
551 }
552 } else if (si_type == RSL_SYSTEM_INFO_3) {
553 if (not isbound(data)) {
554 si.si3 := omit;
555 } else {
556 si.si3 := dec_SystemInformation(data).payload.si3;
557 }
558 } else if (si_type == RSL_SYSTEM_INFO_4) {
559 if (not isbound(data)) {
560 si.si4 := omit;
561 } else {
562 si.si4 := dec_SystemInformation(data).payload.si4;
563 }
564 } else if (si_type == RSL_SYSTEM_INFO_13) {
565 if (not isbound(data)) {
566 si.si13 := omit;
567 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100568 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200569 }
570 } else {
571 handled := false;
572 }
573 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
574 handled := true;
575
576 if (si_type == RSL_SYSTEM_INFO_5) {
577 if (not isbound(data)) {
578 si.si5 := omit;
579 } else {
580 si.si5 := dec_SystemInformation(data).payload.si5;
581 }
582 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
583 if (not isbound(data)) {
584 si.si5bis := omit;
585 } else {
586 si.si5bis := dec_SystemInformation(data).payload.si5bis;
587 }
588 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
589 if (not isbound(data)) {
590 si.si5ter := omit;
591 } else {
592 si.si5ter := dec_SystemInformation(data).payload.si5ter;
593 }
594 } else if (si_type == RSL_SYSTEM_INFO_6) {
595 if (not isbound(data)) {
596 si.si6 := omit;
597 } else {
598 si.si6 := dec_SystemInformation(data).payload.si6;
599 }
600 } else {
601 handled := false;
602 }
603 }
604
605 if (not handled) {
606 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
607 }
608}
609
Harald Weltea4ca4462018-02-09 00:17:14 +0100610type component test_CT extends CTRL_Adapter_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600611 /* Array of per-BTS/TRX state */
612 var BTS_State bts[NUM_BTS][NUM_TRX];
Harald Welte89ab1912018-02-23 18:56:29 +0100613 /* RSL common Channel Port (for RSL_Emulation) */
614 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600615 /* array of per-BTS/TRX RSL test ports */
616 port IPA_RSL_PT IPA_RSL[NUM_BTS][NUM_TRX];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100617 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200618 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
619 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200620 /* Configure/manage IPA_Emulation per-BTS/TRX port: */
621 port IPA_CFG_PT IPA_CFG_PORT[NUM_BTS][NUM_TRX];
Harald Weltea5d2ab22017-12-09 14:21:42 +0100622
Pau Espin Pedrol3c630532022-10-20 19:00:11 +0200623 var MGCP_Emulation_CT vc_MGCP[NUM_MGW];
624 var integer g_nr_mgw; /* number of vc_MGCP to initialize */
Harald Weltebc03c762018-02-12 18:09:38 +0100625 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100626
Daniel Willmannebdecc02020-08-12 15:30:17 +0200627 /* StatsD */
628 var StatsD_Checker_CT vc_STATSD;
629
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200630 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200631 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100632 /* for old legacy-tests only */
633 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200634 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100635
Harald Welte21b46bd2017-12-17 19:46:32 +0100636 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100637 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100638
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200639 /* Osmux is enabled through VTY */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200640 var boolean g_osmux_enabled_cn := false;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +0200641 var boolean g_osmux_enabled_bts := false;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200642
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100643 /*Configure T(tias) over VTY, seconds */
644 var integer g_bsc_sccp_timer_ias := 7 * 60;
645 /*Configure T(tiar) over VTY, seconds */
646 var integer g_bsc_sccp_timer_iar := 15 * 60;
647
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200648 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100649 timer T_guard := 30.0;
650
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200651 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000652 var CounterNameValsList g_ctr_bsc;
653 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200654
655 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
656 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100657}
658
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200659type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100660modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100661 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100662 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100663 /* port number to which to establish the IPA OML connections */
664 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100665 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100666 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100667 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100668 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200669 /* port number to which to listen for STATSD metrics */
670 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100671 /* IP address at which the test binds */
672 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100673
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200674 RAN_Configurations mp_bssap_cfg := {
675 {
676 transport := BSSAP_TRANSPORT_AoIP,
677 sccp_service_type := "mtp3_itu",
678 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
679 own_pc := 185, /* 0.23.1 first MSC emulation */
680 own_ssn := 254,
681 peer_pc := 187, /* 0.23.3 osmo-bsc */
682 peer_ssn := 254,
683 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200684 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200685 },
686 {
687 transport := BSSAP_TRANSPORT_AoIP,
688 sccp_service_type := "mtp3_itu",
689 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
690 own_pc := 2, /* 0.0.2 second MSC emulation */
691 own_ssn := 254,
692 peer_pc := 187, /* 0.23.3 osmo-bsc */
693 peer_ssn := 254,
694 sio := '83'O,
695 rctx := 2
696 },
697 {
698 transport := BSSAP_TRANSPORT_AoIP,
699 sccp_service_type := "mtp3_itu",
700 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
701 own_pc := 3, /* 0.0.3 third MSC emulation */
702 own_ssn := 254,
703 peer_pc := 187, /* 0.23.3 osmo-bsc */
704 peer_ssn := 254,
705 sio := '83'O,
706 rctx := 3
707 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100708 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200709
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200710 /* Must match per BTS config in osmo-bsc.cfg */
711 phys_chan_configs phys_chan_config := {
712 "CCCH+SDCCH4+CBCH",
713 "TCH/F",
714 "TCH/F",
715 "TCH/F",
716 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600717 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200718 "PDCH",
719 "PDCH"
720 };
721
Harald Welte47cd0e32020-08-21 12:39:11 +0200722 BSSAP_LE_Configuration mp_bssap_le_cfg := {
723 sccp_service_type := "mtp3_itu",
724 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200725 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200726 own_ssn := 252, /* SMLC side SSN */
727 peer_pc := 187, /* 0.23.3 osmo-bsc */
728 peer_ssn := 250, /* BSC side SSN */
729 sio := '83'O,
730 rctx := 6
731 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200732 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200733
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100734 /* Value set in osmo-bsc.cfg "ms max power" */
735 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600736
737 /* Whether to check for memory leaks */
738 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100739}
740
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200741friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200742
743 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200744 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200745 pars.aoip := true;
746 } else {
747 pars.aoip := false;
748 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100749 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200750 pars.mscpool.bssap_idx := bssap_idx;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600751 pars.expect_tsc := c_BtsParams[0].tsc;
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300752 pars.imsi := f_rnd_imsi('00101'H);
753
754 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200755
Philipp Maier48604732018-10-09 15:00:37 +0200756 return pars;
757}
758
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200759/* Convenience functions for rate counters using g_ctr_msc. */
760
761private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
762 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
763 log("initial msc rate counters: ", g_ctr_msc);
764}
765
766private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200767 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200768}
769
770/* f_ctrs_msc_init();
771 * f_do_thing(on_msc := 0);
772 * f_do_thing(on_msc := 0);
773 * f_do_other(on_msc := 1);
774 * f_ctrs_msc_add(0, "thing", 2);
775 * f_ctrs_msc_add(1, "other");
776 * f_ctrs_msc_verify();
777 */
778private function f_ctrs_msc_verify() runs on test_CT {
779 log("verifying msc rate counters: ", g_ctr_msc);
780 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
781}
782
783/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
784 * f_ctrs_msc_init();
785 * f_do_thing(on_msc := 0);
786 * f_do_thing(on_msc := 0);
787 * f_do_thing(on_msc := 0);
788 * f_ctrs_msc_expect(0, "thing", 3);
789 */
790private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
791 f_ctrs_msc_add(msc_nr, countername, val);
792 f_ctrs_msc_verify();
793}
794
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000795/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
796
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100797private function f_ctrs_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000798 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100799 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100800}
801
802function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
803 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000804 f_ctrs_bsc_init(counternames);
805}
806
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100807private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
808 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100809 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100810 f_ctrs_bsc_init(counternames_bsc_bts_handover);
811}
812
813private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000814 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100815}
816
817private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
818 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000819 f_ctrs_bsc_add(countername, val);
820}
821
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100822function f_ctrs_bts_verify() runs on test_CT {
823 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
824}
825
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000826/* f_ctrs_bsc_and_bts_init();
827 * f_do_thing(on_bts := 0);
828 * f_do_thing(on_bts := 0);
829 * f_do_other(on_bts := 1);
830 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
831 * f_ctrs_bsc_and_bts_add(1, "other");
832 * f_ctrs_bsc_and_bts_verify();
833 */
834private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100835 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000836 f_ctrs_bsc_verify();
837}
838
839/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
840 * f_ctrs_bsc_and_bts_init();
841 * f_do_thing(on_bts := 0);
842 * f_do_thing(on_bts := 0);
843 * f_do_thing(on_bts := 0);
844 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
845 */
846private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
847 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
848 f_ctrs_bsc_and_bts_verify();
849}
850
851
852/* Convenience functions for rate counters using g_ctr_bsc. */
853
854private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
855 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
856 log("initial bsc rate counters: ", g_ctr_bsc);
857}
858
859private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
860 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
861}
862
863/* f_ctrs_bsc_init();
864 * f_do_thing();
865 * f_do_thing();
866 * f_do_other();
867 * f_ctrs_bsc_add("thing", 2);
868 * f_ctrs_bsc_add("other");
869 * f_ctrs_bsc_verify();
870 */
871private function f_ctrs_bsc_verify() runs on test_CT {
872 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
873}
874
875/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
876 * f_ctrs_bsc_init();
877 * f_do_thing();
878 * f_ctrs_bsc_expect("thing", 1);
879 */
880private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
881 f_ctrs_bsc_add(countername, val);
882 f_ctrs_bsc_verify();
883}
884
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200885
Oliver Smith39f53072022-10-27 14:44:04 +0200886friend function f_shutdown_helper(boolean ho := false) runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100887 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600888 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100889 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
890 }
891
Oliver Smith39f53072022-10-27 14:44:04 +0200892 /* Reset handover related configuration */
893 if (ho) {
894 f_bts_0_cfg(BSCVTY,
895 {"no neighbors",
896 "neighbor-list mode manual-si5",
897 "neighbor-list add arfcn 100",
898 "neighbor-list add arfcn 200",
899 "si5 neighbor-list add arfcn 10",
900 "si5 neighbor-list add arfcn 20",
901 "handover algorithm 1"});
902 }
903
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200904 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100905 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200906 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100907}
908
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200909private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100910 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200911 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100912 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200913 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200914 ts_BSSMAP_Reset(0, g_osmux_enabled_cn)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100915 T.start;
916 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200917 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200918 tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200919 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100920 }
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200921 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200922 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100923 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200924 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200925 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100926 repeat;
927 }
928 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200929 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200930 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200931 /* If we received a RESET after ours was sent, it
932 may be a race condition where the other peer beacame
933 available after we sent it, but we are in a desired
934 state anyway, so go forward. */
935 if (not reset_received) {
936 setverdict(fail);
937 }
938 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100939 }
Harald Welte28d943e2017-11-25 15:00:50 +0100940}
941
Harald Welteae026692017-12-09 01:03:01 +0100942type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100943 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100944 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100945 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100946 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100947 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100948 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100949 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100950 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100951}
952
Harald Welte21b46bd2017-12-17 19:46:32 +0100953/*! Start the IPA/RSL related bits for one IPA_Client.
954 * \param clnt IPA_Client for which to establish
955 * \param bsc_host IP address / hostname of the BSC
956 * \param bsc_port TCP port number of the BSC
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600957 * \param idx BTS/TRX index values
Harald Welte21b46bd2017-12-17 19:46:32 +0100958 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600959function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port,
960 BtsTrxIdx idx := {0, 0}, boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100961runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100962 timer T := 10.0;
963
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600964 clnt.id := "IPA-BTS" & int2str(idx.bts) & "-TRX" & int2str(idx.trx) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100965 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100966 clnt.ccm_pars := c_IPA_default_ccm_pars;
967 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600968 clnt.ccm_pars.unit_id := int2str(1234 + idx.bts) & "/0/" & int2str(idx.trx);
Harald Welte624f9632017-12-16 19:26:04 +0100969 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100970 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600971 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[idx.bts]);
Harald Welte624f9632017-12-16 19:26:04 +0100972 }
Harald Welteae026692017-12-09 01:03:01 +0100973
974 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200975 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100976 if (handler_mode) {
977 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
978 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600979 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100980 }
Harald Welteae026692017-12-09 01:03:01 +0100981
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600982 var integer local_port := 10000 + idx.bts * 1000 + idx.trx;
983 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", local_port, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100984 if (handler_mode) {
985 clnt.vc_RSL.start(RSL_Emulation.main());
986 return;
987 }
Harald Welteae026692017-12-09 01:03:01 +0100988
989 /* wait for IPA RSL link to connect and send ID ACK */
990 T.start;
991 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600992 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100993 T.stop;
Harald Welteae026692017-12-09 01:03:01 +0100994 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600995 [] IPA_RSL[idx.bts][idx.trx].receive(ASP_IPA_Event:?) { repeat }
996 [] IPA_RSL[idx.bts][idx.trx].receive { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100997 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100998 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200999 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +01001000 }
1001 }
1002}
1003
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001004function f_ipa_rsl_stop(inout IPA_Client clnt, BtsTrxIdx idx := {0, 0}) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001005 var IPL4asp_Types.Result res := {
1006 errorCode := omit,
1007 connId := omit,
1008 os_error_code := omit,
1009 os_error_text := omit
1010 };
1011
Harald Welte12055472018-03-17 20:10:08 +01001012 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
1013 return;
1014 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001015
1016 /* Alive components don't finish sockets (TCP FIN) when they are
1017 * stopped. Hence, we need to manually call close() on them to make sure
1018 * the IUT knows about it. */
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001019 f_ipa_cfg_disconnect(IPA_CFG_PORT[idx.bts][idx.trx], res);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001020
Harald Welte12055472018-03-17 20:10:08 +01001021 clnt.vc_IPA.stop;
1022 if (isbound(clnt.vc_RSL)) {
1023 clnt.vc_RSL.stop;
1024 }
1025}
1026
Harald Welte21b46bd2017-12-17 19:46:32 +01001027/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +01001028function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1029 timer T := secs_max;
1030 T.start;
1031 while (true) {
1032 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1033 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001034 /* the 'degraded' state exists from OML connection time, and we have to wait
1035 * until all MO's are initialized */
1036 T.start(1.0);
1037 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001038 return;
1039 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001040 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001041 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001042 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001043 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001044 }
1045 }
1046}
1047
Harald Welte21b46bd2017-12-17 19:46:32 +01001048/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001049altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001050 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001051 [] T_guard.timeout {
1052 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001053 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001054 }
Harald Welte60e823a2017-12-10 14:10:59 +01001055 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001056 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001057 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001058 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Harald Welte69c1c262017-12-13 21:02:08 +01001059 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001060 }
Harald Welte28d943e2017-11-25 15:00:50 +01001061}
1062
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001063altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001064 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001065 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001066 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001067 }
1068}
1069
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001070function f_init_mgcp(integer mgw_nr, charstring id) runs on test_CT {
1071 id := id & "-MGCP-" & int2str(mgw_nr);
Daniel Willmann191e0d92018-01-17 12:44:35 +01001072
1073 var MGCPOps ops := {
1074 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1075 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1076 };
1077 var MGCP_conn_parameters mgcp_pars := {
1078 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001079 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001080 mgw_ip := mp_test_ip,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001081 mgw_udp_port := 2427 + mgw_nr,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001082 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
Pau Espin Pedrol36eeaf72022-10-20 16:50:31 +02001083 the one with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001084 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001085 };
1086
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001087 vc_MGCP[mgw_nr] := MGCP_Emulation_CT.create(id) alive;
1088 vc_MGCP[mgw_nr].start(MGCP_Emulation.main(ops, mgcp_pars, id));
Daniel Willmann191e0d92018-01-17 12:44:35 +01001089}
1090
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001091/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1092 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1093 * OsmuxCID IE.
1094 */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001095private function f_vty_allow_osmux_cn(boolean allow) runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001096 f_vty_enter_cfg_msc(BSCVTY, 0);
1097 if (allow) {
1098 f_vty_transceive(BSCVTY, "osmux on");
1099 } else {
1100 f_vty_transceive(BSCVTY, "osmux off");
1101 }
1102 f_vty_transceive(BSCVTY, "exit");
1103 f_vty_transceive(BSCVTY, "exit");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001104}
1105
Max2253c0b2018-11-06 19:28:05 +01001106function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001107 if (BSCVTY.checkstate("Mapped")) {
1108 /* skip initialization if already executed once */
1109 return;
1110 }
Harald Weltebc03c762018-02-12 18:09:38 +01001111 map(self:BSCVTY, system:BSCVTY);
1112 f_vty_set_prompts(BSCVTY);
1113 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001114 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1115 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001116}
1117
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001118friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001119{
1120 // log on TTCN3 log output
1121 log(log_msg);
1122 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001123 if (pt.checkstate("Mapped")) {
1124 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1125 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001126}
1127
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001128private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1129{
1130 if (rsl_idx >= lengthof(g_system_information)) {
1131 g_system_information[rsl_idx] := SystemInformationConfig_omit
1132 }
1133 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1134}
1135
1136altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1137 var ASP_RSL_Unitdata rx_rsl_ud;
1138
1139 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001140 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001141 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1142 repeat;
1143 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001144 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001145 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1146 repeat;
1147 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001148 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001149 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1150 repeat;
1151 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001152 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001153 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1154 repeat;
1155 }
1156
1157 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1158 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1159 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1160 repeat;
1161 }
1162 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1163 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1164 repeat;
1165 }
1166 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1167 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1168 repeat;
1169 }
1170 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1171 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1172 repeat;
1173 }
1174}
1175
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001176/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1177private type record of boolean my_BooleanList;
1178
1179private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1180{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001181 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1182
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001183 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001184 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1185 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1186 * stepping into that config node. */
1187 log("msc ", msc_nr, " is not configured, skipping");
1188 continue;
1189 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001190 f_vty_enter_cfg_msc(pt, msc_nr);
1191 if (allow_attach_list[msc_nr]) {
1192 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1193 f_vty_transceive(pt, "allow-attach", strict := false);
1194 } else {
1195 f_vty_transceive(pt, "no allow-attach", strict := false);
1196 }
1197 f_vty_transceive(pt, "exit");
1198 f_vty_transceive(pt, "exit");
1199 }
1200}
1201
Harald Welte21b46bd2017-12-17 19:46:32 +01001202/* global initialization function
1203 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001204 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1205 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1206 */
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001207function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false,
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001208 integer nr_msc := 1, integer nr_mgw := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001209 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001210
Harald Welteae026692017-12-09 01:03:01 +01001211 if (g_initialized) {
1212 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001213 }
Harald Welteae026692017-12-09 01:03:01 +01001214 g_initialized := true;
1215
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001216 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001217 activate(as_Tguard());
1218
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001219 f_init_vty("VirtMSC");
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001220 f_vty_allow_osmux_cn(g_osmux_enabled_cn);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001221
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001222 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001223 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1224
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001225 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1226 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1227 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1228 }
1229
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001230 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001231 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001232 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1233 * MSC-side BSSAP emulation */
1234 if (handler_mode) {
1235 var RanOps ranops := MSC_RanOps;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001236 ranops.use_osmux := g_osmux_enabled_cn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001237 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1238 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1239 f_ran_adapter_start(g_bssap[bssap_idx]);
1240 } else {
1241 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1242 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1243 f_ran_adapter_start(g_bssap[bssap_idx]);
1244 f_legacy_bssap_reset();
1245 }
Harald Welte67089ee2018-01-17 22:19:03 +01001246 }
Harald Welted5833a82018-05-27 16:52:56 +02001247
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001248 if (mp_enable_lcs_tests) {
1249 if (handler_mode) {
1250 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1251 } else {
1252 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1253 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1254 }
1255 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001256 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001257
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001258 /* start the test with exactly all enabled MSCs allowed to attach */
1259 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1260
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001261 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001262
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02001263 g_nr_mgw := nr_mgw;
1264 for (var integer i := 0; i < g_nr_mgw; i := i+1) {
1265 f_init_mgcp(i, "VirtMGW");
1266 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01001267
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001268 for (var integer i := 0; i < nr_bts; i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001269 f_init_bts(i, c_BtsParams[i].trx_num, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001270 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001271
1272 /* Emit a marker to appear in the SUT's own logging output */
1273 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001274}
Harald Welte696ddb62017-12-08 14:01:43 +01001275
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001276function f_init_bts(integer bts_idx := 0,
1277 integer trx_num := NUM_TRX_CFG,
1278 boolean handler_mode := false)
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001279runs on test_CT {
1280 /* wait until osmo-bts-omldummy has respawned */
1281 f_wait_oml(bts_idx, "degraded", 5.0);
1282
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001283 /* start RSL connection(s) */
1284 for (var integer trx_idx := 0; trx_idx < trx_num; trx_idx := trx_idx + 1) {
1285 f_ipa_rsl_start(bts[bts_idx][trx_idx].rsl,
1286 mp_bsc_ip, mp_bsc_rsl_port,
1287 {bts_idx, trx_idx}, handler_mode);
1288 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001289 /* wait until BSC tells us "connected" */
1290 f_wait_oml(bts_idx, "connected", 5.0);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001291
1292 /* Set up BTS with VTY commands: */
Vadim Yanitskiy4d852082022-09-14 14:07:20 +07001293 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
1294 f_vty_enter_cfg_bts(BSCVTY, bts_idx);
1295 if (g_osmux_enabled_bts) {
1296 f_vty_transceive(BSCVTY, "osmux on");
1297 } else {
1298 f_vty_transceive(BSCVTY, "osmux off");
1299 }
1300 f_vty_transceive(BSCVTY, "end");
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001301 }
Harald Welte28d943e2017-11-25 15:00:50 +01001302}
1303
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001304function f_init_bts_and_check_sysinfo(integer bts_idx := 0,
1305 integer trx_num := NUM_TRX_CFG,
1306 boolean handler_mode := false,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001307 template SystemInformationConfig expect_si)
1308runs on test_CT {
1309 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1310
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001311 f_init_bts(bts_idx, trx_num, handler_mode);
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001312
1313 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1314 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1315 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1316 */
1317 f_sleep(5.0);
1318 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1319
1320 deactivate(sysinfo);
1321
1322 if (match(g_system_information[bts_idx], expect_si)) {
1323 setverdict(pass);
1324 } else {
1325 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1326 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1327 setverdict(fail, "received SI does not match expectations");
1328 return;
1329 }
1330}
1331
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001332/* expect to receive a RSL message matching a specified template on a given BTS / TRX */
1333function f_exp_ipa_rx(template (present) RSL_Message t_rx,
1334 BtsTrxIdx idx := {0, 0},
1335 float Tval := 2.0)
Harald Welteae026692017-12-09 01:03:01 +01001336runs on test_CT return RSL_Message {
1337 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001338 timer T := Tval;
Harald Welteae026692017-12-09 01:03:01 +01001339
1340 T.start;
1341 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001342 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001343 T.stop;
1344 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001345 [] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001346 [] T.timeout {
1347 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001348 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001349 }
Harald Welteae026692017-12-09 01:03:01 +01001350 }
1351 return rx_rsl_ud.rsl;
1352}
1353
Harald Welte21b46bd2017-12-17 19:46:32 +01001354/* helper function to transmit RSL on a given BTS/stream */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001355function f_ipa_tx(template (value) RSL_Message t_tx,
1356 BtsTrxIdx idx := {0, 0},
1357 IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001358runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001359 IPA_RSL[idx.bts][idx.trx].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001360}
1361
1362
Harald Welte4003d112017-12-09 22:35:39 +01001363/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001364testcase TC_chan_act_noreply() runs on test_CT {
1365 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001366 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001367
Harald Welte89d42e82017-12-17 16:42:41 +01001368 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001369
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001370 f_ipa_tx(ts_RSL_CHAN_RQD('23'O, 23));
1371 rsl_unused := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001372 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001373}
1374
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001375const CounterNameVals counternames_bts_chreq := {
1376 { "chreq:total", 0 },
1377 { "chreq:attempted_emerg", 0 },
1378 { "chreq:attempted_call", 0 },
1379 { "chreq:attempted_location_upd", 0 },
1380 { "chreq:attempted_pag", 0 },
1381 { "chreq:attempted_pdch", 0 },
1382 { "chreq:attempted_other", 0 },
1383 { "chreq:attempted_unknown", 0 },
1384 { "chreq:successful", 0 },
1385 { "chreq:successful_emerg", 0 },
1386 { "chreq:successful_call", 0 },
1387 { "chreq:successful_location_upd", 0 },
1388 { "chreq:successful_pag", 0 },
1389 { "chreq:successful_pdch", 0 },
1390 { "chreq:successful_other", 0 },
1391 { "chreq:successful_unknown", 0 },
1392 { "chreq:no_channel", 0 },
1393 { "chreq:max_delay_exceeded", 0 }
1394};
1395
1396/* verify the "chreq:*" counters */
1397private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1398{
1399 var GsmFrameNumber fn := 23;
1400
1401 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1402
1403 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001404 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn));
1405 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001406 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1407
1408 f_ctrs_bts_add(0, "chreq:total");
1409 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1410 f_ctrs_bts_verify();
1411
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001412 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1413 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001414
1415 f_ctrs_bts_add(0, "chreq:successful");
1416 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1417 f_ctrs_bts_verify();
1418
1419 /* test is done, release RSL Conn Fail Ind to clean up */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001420 f_ipa_tx(ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1421 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
1422 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001423 f_sleep(1.0);
1424}
1425
Harald Welte4003d112017-12-09 22:35:39 +01001426testcase TC_chan_act_counter() runs on test_CT {
1427 var BSSAP_N_UNITDATA_ind ud_ind;
1428 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001429 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001430
Harald Welte89d42e82017-12-17 16:42:41 +01001431 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001432
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001433 f_vty_allow_emerg_bts(true, 0);
1434
1435 f_ctrs_bts_init(1, counternames_bts_chreq);
1436
1437 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1438 f_chan_act_counter('a3'O, "emerg");
1439
1440 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1441 f_chan_act_counter('43'O, "call");
1442
1443 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1444 f_chan_act_counter('03'O, "location_upd");
1445
1446 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1447 f_chan_act_counter('23'O, "pag");
1448 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1449 f_chan_act_counter('33'O, "pag");
1450
1451 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1452 /* no PCU, so PDCH not allowed. Skip this test for now. */
1453 /* f_chan_act_counter('7b'O, "pdch"); */
1454
1455 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1456 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001457
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001458 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001459}
1460
Harald Welteae026692017-12-09 01:03:01 +01001461/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001462private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001463 var RSL_Message rx_rsl;
1464
Harald Welteae026692017-12-09 01:03:01 +01001465 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001466 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001467
1468 /* expect BSC to disable the channel again if there's no RLL EST IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001469 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := T3101_MAX);
Harald Welteae026692017-12-09 01:03:01 +01001470
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001471 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001472}
1473
Philipp Maier9c60a622020-07-09 15:08:46 +02001474/* Normal variant */
1475testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001476 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001477 f_TC_chan_act_ack_noest();
1478}
1479
1480/* Emergency call variant */
1481testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1482 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001483 f_init(1);
1484 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001485 f_TC_chan_act_ack_noest(ra := 'A5'O);
1486}
1487
Philipp Maier606f07d2020-08-12 17:21:58 +02001488/* Emergency call variant, but emergency calls are not allowed */
1489testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1490 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1491
1492 var RSL_Message rx_rsl;
1493 var GsmRrMessage rr;
1494
1495 f_init(1);
1496 f_vty_allow_emerg_bts(false, 0);
1497
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001498 IPA_RSL[0][0].clear;
1499 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier606f07d2020-08-12 17:21:58 +02001500
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001501 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Philipp Maier606f07d2020-08-12 17:21:58 +02001502 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1503 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1504 setverdict(pass);
1505 } else {
1506 setverdict(fail, "immediate assignment not rejected");
1507 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001508
1509 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001510}
1511
Harald Welteae026692017-12-09 01:03:01 +01001512/* Test behavior if MSC never answers to CR */
1513testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001514 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1515 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001516 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001517 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001518
Harald Welte89d42e82017-12-17 16:42:41 +01001519 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001520
1521 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001522 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001523
1524 var octetstring l3 := '00010203040506'O
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001525 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welteae026692017-12-09 01:03:01 +01001526
1527 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1528
1529 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001530 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001531 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001532 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001533}
1534
1535/* Test behavior if MSC answers with CREF to CR */
1536testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1537 var BSSAP_N_CONNECT_ind rx_c_ind;
1538 var RSL_Message rx_rsl;
1539
Harald Welte89d42e82017-12-17 16:42:41 +01001540 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001541
1542 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001543 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001544
1545 var octetstring l3 := '00010203040506'O
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001546 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welteae026692017-12-09 01:03:01 +01001547
1548 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1549 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1550
1551 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001552 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001553 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001554}
1555
Harald Welte618ef642017-12-14 14:58:20 +01001556/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1557testcase TC_chan_act_nack() runs on test_CT {
1558 var RSL_Message rx_rsl;
1559 var integer chact_nack;
1560
Harald Welte89d42e82017-12-17 16:42:41 +01001561 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001562
1563 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1564
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001565 f_ipa_tx(ts_RSL_CHAN_RQD('33'O, 33));
1566 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte618ef642017-12-14 14:58:20 +01001567 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1568
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001569 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte618ef642017-12-14 14:58:20 +01001570
1571 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1572 f_sleep(0.5);
1573
1574 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1575
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001576 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001577}
1578
Harald Welte799c97b2017-12-14 17:50:30 +01001579/* Test for channel exhaustion due to RACH overload */
1580testcase TC_chan_exhaustion() runs on test_CT {
1581 var ASP_RSL_Unitdata rsl_ud;
1582 var integer i;
1583 var integer chreq_total, chreq_nochan;
1584
Harald Welte89d42e82017-12-17 16:42:41 +01001585 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001586
1587 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1588 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1589
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001590 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001591 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1592 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001593 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001594 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001595 }
1596
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001597 IPA_RSL[0][0].clear;
Harald Welte799c97b2017-12-14 17:50:30 +01001598
Harald Weltedd8cbf32018-01-28 12:07:52 +01001599 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001600 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001601
1602 /* now expect additional channel activations to fail */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001603 f_ipa_tx(ts_RSL_CHAN_RQD('42'O, 42));
Harald Welte799c97b2017-12-14 17:50:30 +01001604
1605 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001606 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001607 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1608 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001609 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001610 var GsmRrMessage rr;
1611 /* match on IMM ASS REJ */
1612 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1613 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1614 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001615 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001616 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1617 chreq_nochan+1);
1618 setverdict(pass);
1619 } else {
1620 repeat;
1621 }
1622 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001623 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte799c97b2017-12-14 17:50:30 +01001624 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001625 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001626}
1627
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001628/* Test channel deactivation due to silence from MS */
1629testcase TC_chan_deact_silence() runs on test_CT {
1630 var RslChannelNr chan_nr;
1631
1632 f_init(1);
1633
1634 /* Request for a dedicated channel */
1635 chan_nr := f_chreq_act_ack('23'O);
1636
1637 /* Wait some time until the channel is released */
1638 f_sleep(2.0);
1639
1640 /* Expect CHANnel RELease */
1641 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001642 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001643 log("Received CHANnel RELease");
1644 setverdict(pass);
1645 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001646 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001647 /* See OS#3709, OsmoBSC should not send Immediate
1648 * Assignment Reject since a dedicated channel was
1649 * already allocated, and Immediate Assignment was
1650 * already sent. */
1651 setverdict(fail, "Unexpected Immediate Assignment!");
1652 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001653 [] IPA_RSL[0][0].receive {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001654 setverdict(fail, "Unexpected RSL message!");
1655 }
1656 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001657 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001658}
1659
Harald Weltecfe2c962017-12-15 12:09:32 +01001660/***********************************************************************
1661 * Assignment Testing
1662 ***********************************************************************/
1663
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001664/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1665 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001666testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001667 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001668
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001669 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1670 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001671 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001672 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001673}
1674
Harald Welte16a4adf2017-12-14 18:54:01 +01001675/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001676testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001677 var BSSAP_N_CONNECT_ind rx_c_ind;
1678 var RSL_Message rx_rsl;
1679 var DchanTuple dt;
1680
Harald Welte89d42e82017-12-17 16:42:41 +01001681 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001682
1683 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001684 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001685 /* send assignment without AoIP IEs */
1686 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1687 } else {
1688 /* Send assignmetn without CIC in IPA case */
1689 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1690 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1691 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1692 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001693 alt {
1694 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1695 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1696 }
Harald Welte235ebf12017-12-15 14:18:16 +01001697 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001698 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1699 setverdict(pass);
1700 }
1701 [] BSSAP.receive { repeat; }
1702 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001703 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001704 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001705}
1706
Harald Welteed848512018-05-24 22:27:58 +02001707/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001708function f_gen_ass_req(boolean osmux_enabled := false, integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4") return PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001709 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001710 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001711 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001712 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001713 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001714 if (osmux_enabled) {
1715 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1716 } else {
1717 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1718 }
Harald Welteed848512018-05-24 22:27:58 +02001719 } else {
1720 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001721 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001722 }
1723 return ass_cmd;
1724}
1725
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001726function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001727 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001728 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1729 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001730 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001731
1732 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1733 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001734 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1735 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001736 if (ispresent(enc)) {
1737 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001738 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1739 if (ispresent(v_enc.enc_alg_chosen)) {
1740 chosenEncryptionAlgorithm := valueof(
1741 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1742 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1743 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001744 if (ispresent(v_enc.enc_kc128)) {
1745 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1746 }
1747 }
1748
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001749 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001750 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001751 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001752 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1753 cell_id_source := cell_id_source,
1754 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001755 encryptionInformation := encryptionInformation,
1756 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001757 kC128 := kc128,
1758 /* on AoIP, allow "all" codecs (until we add more concise
1759 * tests) */
1760 codecList := ts_BSSMAP_IE_CodecList(
1761 {ts_CodecAMR_F, ts_CodecAMR_H,
1762 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001763 } else {
1764 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001765 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1766 cell_id_source := cell_id_source,
1767 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001768 encryptionInformation := encryptionInformation,
1769 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1770 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001771 }
1772 return ho_req;
1773}
1774
Harald Welteed848512018-05-24 22:27:58 +02001775/* generate an assignment complete template for either AoIP or SCCPlite */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001776function f_gen_exp_compl(integer bssap_idx := 0)
1777runs on MSC_ConnHdlr return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001778 var template PDU_BSSAP exp_compl;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001779 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001780 var template BSSMAP_IE_Osmo_OsmuxCID exp_osmux_cid := omit;
1781 if (g_pars.use_osmux_cn) {
1782 var template (present) INT1 exp_cid := ?;
1783 if (isbound(g_media.mgcp_conn[0].local_osmux_cid) and isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1784 exp_cid := (g_media.mgcp_conn[0].local_osmux_cid, g_media.mgcp_conn[1].local_osmux_cid);
1785 } else if (isbound(g_media.mgcp_conn[0].local_osmux_cid)) {
1786 exp_cid := g_media.mgcp_conn[0].local_osmux_cid;
1787 } else if (isbound(g_media.mgcp_conn[1].local_osmux_cid)) {
1788 exp_cid := g_media.mgcp_conn[1].local_osmux_cid;
1789 }
1790 exp_osmux_cid := tr_OsmuxCID(exp_cid);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001791 }
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001792 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, exp_osmux_cid);
Harald Welteed848512018-05-24 22:27:58 +02001793 } else {
1794 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02001795 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit, omit);
Harald Welteed848512018-05-24 22:27:58 +02001796 }
1797 return exp_compl;
1798}
1799
Harald Welte235ebf12017-12-15 14:18:16 +01001800/* Run everything required up to sending a caller-specified assignment command and expect response */
1801function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001802runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001803 var BSSAP_N_CONNECT_ind rx_c_ind;
1804 var RSL_Message rx_rsl;
1805 var DchanTuple dt;
1806
Harald Welte89d42e82017-12-17 16:42:41 +01001807 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001808
1809 dt := f_est_dchan('23'O, 23, '00000000'O);
1810 /* send assignment without AoIP IEs */
1811 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1812 alt {
1813 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1814 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1815 setverdict(pass);
1816 } else {
1817 setverdict(fail, fail_text);
1818 }
1819 }
1820 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1821 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1822 setverdict(pass);
1823 } else {
1824 setverdict(fail, fail_text);
1825 }
1826 }
1827 [] BSSAP.receive { repeat; }
1828 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001829 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001830}
1831testcase TC_assignment_csd() runs on test_CT {
1832 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001833 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001834 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1835 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001836 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1837 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001838 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001839}
1840
1841testcase TC_assignment_ctm() runs on test_CT {
1842 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001843 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001844 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1845 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001846 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1847 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001848 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001849}
1850
Harald Welte4003d112017-12-09 22:35:39 +01001851type record DchanTuple {
1852 integer sccp_conn_id,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001853 RslChannelNr rsl_chan_nr,
1854 BtsTrxIdx idx
Harald Weltea5d2ab22017-12-09 14:21:42 +01001855}
1856
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001857type record of DchanTuple DchanTuples;
1858
Harald Welted6939652017-12-13 21:02:46 +01001859/* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001860private function f_chreq_act_ack(OCT1 ra := '23'O,
1861 GsmFrameNumber fn := 23,
1862 BtsTrxIdx idx := {0, 0})
Harald Welted6939652017-12-13 21:02:46 +01001863runs on test_CT return RslChannelNr {
1864 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001865 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
1866 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Harald Welted6939652017-12-13 21:02:46 +01001867 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001868 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10), idx);
1869 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Harald Welted6939652017-12-13 21:02:46 +01001870 return chan_nr;
1871}
1872
Harald Welte4003d112017-12-09 22:35:39 +01001873/* helper function to establish a dedicated channel via BTS and MSC */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001874function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1875 BtsTrxIdx idx := {0, 0})
Harald Welte4003d112017-12-09 22:35:39 +01001876runs on test_CT return DchanTuple {
1877 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001878 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001879
Harald Welte4003d112017-12-09 22:35:39 +01001880 /* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001881 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn, idx);
Harald Welte4003d112017-12-09 22:35:39 +01001882
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001883 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3), idx);
Harald Welte4003d112017-12-09 22:35:39 +01001884
1885 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1886 dt.sccp_conn_id := rx_c_ind.connectionId;
1887 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1888
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001889 dt.idx := idx;
Harald Welte4003d112017-12-09 22:35:39 +01001890 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001891}
1892
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001893/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001894function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1895 BtsTrxIdx idx := {0, 0})
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001896runs on test_CT return DchanTuple {
1897 var BSSAP_N_CONNECT_ind rx_c_ind;
1898 var DchanTuple dt;
1899
1900 /* Send CHAN RQD */
1901 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001902 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001903
1904 /* The dyn TS first deactivates PDCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001905 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), idx, Tval := T3101_MAX);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001906 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001907 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001908
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001909 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001910 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1911
1912 /* Now activates the signalling channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001913 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10), idx);
1914 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001915
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001916 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001917
1918 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1919 dt.sccp_conn_id := rx_c_ind.connectionId;
1920 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1921
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001922 dt.idx := idx;
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001923 return dt;
1924}
1925
Harald Welte641fcbe2018-06-14 10:58:35 +02001926/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001927private function f_exp_chan_rel_and_clear(DchanTuple dt)
1928runs on test_CT {
Harald Welte641fcbe2018-06-14 10:58:35 +02001929 var RSL_Message rx_rsl;
1930 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001931 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), dt.idx, Tval := T3101_MAX);
Harald Welte641fcbe2018-06-14 10:58:35 +02001932 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001933 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), dt.idx);
Harald Welte641fcbe2018-06-14 10:58:35 +02001934
1935 /* expect Clear Complete from BSC */
1936 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1937
1938 /* MSC disconnects as instructed. */
1939 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1940}
1941
Harald Welte4003d112017-12-09 22:35:39 +01001942/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1943testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001944 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001945 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001946
Harald Welte89d42e82017-12-17 16:42:41 +01001947 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001948
Harald Welte4003d112017-12-09 22:35:39 +01001949 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1950
1951 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001952 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Harald Welte4003d112017-12-09 22:35:39 +01001953
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001954 /* expect Clear Request on MSC side */
1955 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1956
1957 /* Instruct BSC to clear channel */
1958 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1959 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1960
Harald Welte4003d112017-12-09 22:35:39 +01001961 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001962 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001963
1964 /* wait for SCCP emulation to do its job */
1965 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001966
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001967 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001968}
1969
1970/* Test behavior of channel release after CONN FAIL IND from BTS */
1971testcase TC_chan_rel_conn_fail() runs on test_CT {
1972 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001973 var DchanTuple dt;
1974
Harald Welte89d42e82017-12-17 16:42:41 +01001975 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001976
1977 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1978
Vadim Yanitskiy01d0a902022-12-14 22:41:42 +07001979 /* Sending CONN FAIL IND immediately may trigger a race condition.
1980 * Give the BSC some time to process a new SCCP connection (OS#5823). */
1981 f_sleep(0.2);
1982
Harald Welte4003d112017-12-09 22:35:39 +01001983 /* simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001984 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001985 /* TODO: different cause values? */
1986
Harald Welte4003d112017-12-09 22:35:39 +01001987 /* expect Clear Request from BSC */
1988 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1989
1990 /* Instruct BSC to clear channel */
1991 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1992 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1993
Harald Welte6ff76ea2018-01-28 13:08:01 +01001994 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001995 f_exp_chan_rel_and_clear(dt);
Harald Welte4003d112017-12-09 22:35:39 +01001996
1997 /* wait for SCCP emulation to do its job */
1998 f_sleep(1.0);
1999
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002000 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002001}
2002
Harald Welte99f3ca02018-06-14 13:40:29 +02002003/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
2004/* See also https://www.osmocom.org/issues/3182 */
2005testcase TC_early_conn_fail() runs on test_CT {
2006 var RSL_Message rx_rsl;
2007 var DchanTuple dt;
2008
2009 f_init(1);
2010
2011 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02002012 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02002013
2014 /* BTS->BSC: simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002015 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002016
2017 /* BTS->BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002018 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002019
2020 /* BTS<-BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002021 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002022
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002023 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002024}
2025
2026/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
2027/* See also https://www.osmocom.org/issues/3182 */
2028testcase TC_late_conn_fail() runs on test_CT {
2029 var RSL_Message rx_rsl;
2030 var DchanTuple dt;
2031
2032 f_init(1);
2033
2034 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2035
2036 /* BSC<-MSC: Instruct BSC to clear connection */
2037 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
2038
2039 /* BTS->BSC: expect BSC to deactivate SACCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002040 rx_rsl := f_exp_ipa_rx(tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002041
2042 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002043 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002044
2045 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002046 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002047 /* BTS->BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002048 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002049
2050 /* BSC->MSC: expect Clear Complete from BSC */
2051 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2052
2053 /* BSC<-MSC: MSC disconnects as requested. */
2054 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2055
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002056 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002057}
2058
Oliver Smithaf03bef2021-08-24 15:34:51 +02002059private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
2060 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
2061 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2062
2063 f_statsd_reset();
2064
2065 /* Establish SDCCH */
2066 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
2067 f_establish_fully(ass_cmd, exp_fail);
2068
2069 /* Expect stats to be 0 */
2070 var StatsDExpects expect := {
2071 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
2072 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
2073 };
2074 f_statsd_expect(expect);
2075
2076 /* Simulate CONN FAIL IND on SDCCH */
2077 RSL.send(ts_ASP_RSL_UD(
2078 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2079 IPAC_PROTO_RSL_TRX0));
2080
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002081 f_sleep(1.0);
2082
Oliver Smithaf03bef2021-08-24 15:34:51 +02002083 /* Expect stats to be 1 */
2084 expect := {
2085 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2086 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2087 };
2088 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002089 BSSAP.receive(tr_BSSMAP_ClearRequest);
2090 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002091}
2092testcase TC_stats_conn_fail() runs on test_CT {
2093 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2094 var MSC_ConnHdlr vc_conn;
2095
2096 f_init(1, true);
2097 f_sleep(1.0);
2098
2099 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2100 vc_conn.done;
2101
2102 f_shutdown_helper();
2103}
2104
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002105function f_expect_chan_rel(RslChannelNr rsl_chan_nr,
2106 BtsTrxIdx idx := {0, 0},
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002107 boolean expect_deact_sacch := true,
2108 boolean expect_rr_chan_rel := true,
2109 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002110 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002111 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002112 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002113 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002114
2115 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002116 var boolean got_deact_sacch := false;
2117 var boolean got_rr_chan_rel := false;
2118 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002119 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002120 var RSL_IE_Body l3_ie;
2121 var PDU_ML3_NW_MS l3;
2122 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002123 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2124 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002125 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002126 [] 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 +01002127 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002128 repeat;
2129 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002130 [] 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 +01002131 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002132
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002133 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2134 setverdict(fail, "cannot find L3");
2135 mtc.stop;
2136 }
2137 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2138
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002139 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002140 var CellSelIndValue cells := dec_CellSelIndValue(
2141 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2142
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002143 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2144 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002145 setverdict(pass);
2146 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002147 log("EXPECTED CELLS: ", expect_cells);
2148 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002149 }
2150 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002151
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002152 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2153 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2154 if (match(got_cause, expect_rr_cause)) {
2155 setverdict(pass);
2156 } else {
2157 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2158 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002159 }
Harald Welte99787102019-02-04 10:41:36 +01002160 repeat;
2161 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002162 [] 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 +01002163 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002164 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002165 if (handle_rll_rel) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002166 f_ipa_tx(ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002167 }
Harald Welte91d54a52018-01-28 15:35:07 +01002168 repeat;
2169 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002170 [] 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 +01002171 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002172 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
Harald Welte91d54a52018-01-28 15:35:07 +01002173 }
2174 /* ignore any user data */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002175 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002176 repeat;
2177 }
2178 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002179
2180 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2181 " got_rll_rel_req=", got_rll_rel_req);
2182
2183 if (expect_deact_sacch != got_deact_sacch) {
2184 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2185 }
2186 if (expect_rr_chan_rel != got_rr_chan_rel) {
2187 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2188 }
2189 if (expect_rll_rel_req != got_rll_rel_req) {
2190 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2191 }
Harald Welte91d54a52018-01-28 15:35:07 +01002192}
2193
Harald Welte4003d112017-12-09 22:35:39 +01002194/* Test behavior of channel release after hard Clear Command from MSC */
2195testcase TC_chan_rel_hard_clear() runs on test_CT {
2196 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002197 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002198
Harald Welte89d42e82017-12-17 16:42:41 +01002199 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002200
2201 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2202
2203 /* Instruct BSC to clear channel */
2204 var BssmapCause cause := 0;
2205 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2206
2207 /* expect Clear Complete from BSC on A */
2208 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2209 /* release the SCCP connection */
2210 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2211 }
2212
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002213 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002214 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002215}
2216
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002217function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2218 var BSSAP_N_DATA_ind rx_di;
2219 var DchanTuple dt;
2220
2221 f_init(1);
2222
2223 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2224 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2225 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2226 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2227
2228 /* Instruct BSC to clear channel */
2229 var BssmapCause cause := 0;
2230 if (tx_csfb_ind) {
2231 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2232 } else {
2233 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2234 }
2235
2236 /* expect Clear Complete from BSC on A */
2237 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2238 /* release the SCCP connection */
2239 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2240 }
2241
2242 /* 1 neighbor is added by default in osmo-bts.cfg and
2243 SystemInformationConfig_default, use that: */
2244 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2245
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002246 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 +02002247 f_shutdown_helper();
2248}
2249
2250/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2251 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2252 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2253 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2254 Indicator or not shouldn't matter at all. */
2255testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2256 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2257}
2258
2259/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2260 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2261 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. */
2263testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2264 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2265}
2266
2267/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2268 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2269 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2270 CSFB Indicator should not be used anymore, and hence, there should be no
2271 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2272 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002273testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2274 var BSSAP_N_DATA_ind rx_di;
2275 var DchanTuple dt;
2276
2277 f_init(1);
2278
2279 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2280
2281 /* Instruct BSC to clear channel */
2282 var BssmapCause cause := 0;
2283 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2284
2285 /* expect Clear Complete from BSC on A */
2286 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2287 /* release the SCCP connection */
2288 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2289 }
2290
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002291 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002292 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002293}
2294
Harald Welted8c36cd2017-12-09 23:05:31 +01002295/* Test behavior of channel release after hard RLSD from MSC */
2296testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002297 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002298
Harald Welte89d42e82017-12-17 16:42:41 +01002299 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002300
2301 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2302
2303 /* release the SCCP connection */
2304 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2305
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002306 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002307 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002308}
2309
Harald Welte550daf92018-06-11 19:22:13 +02002310/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2311testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2312 var DchanTuple dt;
2313
2314 f_init(1);
2315
2316 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2317
2318 /* release the SCCP connection */
2319 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2320
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002321 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002322 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002323}
2324
Harald Welte85804d42017-12-10 14:11:58 +01002325/* Test behavior of channel release after BSSMAP RESET from MSC */
2326testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002327 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002328
Harald Welte89d42e82017-12-17 16:42:41 +01002329 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002330
2331 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2332
2333 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002334 IPA_RSL[0][0].clear;
Harald Welte85804d42017-12-10 14:11:58 +01002335
2336 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002337 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 +01002338 interleave {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002339 [] 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 +01002340 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2341 }
2342
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002343 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002344 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002345}
2346
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002347/* Verify T(iar) triggers and releases the channel */
2348testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2349 var DchanTuple dt;
2350
2351 /* Set T(iar) in BSC low enough that it will trigger before other side
2352 has time to keep alive with a T(ias). Keep recommended ratio of
2353 T(iar) >= T(ias)*2 */
2354 g_bsc_sccp_timer_ias := 2;
2355 g_bsc_sccp_timer_iar := 5;
2356
2357 f_init(1);
2358
2359 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002360 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002361 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002362}
2363
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002364private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2365 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002366runs on test_CT
2367{
2368 var DchanTuple dt;
2369
2370 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2371 var BssmapCause cause := 0;
2372 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2373 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2374 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2375 }
2376
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002377 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 +02002378}
2379
2380/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2381testcase TC_chan_rel_rr_cause() runs on test_CT {
2382 f_init(1);
2383
2384 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2385 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2386 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2387 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2388 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2389 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002390
2391 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002392}
2393
Harald Welte5cd20ed2017-12-13 21:03:20 +01002394/* Test behavior if RSL EST IND for non-active channel */
2395testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2396 timer T := 2.0;
2397
Harald Welte89d42e82017-12-17 16:42:41 +01002398 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002399
2400 var octetstring l3 := '00010203040506'O;
2401 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002402 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002403
2404 T.start;
2405 alt {
2406 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2407 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2408 }
2409 [] BSSAP.receive {}
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002410 [] IPA_RSL[0][0].receive {}
Harald Welte5cd20ed2017-12-13 21:03:20 +01002411 [] T.timeout {}
2412 }
2413
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002414 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002415}
2416
2417/* Test behavior if RSL EST IND for invalid SAPI */
2418testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2419 var RslChannelNr chan_nr;
2420
Harald Welte89d42e82017-12-17 16:42:41 +01002421 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002422
2423 chan_nr := f_chreq_act_ack()
2424
2425 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002426 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002427
2428 timer T := 2.0;
2429 T.start;
2430 alt {
2431 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2432 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2433 }
2434 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002435 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002436 [] T.timeout {}
2437 }
2438
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002439 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002440}
2441
2442/* Test behavior if RSL EST IND for invalid SAPI */
2443testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2444 timer T := 2.0;
2445
Harald Welte89d42e82017-12-17 16:42:41 +01002446 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002447
2448 var RslChannelNr chan_nr := f_chreq_act_ack();
2449
2450 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002451 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002452
2453 T.start;
2454 alt {
2455 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2456 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2457 }
2458 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002459 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002460 [] T.timeout {}
2461 }
2462
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002463 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002464}
2465
2466/* Test behavior if RSL EST IND for invalid SACCH */
2467testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2468 timer T := 2.0;
2469
Harald Welte89d42e82017-12-17 16:42:41 +01002470 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002471
2472 var RslChannelNr chan_nr := f_chreq_act_ack();
2473
2474 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002475 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002476
2477 T.start;
2478 alt {
2479 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2480 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2481 }
2482 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002483 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002484 [] T.timeout {}
2485 }
2486
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002487 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002488}
2489
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002490/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2491private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2492 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2493 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2494
2495 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2496 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2497
2498 f_establish_fully(ass_cmd, exp_compl);
2499
2500 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2501 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2502 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2503 BSSAP.receive(PDU_BSSAP:{
2504 discriminator := '1'B,
2505 spare := '0000000'B,
2506 dlci := 'C3'O,
2507 lengthIndicator := ?,
2508 pdu := { dtap := '0904'O }
2509 });
2510
2511 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2512 for (var integer i := 0; i < 32; i := i + 1) {
2513 var octetstring l3 := '09'O & f_rnd_octstring(14);
2514 var template (value) RslLinkId link_id;
2515 var template (value) OCT1 dlci;
2516
2517 if (i mod 2 == 0) {
2518 /* SAPI0 on FACCH or SDCCH */
2519 link_id := ts_RslLinkID_DCCH(0);
2520 dlci := '80'O;
2521 } else {
2522 /* SAPI3 on SACCH */
2523 link_id := ts_RslLinkID_SACCH(3);
2524 dlci := 'C3'O;
2525 }
2526
2527 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002528 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002529 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002530 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002531 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002532 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002533}
2534testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2535 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2536 var MSC_ConnHdlr vc_conn;
2537
2538 f_init(1, true);
2539 f_sleep(1.0);
2540
2541 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2542 vc_conn.done;
2543
2544 f_shutdown_helper();
2545}
2546
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002547private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002548 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002549 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002550 float T_val := 2.0)
2551runs on test_CT {
2552 var BSSAP_N_DATA_ind rx_di;
2553 timer T;
2554
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002555 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2556 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002557
2558 T.start(T_val);
2559 alt {
2560 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2561 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2562 if (not match(rx_cause, tr_cause)) {
2563 setverdict(fail, "Rx unexpected Cause IE: ",
2564 rx_cause, " vs expected ", tr_cause);
2565 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002566
2567 /* Who ever on the earth decided to define this field as two separate bits?!? */
2568 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2569 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2570 if (not match(rx_cc, cc)) {
2571 setverdict(fail, "Rx unexpected Control Channel type: ",
2572 rx_cc, " vs expected ", cc);
2573 }
2574
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002575 setverdict(pass);
2576 }
2577 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2578 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2579 }
2580 [] T.timeout {
2581 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2582 }
2583 }
2584}
2585
2586/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2587testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2588 var octetstring rnd_data := f_rnd_octstring(16);
2589 var RSL_Message rx_rsl;
2590 var DchanTuple dt;
2591
2592 f_init(1);
2593
2594 /* MS establishes a SAPI=0 link on DCCH */
2595 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2596
2597 /* MSC sends some data on (not yet established) SAPI=3 link */
2598 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2599 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002600 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 +07002601
2602 /* MS sends unexpected RELease INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002603 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002604 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2605 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2606
2607 /* Clean up the connection */
2608 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002609 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002610
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002611 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002612}
2613
2614/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2615testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2616 var octetstring rnd_data := f_rnd_octstring(16);
2617 var RSL_Message rx_rsl;
2618 var DchanTuple dt;
2619
2620 f_init(1);
2621
2622 /* MS establishes a SAPI=0 link on DCCH */
2623 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2624
2625 /* MSC sends some data on (not yet established) SAPI=3 link */
2626 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2627 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002628 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 +07002629
2630 /* BTS sends unexpected ERROR INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002631 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002632 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2633 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2634
2635 /* Clean up the connection */
2636 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002637 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002638
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002639 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002640}
2641
2642/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2643testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2644 var octetstring rnd_data := f_rnd_octstring(16);
2645 var RSL_Message rx_rsl;
2646 var DchanTuple dt;
2647
2648 f_init(1);
2649
2650 /* MS establishes a SAPI=0 link on DCCH */
2651 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2652
2653 /* MSC sends some data on (not yet established) SAPI=3 link */
2654 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2655 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002656 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 +07002657
2658 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2659 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2660
2661 /* Clean up the connection */
2662 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002663 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002664
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002665 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002666}
2667
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002668/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2669testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
2670 var octetstring rnd_data := f_rnd_octstring(16);
2671 var RSL_Message rx_rsl;
2672 var DchanTuple dt;
2673
2674 f_init(1);
2675
2676 /* MS establishes a SAPI=0 link on DCCH */
2677 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2678
2679 /* MSC sends some data on (not yet established) SAPI=3 link */
2680 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2681 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002682 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 +07002683
2684 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002685 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002686 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002687
2688 /* Clean up the connection */
2689 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002690 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002691
2692 f_shutdown_helper();
2693}
2694
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002695testcase TC_si_default() runs on test_CT {
2696 f_init(0);
2697 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002698 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002699}
Harald Welte4003d112017-12-09 22:35:39 +01002700
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002701/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2702 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2703private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2704{
2705 select (earfcn_index) {
2706 case (0) {
2707 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2708 return 111;
2709 }
2710 case (1) {
2711 return 1;
2712 }
2713 case (2) {
2714 return 0;
2715 }
2716 case (3) {
2717 return 65535;
2718 }
2719 case else {
2720 return 23 * (earfcn_index - 3);
2721 }
2722 }
2723}
2724
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002725function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2726 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002727
2728 f_init(0);
2729
2730 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2731 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002732 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2733 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002734 }
2735
2736 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2737
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002738 if (not istemplatekind(expect_cells, "omit")) {
2739 /* Also check that RR Channel Release contains these EARFCNs.
2740 * (copied code from TC_chan_rel_hard_clear_csfb) */
2741 var BSSAP_N_DATA_ind rx_di;
2742 var DchanTuple dt;
2743
2744 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002745 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2746 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2747 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002748
2749 /* Instruct BSC to clear channel */
2750 var BssmapCause cause := 0;
2751 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2752
2753 /* expect Clear Complete from BSC on A */
2754 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2755 /* release the SCCP connection */
2756 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2757 }
2758
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002759 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002760 }
2761
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002762 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002763 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 +02002764 }
2765}
2766
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002767private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2768{
2769 var template SI2quaterRestOctetsList si2quater := {};
2770 var integer si2quater_count := (count + 2) / 3;
2771
2772 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002773 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002774 var integer index := i / 3;
2775 var integer earfcn_index := i mod 3;
2776 if (index >= lengthof(si2quater)) {
2777 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2778 }
2779 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);
2780 }
2781
2782 return si2quater;
2783}
2784
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002785private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2786{
2787 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2788
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002789 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002790 for (var integer i := 0; i < count; i := i + 1) {
2791 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002792 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002793 }
2794
2795 return tr_CellSelIndValue_EUTRAN(cells);
2796}
2797
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002798private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2799{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002800 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002801 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002802 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2803 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002804}
2805
2806testcase TC_si2quater_2_earfcns() runs on test_CT {
2807 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002808 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002809}
2810
2811testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002812 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002813 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002814}
2815
2816testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002817 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002818 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002819}
2820
2821testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002822 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002823 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002824}
2825
2826testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002827 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002828 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002829}
2830
2831testcase TC_si2quater_12_earfcns() runs on test_CT {
2832 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002833 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002834}
2835
2836testcase TC_si2quater_23_earfcns() runs on test_CT {
2837 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002838 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002839}
2840
2841testcase TC_si2quater_32_earfcns() runs on test_CT {
2842 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002843 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002844}
2845
2846testcase TC_si2quater_33_earfcns() runs on test_CT {
2847 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002848 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002849}
2850
2851testcase TC_si2quater_42_earfcns() runs on test_CT {
2852 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002853 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002854}
2855
2856testcase TC_si2quater_48_earfcns() runs on test_CT {
2857 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002858 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002859}
2860
2861/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2862 * 48 EARFCNs. */
2863testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002864 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002865 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2866 f_init(0);
2867
2868 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002869 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2870 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002871 }
2872
2873 /* The 49th EARFCN no longer fits, expect VTY error */
2874 f_vty_enter_cfg_bts(BSCVTY, 0);
2875 var charstring vty_error;
2876 vty_error := f_vty_transceive_ret(BSCVTY,
2877 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2878 f_vty_transceive(BSCVTY, "end");
2879
2880 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2881 log("Got expected VTY error: ", vty_error);
2882 setverdict(pass);
2883 } else {
2884 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2885 }
2886
2887 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2888
2889 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002890 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 +02002891 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002892 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002893}
2894
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002895private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2896{
2897 var uint8_t count := 0;
2898 for (var integer i := 5; i < 16; i := i + 1) {
2899 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2900 count := count + 1;
2901 }
2902 }
2903 return count;
2904}
2905
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002906private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2907{
2908 var ASP_RSL_Unitdata rx_rsl_ud;
2909 var SystemInformationType1 last_si1;
2910
2911 timer T := 30.0;
2912 T.start;
2913 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002914 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2915 tr_RSL_BCCH_INFO,
2916 tr_RSL_NO_SACCH_FILL,
2917 tr_RSL_SACCH_FILL))) -> value rx_rsl_ud {
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002918 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2919 if (g_system_information[rsl_idx].si1 == omit) {
2920 repeat;
2921 }
2922 last_si1 := g_system_information[rsl_idx].si1;
2923 g_system_information[rsl_idx].si1 := omit;
2924 T.stop;
2925 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002926 [] IPA_RSL[rsl_idx][0].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002927 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2928 }
2929 return last_si1;
2930}
2931
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002932/* verify ACC rotate feature */
2933testcase TC_si_acc_rotate() runs on test_CT {
2934 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002935 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002936 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002937 var uint8_t count;
2938 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2939
2940 f_init(0, guard_timeout := 60.0);
2941
2942 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2943 "access-control-class-rotate 3",
2944 "access-control-class-rotate-quantum 1"});
2945
2946 /* Init and get first sysinfo */
2947 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2948
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002949 for (var integer i:= 0; i < 20; i := i + 1) {
2950 last_si1 := f_recv_next_si1(0);
2951 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002952 count := f_acc09_count_allowed(acc);
2953 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2954
2955 if (count != 3) {
2956 log("RSL: EXPECTED SI ACC len=3");
2957 setverdict(fail, "received SI does not match expectations");
2958 break;
2959 }
2960
2961 for (var integer j := 0; j < 10; j := j + 1) {
2962 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2963 times_allowed[j] := times_allowed[j] + 1;
2964 }
2965 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002966 }
2967
2968 for (var integer j := 0; j < 10; j := j + 1) {
2969 log("ACC", j, " allowed ", times_allowed[j], " times" );
2970 if (j != 5 and times_allowed[j] < 3) {
2971 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2972 } else if (j == 5 and times_allowed[j] > 0) {
2973 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2974 }
2975 }
2976
2977 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2978 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002979 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002980}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002981
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002982/* verify ACC startup ramp+rotate feature */
2983testcase TC_si_acc_ramp_rotate() runs on test_CT {
2984 var template SystemInformationConfig sic := SystemInformationConfig_default;
2985 var SystemInformationType1 last_si1;
2986 var AccessControlClass acc;
2987 var ASP_RSL_Unitdata rx_rsl_ud;
2988 var uint8_t count;
2989 var uint8_t prev_count;
2990 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2991
2992 f_init(0, guard_timeout := 80.0);
2993
2994 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2995 "access-control-class-rotate 0",
2996 "access-control-class-rotate-quantum 1",
2997 "access-control-class-ramping",
2998 "access-control-class-ramping-step-interval 5",
2999 "access-control-class-ramping-step-size 5"});
3000
3001 /* Init and get first sysinfo */
3002 f_init_bts_and_check_sysinfo(0, expect_si := ?);
3003 last_si1 := g_system_information[0].si1;
3004 acc := last_si1.rach_control.acc;
3005 count := f_acc09_count_allowed(acc);
3006 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
3007 while (count > 0) {
3008 last_si1 := f_recv_next_si1(0);
3009 acc := last_si1.rach_control.acc;
3010 count := f_acc09_count_allowed(acc);
3011 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
3012 }
3013
3014 /* Increase adm subset size, we should see ramping start up */
3015 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
3016 prev_count := 0;
3017 while (true) {
3018 last_si1 := f_recv_next_si1(0);
3019 acc := last_si1.rach_control.acc;
3020 count := f_acc09_count_allowed(acc);
3021 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
3022
3023 if (prev_count > count) {
3024 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
3025 break;
3026 }
3027
3028 if (count == 9) {
3029 break; /* Maximum reached (10 - 1 perm barred), done here */
3030 }
3031
3032 prev_count := count;
3033 }
3034
3035 setverdict(pass);
3036
3037 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
3038 "rach access-control-class 4 allowed",
3039 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003040 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003041}
3042
Harald Welte4003d112017-12-09 22:35:39 +01003043testcase TC_ctrl_msc_connection_status() runs on test_CT {
3044 var charstring ctrl_resp;
3045
Harald Welte89d42e82017-12-17 16:42:41 +01003046 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003047
3048 /* See https://osmocom.org/issues/2729 */
3049 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003050 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01003051}
3052
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003053testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3054 var charstring ctrl_resp;
3055
3056 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003057
3058 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003059 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003060}
3061
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003062/* Verify correct stats on the number of configured and connected MSCs */
3063private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3064 g_pars := f_gen_test_hdlr_pars();
3065 var StatsDExpects expect := {
3066 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3067 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3068 };
3069 f_statsd_expect(expect);
3070}
3071
3072private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3073{
3074 var MSC_ConnHdlr vc_conn;
3075
3076 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3077 f_sleep(1.0);
3078 vc_conn := f_start_handler(tc_fn);
3079 vc_conn.done;
3080
3081 /* Also verify stat exposed on CTRL interface */
3082 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3083 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3084
3085 f_shutdown_helper();
3086}
3087
3088/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3089private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3090 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3091}
3092testcase TC_stat_num_msc_connected_1() runs on test_CT {
3093 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3094}
3095
3096/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3097private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3098 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3099}
3100testcase TC_stat_num_msc_connected_2() runs on test_CT {
3101 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3102}
3103
3104/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3105private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3106 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3107}
3108testcase TC_stat_num_msc_connected_3() runs on test_CT {
3109 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3110}
3111
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003112/* Verify correct stats on the number of configured and connected MSCs */
3113private 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 +06003114 var integer num_trx_connected := 0;
3115 var integer num_trx_total := 0;
3116
3117 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3118 var integer trx_num := c_BtsParams[i].trx_num;
3119 num_trx_total := num_trx_total + trx_num;
3120 if (i < expect_num_bts_connected) {
3121 num_trx_connected := num_trx_connected + trx_num;
3122 }
3123 }
3124
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003125 var StatsDExpects expect := {
3126 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3127 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3128 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003129 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := num_trx_connected, max := num_trx_connected },
3130 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := num_trx_total, max := num_trx_total }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003131 };
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003132
3133 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003134 f_statsd_expect(expect);
3135}
3136
3137private 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 +06003138 var integer num_trx_connected := 0;
3139 var integer num_trx_total := 0;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003140 var MSC_ConnHdlr vc_conn;
3141
3142 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3143 f_sleep(1.0);
3144 vc_conn := f_start_handler(tc_fn);
3145 vc_conn.done;
3146
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003147 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3148 var integer trx_num := c_BtsParams[i].trx_num;
3149 num_trx_total := num_trx_total + trx_num;
3150 if (i < nr_bts) {
3151 num_trx_connected := num_trx_connected + trx_num;
3152 }
3153 }
3154
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003155 /* Also verify stat exposed on CTRL interface */
3156 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3157 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 +06003158 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(num_trx_connected));
3159 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 +02003160
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003161 /* Verify rf_states exposed on CTRL interface */
3162 var charstring expect_net_rf_states := "";
3163 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003164 var charstring expect_bts_rf_states := "";
3165
3166 for (var integer j := 0; j < c_BtsParams[i].trx_num; j := j + 1) {
3167 expect_bts_rf_states := expect_bts_rf_states &
3168 int2str(i) & "," & int2str(j) & ",";
3169 if (i < NUM_BTS) {
3170 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3171 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3172 } else {
3173 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3174 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3175 }
3176 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3177 expect_bts_rf_states := expect_bts_rf_states & "on,";
3178 if (i < nr_bts) {
3179 /* For BTS where RSL is connected, the RSL state will be "up" */
3180 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3181 } else {
3182 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3183 }
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003184 }
3185
3186 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3187 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3188 }
3189 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3190
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003191 f_shutdown_helper();
3192}
3193
3194/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3195private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3196 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3197}
3198testcase TC_stat_num_bts_connected_1() runs on test_CT {
3199 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3200}
3201
3202/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3203private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3204 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3205}
3206testcase TC_stat_num_bts_connected_2() runs on test_CT {
3207 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3208}
3209
3210/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3211private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3212 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3213}
3214testcase TC_stat_num_bts_connected_3() runs on test_CT {
3215 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3216}
3217
Harald Welte4003d112017-12-09 22:35:39 +01003218testcase TC_ctrl() runs on test_CT {
3219 var charstring ctrl_resp;
3220
Harald Welte89d42e82017-12-17 16:42:41 +01003221 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003222
3223 /* all below values must match the osmo-bsc.cfg config file used */
3224
Harald Welte6a129692018-03-17 17:30:14 +01003225 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3226 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003227 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003228
3229 var integer bts_nr := 0;
3230 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3231 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3232 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3233 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3234 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3235 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3236 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3237
3238 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3239 f_sleep(2.0);
3240 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3241 setverdict(fail, "oml-uptime not incrementing as expected");
3242 }
3243 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3244
3245 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3246
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003247 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003248}
3249
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003250/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3251 "location-state" over the SCCPlite IPA conn */
3252testcase TC_ctrl_location() runs on test_CT {
3253 var MSC_ConnHdlr vc_conn;
3254 var integer bts_nr := 0;
3255
3256 f_init(1, true);
3257 f_sleep(1.0);
3258
3259 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3260 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3261 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3262
3263 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3264 f_sleep(2.0);
3265
3266 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3267 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3268 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3269
3270 /* should match the one from config */
3271 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3272
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003273 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003274}
3275
Harald Welte6f521d82017-12-11 19:52:02 +01003276
3277/***********************************************************************
3278 * Paging Testing
3279 ***********************************************************************/
3280
3281type record Cell_Identity {
3282 GsmMcc mcc,
3283 GsmMnc mnc,
3284 GsmLac lac,
3285 GsmCellId ci
3286};
Harald Welte24135bd2018-03-17 19:27:53 +01003287private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003288private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003289
Harald Welte5d1a2202017-12-13 19:51:29 +01003290type set of integer BtsIdList;
3291
3292private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3293 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3294 if (bts_id == bts_ids[j]) {
3295 return true;
3296 }
3297 }
3298 return false;
3299}
Harald Welte6f521d82017-12-11 19:52:02 +01003300
3301/* core paging test helper function; used by most paging test cases */
3302private function f_pageing_helper(hexstring imsi,
3303 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003304 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003305 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003306 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003307{
3308 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003309 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003310 var RSL_Message rx_rsl;
3311 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003312 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003313
3314 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003315
3316 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003317 for (i := 0; i < NUM_BTS; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003318 IPA_RSL[i][0].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003319 }
Harald Welte6f521d82017-12-11 19:52:02 +01003320
3321 if (isvalue(rsl_chneed)) {
3322 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3323 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3324 } else {
3325 bssmap_chneed := omit;
3326 }
3327
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003328 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3329 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003330
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003331 if (not istemplatekind(tmsi, "omit")) {
3332 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003333 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003334 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003335 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003336
Harald Welte5d1a2202017-12-13 19:51:29 +01003337 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003338 rx_rsl := f_exp_ipa_rx(tr_RSL_PAGING_CMD(mi), idx := {bts_ids[i], 0});
Harald Welte5d1a2202017-12-13 19:51:29 +01003339 /* check channel type, paging group */
3340 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3341 setverdict(fail, "Paging for wrong paging group");
3342 }
3343 if (ispresent(rsl_chneed) and
3344 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3345 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3346 }
Harald Welte6f521d82017-12-11 19:52:02 +01003347 }
Harald Welte2fccd982018-01-31 15:48:19 +01003348 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003349 /* do a quick check on all not-included BTSs if they received paging */
3350 for (i := 0; i < NUM_BTS; i := i + 1) {
3351 timer T := 0.1;
3352 if (f_bts_in_list(i, bts_ids)) {
3353 continue;
3354 }
3355 T.start;
3356 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003357 [] IPA_RSL[i][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003358 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3359 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003360 [] IPA_RSL[i][0].receive { repeat; }
Harald Welte5d1a2202017-12-13 19:51:29 +01003361 [] T.timeout { }
3362 }
Harald Welte6f521d82017-12-11 19:52:02 +01003363 }
3364
3365 setverdict(pass);
3366}
3367
Harald Welte5d1a2202017-12-13 19:51:29 +01003368const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003369const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003370const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3371const BtsIdList c_BtsId_LAC2 := { 2 };
3372
Harald Welte6f521d82017-12-11 19:52:02 +01003373/* PAGING by IMSI + TMSI */
3374testcase TC_paging_imsi_nochan() runs on test_CT {
3375 var BSSMAP_FIELD_CellIdentificationList cid_list;
3376 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003377 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003378 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003379}
3380
3381/* PAGING by IMSI + TMSI */
3382testcase TC_paging_tmsi_nochan() runs on test_CT {
3383 var BSSMAP_FIELD_CellIdentificationList cid_list;
3384 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003385 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003386 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003387}
3388
3389/* Paging with different "channel needed' values */
3390testcase TC_paging_tmsi_any() runs on test_CT {
3391 var BSSMAP_FIELD_CellIdentificationList cid_list;
3392 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003393 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003394 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003395}
3396testcase TC_paging_tmsi_sdcch() 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('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003400 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003401}
3402testcase TC_paging_tmsi_tch_f() 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('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'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_hf() 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('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003412 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003413}
3414
3415/* Paging by CGI */
3416testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3417 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3418 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003419 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003420 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003421}
3422
3423/* Paging by LAC+CI */
3424testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3425 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3426 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003427 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003428 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003429}
3430
3431/* Paging by CI */
3432testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3433 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3434 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003435 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003436 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003437}
3438
3439/* Paging by LAI */
3440testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3441 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3442 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003443 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003444 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003445}
3446
3447/* Paging by LAC */
3448testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3449 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3450 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003451 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003452 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003453}
3454
3455/* Paging by "all in BSS" */
3456testcase TC_paging_imsi_nochan_all() runs on test_CT {
3457 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3458 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003459 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003460 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003461}
3462
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003463/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003464testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3465 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3466 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 +01003467 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003468 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003469}
Harald Welte6f521d82017-12-11 19:52:02 +01003470
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003471/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003472testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3473 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3474 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003475 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003476 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003477}
3478
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003479/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003480testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3481 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3482 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003483 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003484 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003485}
3486
Harald Welte6f521d82017-12-11 19:52:02 +01003487/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003488testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3489 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3490 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3491 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003492 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003493}
3494
3495/* Paging on empty list: Verify none of them page */
3496testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3497 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3498 cid_list := { cIl_LAC := { } };
3499 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003500 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003501}
3502
Stefan Sperling049a86e2018-03-20 15:51:00 +01003503/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3504testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3505 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3506 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3507 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3508 f_shutdown_helper();
3509}
3510
Harald Welte6f521d82017-12-11 19:52:02 +01003511/* Verify paging retransmission interval + count */
3512/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003513/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003514
Harald Weltee65d40e2017-12-13 00:09:06 +01003515/* Verify PCH load */
3516testcase TC_paging_imsi_load() runs on test_CT {
3517 var BSSMAP_FIELD_CellIdentificationList cid_list;
3518 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003519 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003520 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003521 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003522
3523 /* tell BSC there is no paging space anymore */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003524 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003525 f_sleep(0.2);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003526 IPA_RSL[0][0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003527
3528 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3529 * there would be 8 retransmissions during 4 seconds */
3530 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003531 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003532 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003533 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003534 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003535 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003536 }
Harald Welte2caa1062018-03-17 18:19:05 +01003537 [] T_retrans.timeout {
3538 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003539 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte2caa1062018-03-17 18:19:05 +01003540 T_retrans.start;
3541 repeat;
3542 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003543 [] T.timeout {
3544 setverdict(pass);
3545 }
3546 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003547
3548 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003549}
3550
Harald Welte235ebf12017-12-15 14:18:16 +01003551/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003552testcase TC_paging_counter() runs on test_CT {
3553 var BSSMAP_FIELD_CellIdentificationList cid_list;
3554 timer T := 4.0;
3555 var integer i;
3556 var integer paging_attempted_bsc;
3557 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003558 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003559 var integer paging_expired_bts[NUM_BTS];
3560 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3561
3562 f_init();
3563
3564 /* read counters before paging */
3565 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003566 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3567 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3568 }
Harald Welte1ff69992017-12-14 12:31:17 +01003569 for (i := 0; i < NUM_BTS; i := i+1) {
3570 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3571 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3572 }
3573
3574 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3575
3576 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3577 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3578 for (i := 0; i < NUM_BTS; i := i+1) {
3579 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3580 paging_attempted_bts[i]+1);
3581 }
3582
3583 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3584 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003585 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3586 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3587 }
Harald Welte1ff69992017-12-14 12:31:17 +01003588 for (i := 0; i < NUM_BTS; i := i+1) {
3589 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3590 paging_expired_bts[i]+1);
3591 }
Harald Welte1ff69992017-12-14 12:31:17 +01003592
Philipp Maier282ca4b2018-02-27 17:17:00 +01003593 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003594}
3595
3596
Harald Welte10985002017-12-12 09:29:15 +01003597/* Verify paging stops after A-RESET */
3598testcase TC_paging_imsi_a_reset() runs on test_CT {
3599 var BSSMAP_FIELD_CellIdentificationList cid_list;
3600 timer T := 3.0;
3601 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003602 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003603
3604 /* Perform a BSSMAP Reset and wait for ACK */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003605 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 +01003606 alt {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003607 [] 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 +01003608 [] BSSAP.receive { repeat; }
3609 }
3610
Daniel Willmanncbef3982018-07-30 09:22:40 +02003611 /* Wait to avoid a possible race condition if a paging message is
3612 * received right before the reset ACK. */
3613 f_sleep(0.2);
3614
Harald Welte10985002017-12-12 09:29:15 +01003615 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003616 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003617 IPA_RSL[i][0].clear;
Philipp Maier1e6b4422018-02-23 14:02:13 +01003618 }
Harald Welte10985002017-12-12 09:29:15 +01003619
3620 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3621 T.start;
3622 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003623 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003624 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003625 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003626 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003627 [] IPA_RSL[1][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003628 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003629 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003630 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003631 [] IPA_RSL[2][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003632 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003633 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003634 }
Harald Welte10985002017-12-12 09:29:15 +01003635 [] T.timeout {
3636 setverdict(pass);
3637 }
3638 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003639
3640 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003641}
Harald Welteae026692017-12-09 01:03:01 +01003642
Philipp Maierf45824a2019-08-14 14:44:10 +02003643/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3644 * paging response we can not know which MSC is in charge, so we will blindly
3645 * pick the first configured MSC. This behavior is required in order to make
3646 * MT-CSFB calls working because in those cases the BSC can not know that the
3647 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3648 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003649 */
3650testcase TC_paging_resp_unsol() runs on test_CT {
3651
3652 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003653 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003654
3655 var BSSAP_N_CONNECT_ind rx_c_ind;
3656 var DchanTuple dt;
3657 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003658 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003659
3660 /* Send CHAN RQD and wait for allocation; acknowledge it */
3661 dt.rsl_chan_nr := f_chreq_act_ack();
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003662 dt.idx := {0, 0};
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003663
3664 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003665 f_ipa_tx(ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003666
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003667
Philipp Maierf45824a2019-08-14 14:44:10 +02003668 /* Expevct a CR with a matching Paging response on the A-Interface */
3669 T.start;
3670 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003671 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003672 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003673 dt.sccp_conn_id := rx_c_ind.connectionId;
3674 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003675 }
3676 [] BSSAP.receive {
3677 setverdict(fail, "Received unexpected message on A-Interface!");
3678 }
3679 [] T.timeout {
3680 setverdict(fail, "Received nothing on A-Interface!");
3681 }
3682 }
3683
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003684 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003685 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003686}
3687
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003688/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3689function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003690 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003691 var Hexstrings imsis := {};
3692 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003693 var integer rx_paging_num := 0;
3694 var integer i;
3695 timer T_rx := 60.0;
3696 timer T_load_ind := 1.0;
3697
3698 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003699 imsis := imsis & {f_gen_imsi(i)};
3700 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003701 }
3702
3703 f_init(1, guard_timeout := 100.0);
3704
3705 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003706 IPA_RSL[0][0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003707 if (send_pag_load_ind) {
3708 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003709 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(65535));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003710 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003711
3712 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003713 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003714 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 +02003715 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3716 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003717 }
3718
3719 T_rx.start;
3720 T_load_ind.start;
3721 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003722 [] 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 +02003723 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3724 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3725 var charstring imsi_str := hex2str(imsi_suffix);
3726 var integer imsi_idx := str2int(imsi_str);
3727 if (rx_paging_done[imsi_idx] == false) {
3728 rx_paging_done[imsi_idx] := true;
3729 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003730 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003731 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 +02003732 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003733 }
3734 if (rx_paging_num < num_subscribers) {
3735 repeat;
3736 }
3737 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003738 [] IPA_RSL[0][0].receive { repeat; }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003739 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003740 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3741 if (send_pag_load_ind) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003742 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(40));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003743 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003744 T_load_ind.start;
3745 repeat;
3746 }
3747 [] T_rx.timeout {
3748 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3749 mtc.stop;
3750 }
3751 }
3752
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003753 /* Drop OML connection to have all paging requests flushed: */
3754 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3755
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003756 f_shutdown_helper();
3757}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003758/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3759testcase TC_paging_500req() runs on test_CT {
3760 f_TC_paging_Nreq(500, true);
3761}
3762/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3763 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3764 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3765 * for current config yields ~8req/sec, so 480req/min maximum. */
3766testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3767 f_TC_paging_Nreq(450, false);
3768}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003769
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003770/* Test RSL link drop causes counter increment */
3771testcase TC_rsl_drop_counter() runs on test_CT {
3772 var integer rsl_fail;
3773
Harald Welte89d42e82017-12-17 16:42:41 +01003774 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003775
3776 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3777
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003778 f_ipa_rsl_stop(bts[0][0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003779
3780 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3781
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003782 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003783}
3784
3785/* TODO: Test OML link drop causes counter increment */
3786
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003787/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3788function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003789 var IPA_Client client;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003790 timer T := 10.0;
3791
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003792 client.id := "IPA-BTS0-TRX0-RSL";
3793 client.vc_IPA := IPA_Emulation_CT.create(client.id & "-IPA") alive;
3794 client.ccm_pars := c_IPA_default_ccm_pars;
3795 client.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
3796 client.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003797
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003798 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003799
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003800 f_init_mgcp(0, "VirtMGW");
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003801
3802 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003803 map(client.vc_IPA:IPA_PORT, system:IPA);
3804 connect(client.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0][0]);
3805 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 +01003806
3807 /* wait for IPA OML link to connect and then disconnect */
3808 T.start;
3809 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003810 [] IPA_RSL[0][0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003811 T.stop;
3812 return true;
3813 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003814 [] IPA_RSL[0][0].receive { repeat }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003815 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003816 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003817 }
3818 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003819 return false;
3820}
3821
3822/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3823testcase TC_rsl_unknown_unit_id() runs on test_CT {
3824 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3825 setverdict(pass);
3826 } else {
3827 setverdict(fail, "Timeout RSL waiting for connection to close");
3828 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003829 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003830}
3831
3832
3833/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3834testcase TC_oml_unknown_unit_id() runs on test_CT {
3835 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3836 setverdict(pass);
3837 } else {
3838 setverdict(fail, "Timeout OML waiting for connection to close");
3839 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003840 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003841}
3842
3843
Harald Weltec1a2fff2017-12-17 11:06:19 +01003844/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003845 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003846 ***********************************************************************/
3847
Harald Welte6811d102019-04-14 22:23:14 +02003848import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003849import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003850import from RSL_Emulation all;
3851import from MSC_ConnectionHandler all;
3852
3853type function void_fn(charstring id) runs on MSC_ConnHdlr;
3854
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003855/* helper function to create and connect a MSC_ConnHdlr component
3856 * TODO: allow connecting to TRX1..N, not only TRX0 */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003857private 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 +02003858 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003859 connect(vc_conn:RSL, bts[0][0].rsl.vc_RSL:CLIENT_PT);
3860 connect(vc_conn:RSL_PROC, bts[0][0].rsl.vc_RSL:RSL_PROC);
3861 if (isvalue(bts[1][0])) {
3862 connect(vc_conn:RSL1, bts[1][0].rsl.vc_RSL:CLIENT_PT);
3863 connect(vc_conn:RSL1_PROC, bts[1][0].rsl.vc_RSL:RSL_PROC);
Philipp Maier956a92f2018-02-16 10:58:07 +01003864 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003865 if (isvalue(bts[2][0])) {
3866 connect(vc_conn:RSL2, bts[2][0].rsl.vc_RSL:CLIENT_PT);
3867 connect(vc_conn:RSL2_PROC, bts[2][0].rsl.vc_RSL:RSL_PROC);
Neels Hofmeyr91401012019-07-11 00:42:35 +02003868 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003869 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003870 if (mp_enable_lcs_tests) {
3871 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3872 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3873 }
Daniel Willmannebdecc02020-08-12 15:30:17 +02003874 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003875 connect(vc_conn:MGCP_PROC, vc_MGCP[mgwpool_idx]:MGCP_PROC);
3876 connect(vc_conn:MGCP, vc_MGCP[mgwpool_idx]:MGCP_CLIENT);
3877 connect(vc_conn:MGCP_MULTI, vc_MGCP[mgwpool_idx]:MGCP_CLIENT_MULTI);
Harald Welte336820c2018-05-31 20:34:52 +02003878}
3879
Neels Hofmeyrda436782021-07-20 22:09:06 +02003880function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003881runs on test_CT return MSC_ConnHdlr {
3882 var charstring id := testcasename();
3883 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003884 var integer bssap_idx := 0;
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003885 var integer mgwpool_idx := 0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003886 if (isvalue(pars)) {
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003887 var TestHdlrParams pars_val := valueof(pars);
3888 bssap_idx := pars_val.mscpool.bssap_idx;
3889 mgwpool_idx := pars_val.mgwpool_idx;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003890 }
Harald Welte336820c2018-05-31 20:34:52 +02003891 vc_conn := MSC_ConnHdlr.create(id);
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02003892 f_connect_handler(vc_conn, bssap_idx, mgwpool_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003893 return vc_conn;
3894}
3895
3896function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3897runs on test_CT return MSC_ConnHdlr {
3898 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003899 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003900 return vc_conn;
3901}
3902
Neels Hofmeyrda436782021-07-20 22:09:06 +02003903function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3904runs on test_CT return MSC_ConnHdlr {
3905 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3906}
3907
Harald Weltea0630032018-03-20 21:09:55 +01003908/* first function inside ConnHdlr component; sets g_pars + starts function */
3909private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3910runs on MSC_ConnHdlr {
3911 if (isvalue(pars)) {
3912 g_pars := valueof(pars);
3913 }
3914 fn.apply(id);
3915}
3916
Oliver Smith26a3db72021-07-09 13:51:29 +02003917private function f_vty_encryption_a5(charstring options) runs on test_CT {
3918 f_vty_transceive(BSCVTY, "configure terminal");
3919 f_vty_transceive(BSCVTY, "network");
3920 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3921 f_vty_transceive(BSCVTY, "exit");
3922 f_vty_transceive(BSCVTY, "exit");
3923}
3924
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003925const charstring VTY_A5_DEFAULT := "0 1 3";
3926
Oliver Smith26a3db72021-07-09 13:51:29 +02003927private function f_vty_encryption_a5_reset() runs on test_CT {
3928 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003929 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003930}
3931
Harald Welte3c86ea02018-05-10 22:28:05 +02003932/* Establish signalling channel (non-assignment case) followed by cipher mode */
3933private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003934 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3935 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003936 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003937 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3938 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3939 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3940 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003941
Philipp Maier23000732018-05-18 11:25:37 +02003942 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003943 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003944}
3945testcase TC_ciph_mode_a5_0() runs on test_CT {
3946 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003947 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003948 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3949
3950 f_init(1, true);
3951 f_sleep(1.0);
3952 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3953 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003954 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003955}
3956testcase TC_ciph_mode_a5_1() runs on test_CT {
3957 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003958 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003959 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3960
3961 f_init(1, true);
3962 f_sleep(1.0);
3963 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3964 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003965 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003966}
Oliver Smith50b98122021-07-09 15:00:28 +02003967/* OS#4975: verify that A5/2 is preferred over A5/0 */
3968testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3969 var MSC_ConnHdlr vc_conn;
3970 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3971
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003972 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003973
3974 f_init(1, true);
3975 f_vty_encryption_a5("0 1 2 3");
3976 f_sleep(1.0);
3977 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3978 vc_conn.done;
3979 f_vty_encryption_a5_reset();
3980 f_shutdown_helper();
3981}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003982/* OS#4975: verify that A5/1 is preferred over A5/2 */
3983testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3984 var MSC_ConnHdlr vc_conn;
3985 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3986
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003987 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003988
3989 f_init(1, true);
3990 f_vty_encryption_a5("1 2");
3991 f_sleep(1.0);
3992 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3993 vc_conn.done;
3994 f_vty_encryption_a5_reset();
3995 f_shutdown_helper();
3996}
Harald Welte3c86ea02018-05-10 22:28:05 +02003997testcase TC_ciph_mode_a5_3() runs on test_CT {
3998 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003999 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02004000 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
4001
4002 f_init(1, true);
4003 f_sleep(1.0);
4004 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4005 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004006 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02004007}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004008/* Establish a Signalling channel with A5/4 encryption. */
4009testcase TC_ciph_mode_a5_4() runs on test_CT {
4010 var MSC_ConnHdlr vc_conn;
4011 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4012 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02004013
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004014 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02004015 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004016 f_sleep(1.0);
4017 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
4018 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02004019 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02004020 f_shutdown_helper();
4021}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004022/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
4023private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
4024 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4025 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
4026 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4027 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4028
4029 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004030 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004031}
4032testcase TC_assignment_aoip_tla_v6() runs on test_CT {
4033 var MSC_ConnHdlr vc_conn;
4034 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4035
4036 f_init(1, true);
4037 f_sleep(1.0);
4038 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
4039 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004040 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02004041}
4042
Harald Welte3c86ea02018-05-10 22:28:05 +02004043
4044/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02004045private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004046 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4047 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004048
Harald Welte552620d2017-12-16 23:21:36 +01004049 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4050 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01004051
Harald Weltea0630032018-03-20 21:09:55 +01004052 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004053 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004054}
Harald Welte552620d2017-12-16 23:21:36 +01004055testcase TC_assignment_fr_a5_0() runs on test_CT {
4056 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004057 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004058 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01004059
Harald Welte89d42e82017-12-17 16:42:41 +01004060 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004061 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004062 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004063 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004064 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004065}
Harald Welte552620d2017-12-16 23:21:36 +01004066testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01004067 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004068 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004069 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004070
Harald Welte89d42e82017-12-17 16:42:41 +01004071 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004072 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004073 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4074 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004075 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02004076}
4077testcase TC_assignment_fr_a5_3() runs on test_CT {
4078 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004079 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004080 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004081
Harald Welte651fcdc2018-05-10 20:23:16 +02004082 f_init(1, true);
4083 f_sleep(1.0);
4084 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004085 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004086 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004087}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004088/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
4089testcase TC_assignment_fr_a5_4() runs on test_CT {
4090 var MSC_ConnHdlr vc_conn;
4091 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4092 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
4093
4094 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004095 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004096 f_sleep(1.0);
4097 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4098 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02004099 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004100 f_shutdown_helper();
4101}
Harald Weltec1a2fff2017-12-17 11:06:19 +01004102
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02004103/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
4104testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
4105 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4106 var MSC_ConnHdlr vc_conn;
4107
4108 f_init(1, true);
4109 f_sleep(1.0);
4110
4111 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4112 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4113 vc_conn.done;
4114 f_shutdown_helper();
4115}
4116
Harald Welte552620d2017-12-16 23:21:36 +01004117/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4118private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004119 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004120 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004121 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004122
4123 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004124 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4125
Harald Weltea0630032018-03-20 21:09:55 +01004126 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004127 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004128}
Harald Welte552620d2017-12-16 23:21:36 +01004129testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4130 var MSC_ConnHdlr vc_conn;
4131
Harald Welte89d42e82017-12-17 16:42:41 +01004132 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004133 f_sleep(1.0);
4134
Harald Welte8863fa12018-05-10 20:15:27 +02004135 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004136 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004137 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004138}
4139
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004140private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4141 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4142 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004143
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004144 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4145 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4146
4147 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4148
4149 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004150
4151 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4152 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4153
4154 f_create_chan_and_exp();
4155 /* we should now have a COMPL_L3 at the MSC */
4156
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004157 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004158 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004159 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004160}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004161testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4162 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004163 var MSC_ConnHdlr vc_conn;
4164
Harald Welte89d42e82017-12-17 16:42:41 +01004165 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004166 f_sleep(1.0);
4167
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004168 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004169 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004170 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004171 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004172}
4173
4174
Harald Welte4532e0a2017-12-23 02:05:44 +01004175private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004176 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004177 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004178 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004179 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004180
4181 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004182 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004183
4184 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004185 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4186 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004187 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4188 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4189 };
4190 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004191 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004192}
4193
4194testcase TC_assignment_sign() runs on test_CT {
4195 var MSC_ConnHdlr vc_conn;
4196
4197 f_init(1, true);
4198 f_sleep(1.0);
4199
Harald Welte8863fa12018-05-10 20:15:27 +02004200 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004201 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004202 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004203}
4204
Harald Welte60aa5762018-03-21 19:33:13 +01004205/***********************************************************************
4206 * Codec (list) testing
4207 ***********************************************************************/
4208
4209/* check if the given rsl_mode is compatible with the a_elem */
4210private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4211return boolean {
4212 select (a_elem.codecType) {
4213 case (GSM_FR) {
4214 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4215 return true;
4216 }
4217 }
4218 case (GSM_HR) {
4219 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4220 return true;
4221 }
4222 }
4223 case (GSM_EFR) {
4224 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4225 return true;
4226 }
4227 }
4228 case (FR_AMR) {
4229 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4230 return true;
4231 }
4232 }
4233 case (HR_AMR) {
4234 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4235 return true;
4236 }
4237 }
4238 case else { }
4239 }
4240 return false;
4241}
4242
4243/* check if the given rsl_mode is compatible with the a_list */
4244private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4245return boolean {
4246 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4247 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4248 return true;
4249 }
4250 }
4251 return false;
4252}
4253
4254/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004255function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004256return BSSMAP_IE_ChannelType {
4257 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4258 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4259 select (a_elem.codecType) {
4260 case (GSM_FR) {
4261 ret.channelRateAndType := ChRate_TCHF;
4262 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4263 }
4264 case (GSM_HR) {
4265 ret.channelRateAndType := ChRate_TCHH;
4266 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4267 }
4268 case (GSM_EFR) {
4269 ret.channelRateAndType := ChRate_TCHF;
4270 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4271 }
4272 case (FR_AMR) {
4273 ret.channelRateAndType := ChRate_TCHF;
4274 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4275 }
4276 case (HR_AMR) {
4277 ret.channelRateAndType := ChRate_TCHH;
4278 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4279 }
4280 case else {
4281 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004282 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004283 }
4284 }
4285 return ret;
4286}
4287
Harald Weltea63b9102018-03-22 20:36:16 +01004288private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4289return template RSL_IE_Body {
4290 var template RSL_IE_Body mode_ie := {
4291 chan_mode := {
4292 len := ?,
4293 reserved := ?,
4294 dtx_d := ?,
4295 dtx_u := ?,
4296 spd_ind := RSL_SPDI_SPEECH,
4297 ch_rate_type := -,
4298 coding_alg_rate := -
4299 }
4300 }
4301
4302 select (a_elem.codecType) {
4303 case (GSM_FR) {
4304 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4305 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4306 }
4307 case (GSM_HR) {
4308 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4309 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4310 }
4311 case (GSM_EFR) {
4312 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4313 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4314 }
4315 case (FR_AMR) {
4316 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4317 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4318 }
4319 case (HR_AMR) {
4320 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4321 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4322 }
4323 }
4324 return mode_ie;
4325}
4326
Harald Welte60aa5762018-03-21 19:33:13 +01004327type record CodecListTest {
4328 BSSMAP_IE_SpeechCodecList codec_list,
4329 charstring id
4330}
4331type record of CodecListTest CodecListTests
4332
4333private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004334 f_assignment_codec(id);
4335}
4336
4337private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02004338 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02004339 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Harald Welte60aa5762018-03-21 19:33:13 +01004340
4341 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004342 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004343 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4344 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4345 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004346 if (isvalue(g_pars.expect_mr_s0_s7)) {
4347 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4348 g_pars.expect_mr_s0_s7;
4349 }
Harald Welte79f3f542018-05-25 20:02:37 +02004350 }
Harald Welte60aa5762018-03-21 19:33:13 +01004351 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4352 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004353 log("expecting ASS COMPL like this: ", exp_compl);
4354
4355 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004356
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004357 if (not g_pars.expect_channel_mode_modify) {
4358 /* Verify that the RSL-side activation actually matches our expectations */
4359 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004360
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004361 var RSL_IE_Body mode_ie;
4362 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4363 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004364 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004365 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004366 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4367 if (not match(mode_ie, t_mode_ie)) {
4368 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4369 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004370 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004371
4372 var RSL_IE_Body mr_conf;
4373 if (g_pars.expect_mr_conf_ie != omit) {
4374 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4375 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4376 mtc.stop;
4377 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004378 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004379
4380 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
Vadim Yanitskiy8b189372022-09-14 17:31:17 +07004381 setverdict(fail, "RSL MR CONFIG IE does not match expectation. ",
4382 "Expected: ", g_pars.expect_mr_conf_ie, ", got: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004383 }
4384 } else {
4385 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4386 log("found RSL MR CONFIG IE: ", mr_conf);
4387 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4388 mtc.stop;
4389 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004390 }
4391 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004392
4393 if (do_perform_clear) {
4394 f_perform_clear();
4395 }
Harald Welte60aa5762018-03-21 19:33:13 +01004396}
4397
Philipp Maierd0e64b02019-03-13 14:15:23 +01004398private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4399
4400 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4401 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4402
4403 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004404 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004405 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4406 }
4407 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4408 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4409 log("expecting ASS FAIL like this: ", exp_fail);
4410
4411 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004412 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004413}
4414
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004415const CounterNameVals counternames_bsc_bts_assignment := {
4416 { "assignment:attempted", 0 },
4417 { "assignment:completed", 0 },
4418 { "assignment:stopped", 0 },
4419 { "assignment:no_channel", 0 },
4420 { "assignment:timeout", 0 },
4421 { "assignment:failed", 0 },
4422 { "assignment:error", 0 }
4423};
4424
4425const CounterNameVals counternames_bts_assignment := {
4426 { "assignment:attempted_sign", 0 },
4427 { "assignment:attempted_speech", 0 },
4428 { "assignment:completed_sign", 0 },
4429 { "assignment:completed_speech", 0 },
4430 { "assignment:stopped_sign", 0 },
4431 { "assignment:stopped_speech", 0 },
4432 { "assignment:no_channel_sign", 0 },
4433 { "assignment:no_channel_speech", 0 },
4434 { "assignment:timeout_sign", 0 },
4435 { "assignment:timeout_speech", 0 },
4436 { "assignment:failed_sign", 0 },
4437 { "assignment:failed_speech", 0 },
4438 { "assignment:error_sign", 0 },
4439 { "assignment:error_speech", 0 }
4440};
4441
4442function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4443 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4444 f_ctrs_bts_init(bts_count, bts_names);
4445 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4446}
4447
Harald Welte60aa5762018-03-21 19:33:13 +01004448testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004449 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004450 var MSC_ConnHdlr vc_conn;
4451
4452 f_init(1, true);
4453 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004454 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004455
4456 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004457 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004458 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004459
4460 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4461 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4462 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4463 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4464 f_ctrs_bts_verify();
4465
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004466 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004467}
4468
4469testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004470 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004471 var MSC_ConnHdlr vc_conn;
4472
4473 f_init(1, true);
4474 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004475 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004476
4477 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004478 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004479 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004480
4481 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4482 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4483 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4484 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4485 f_ctrs_bts_verify();
4486
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004487 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004488}
4489
4490testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004491 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004492 var MSC_ConnHdlr vc_conn;
4493
4494 f_init(1, true);
4495 f_sleep(1.0);
4496
4497 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004498 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004499 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004500 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004501}
4502
Philipp Maierd0e64b02019-03-13 14:15:23 +01004503/* Allow 5,90k only (current default config) */
4504private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004505 f_vty_cfg_msc(BSCVTY, 0, {
4506 "amr-config 12_2k forbidden",
4507 "amr-config 10_2k forbidden",
4508 "amr-config 7_95k forbidden",
4509 "amr-config 7_40k forbidden",
4510 "amr-config 6_70k forbidden",
4511 "amr-config 5_90k allowed",
4512 "amr-config 5_15k forbidden",
4513 "amr-config 4_75k forbidden"
4514 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004515}
4516
4517/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4518 * ("Config-NB-Code = 1") */
4519private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004520 f_vty_cfg_msc(BSCVTY, 0, {
4521 "amr-config 12_2k allowed",
4522 "amr-config 10_2k forbidden",
4523 "amr-config 7_95k forbidden",
4524 "amr-config 7_40k allowed",
4525 "amr-config 6_70k forbidden",
4526 "amr-config 5_90k allowed",
4527 "amr-config 5_15k forbidden",
4528 "amr-config 4_75k allowed"
4529 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004530}
4531
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004532private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4533 var charstring tch;
4534 if (fr) {
4535 tch := "tch-f";
4536 } else {
4537 tch := "tch-h";
4538 }
4539 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4540}
4541
4542/* Set the AMR start-mode for this TCH back to the default configuration. */
4543private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4544 f_vty_amr_start_mode_set(fr, "auto");
4545}
4546
Harald Welte60aa5762018-03-21 19:33:13 +01004547testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004548 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004549 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004550
4551 /* Note: This setups the codec configuration. The parameter payload in
4552 * mr_conf must be consistant with the parameter codecElements in pars
4553 * and also must match the amr-config in osmo-bsc.cfg! */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004554 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004555 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004556 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004557 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004558
Harald Welte60aa5762018-03-21 19:33:13 +01004559 f_init(1, true);
4560 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004561 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004562 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004563
Harald Welte8863fa12018-05-10 20:15:27 +02004564 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004565 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004566
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004567 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4568 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4569 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4570 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4571 f_ctrs_bts_verify();
4572
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004573 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004574 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004575}
4576
4577testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004578 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004579 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004580
4581 /* See note above */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004582 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004583 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004584 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07004585 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004586
Harald Welte60aa5762018-03-21 19:33:13 +01004587 f_init(1, true);
4588 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004589 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004590 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004591
Harald Welte8863fa12018-05-10 20:15:27 +02004592 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004593 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004594
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004595 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4596 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4597 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4598 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4599 f_ctrs_bts_verify();
4600
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004601 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004602 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004603}
4604
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004605/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4606testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4607 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4608 var MSC_ConnHdlr vc_conn;
4609
4610 f_init(1, true);
4611 f_sleep(1.0);
4612
4613 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4614 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4615 * expecting a Channel Mode Modify if the channel type is compatible. */
4616 f_disable_all_sdcch();
4617 f_disable_all_tch_h();
4618
4619 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4620 pars.expect_channel_mode_modify := true;
4621 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4622 vc_conn.done;
4623
4624 f_enable_all_sdcch();
4625 f_enable_all_tch();
4626 f_shutdown_helper();
4627}
4628
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004629/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4630testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4631 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4632 var MSC_ConnHdlr vc_conn;
4633
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004634 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4635 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4636 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Vadim Yanitskiy36fe9582022-09-14 15:25:04 +07004637 pars.expect_mr_conf_ie := c_mr_conf_5_90;
4638 pars.expect_mr_conf_ie.multirate_cfg.icmi := false; /* expect ICMI=0, smod=00: */
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004639
4640 f_init(1, true);
4641 f_sleep(1.0);
4642
4643 /* First set nonzero start mode bits */
4644 f_vty_amr_start_mode_set(true, "4");
4645 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4646 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4647 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4648 f_vty_amr_start_mode_set(true, "auto");
4649
4650 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4651 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004652
4653 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4654 f_vty_amr_start_mode_set(true, "1");
4655 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004656 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004657}
4658
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004659function f_TC_assignment_codec_amr(boolean fr, RSL_IE_MultirateCfg mr_cfg,
4660 bitstring s8_s0, bitstring exp_s8_s0,
4661 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004662runs on test_CT {
4663
4664 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4665 var MSC_ConnHdlr vc_conn;
4666
Philipp Maierd0e64b02019-03-13 14:15:23 +01004667 if (fr) {
4668 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4669 } else {
4670 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4671 }
4672 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4673 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004674 pars.expect_mr_conf_ie := { multirate_cfg := mr_cfg };
Philipp Maierd0e64b02019-03-13 14:15:23 +01004675 pars.expect_mr_s0_s7 := exp_s8_s0;
4676
4677 f_init(1, true);
4678 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004679 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004680 f_sleep(1.0);
4681
4682 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4683 vc_conn.done;
4684 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004685 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004686}
4687
4688function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4689runs on test_CT {
4690
4691 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4692 var MSC_ConnHdlr vc_conn;
4693
4694 if (fr) {
4695 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4696 } else {
4697 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4698 }
4699 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4700 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4701
4702 f_init(1, true);
4703 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004704 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004705 f_sleep(1.0);
4706
4707 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4708 vc_conn.done;
4709 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004710 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004711}
4712
Philipp Maierd0e64b02019-03-13 14:15:23 +01004713/* Set S1, we expect an AMR multirate configuration IE with all four rates
4714 * set. */
4715testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004716 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4717 params := '20882208'O));
4718 f_TC_assignment_codec_amr(true, mr_cfg, '00000011'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004719 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004720}
4721
4722/* Set S1, we expect an AMR multirate configuration IE with the lower three
4723 * rates set. */
4724testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004725 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4726 params := '208820'O));
4727 f_TC_assignment_codec_amr(false, mr_cfg, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004728 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004729}
4730
4731/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4732 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4733testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004734 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4735 params := '20882208'O));
4736 f_TC_assignment_codec_amr(true, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004737 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004738}
4739
4740/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4741 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4742testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004743 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4744 params := '208820'O));
4745 f_TC_assignment_codec_amr(false, mr_cfg, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004746 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004747}
4748
4749/* The following block of tests selects more and more rates until all four
4750 * possible rates are in the active set (full rate) */
4751testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004752 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4753 f_TC_assignment_codec_amr(true, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004754 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004755}
4756
4757testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004758 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4759 params := '2080'O));
4760 f_TC_assignment_codec_amr(true, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004761 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004762}
4763
4764testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004765 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4766 params := '208820'O));
4767 f_TC_assignment_codec_amr(true, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004768 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004769}
4770
4771testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004772 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4773 params := '20882208'O));
4774 f_TC_assignment_codec_amr(true, mr_cfg, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004775 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004776}
4777
4778/* The following block of tests selects more and more rates until all three
4779 * possible rates are in the active set (half rate) */
4780testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004781 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000001'B));
4782 f_TC_assignment_codec_amr(false, mr_cfg, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004783 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004784}
4785
4786testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004787 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00000101'B,
4788 params := '2080'O));
4789 f_TC_assignment_codec_amr(false, mr_cfg, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004790 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004791}
4792
4793testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004794 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4795 params := '208820'O));
4796 f_TC_assignment_codec_amr(false, mr_cfg, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004797 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004798}
4799
4800/* The following block tests what happens when the MSC does offer rate
4801 * configurations that are not supported by the BSC. Normally such situations
4802 * should not happen because the MSC gets informed by the BSC in advance via
4803 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4804 * to offer rates that are not applicable anyway. */
4805
4806testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004807 /* Try to include 12,2k in into the active set even though the channel
4808 * is half rate only. The BSC is expected to remove the 12,0k */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004809 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '00010101'B,
4810 params := '208820'O));
4811 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004812 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004813}
4814
4815testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004816 /* See what happens when all rates are selected at once. Since then
4817 * Also S1 is selected, this setting will be prefered and we should
4818 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004819 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4820 params := '20882208'O));
4821 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004822 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004823}
4824
4825testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004826 /* Same as above, but with S1 missing, the MSC is then expected to
4827 * select the currently supported rates, which are also 12.2k, 7,40k,
4828 * 5,90k, and 4,75k, into the active set. */
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004829 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(codec_modes := '10010101'B,
4830 params := '20882208'O));
4831 f_TC_assignment_codec_amr(true, mr_cfg, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004832 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004833}
4834
4835testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004836 /* Try to select no rates at all */
4837 f_TC_assignment_codec_amr_fail(true, '00000000'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_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004842 /* Try to select only unsupported rates */
4843 f_TC_assignment_codec_amr_fail(true, '01101000'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_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004848 /* Try to select 12,2k for half rate */
4849 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004850 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004851}
4852
Neels Hofmeyr21863562020-11-26 00:34:33 +00004853testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004854 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4855 codec_modes := '10010101'B,
4856 params := '20882208'O));
4857 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004858 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004859}
4860
4861testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
Vadim Yanitskiy3998c032022-09-14 17:19:44 +07004862 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(icmi := false,
4863 codec_modes := '00010101'B,
4864 params := '208820'O));
4865 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B,
Neels Hofmeyr21863562020-11-26 00:34:33 +00004866 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004867 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004868}
4869
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004870testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004871 /* "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 +07004872 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 3,
4873 codec_modes := '10010101'B,
4874 params := '20882208'O));
4875 f_TC_assignment_codec_amr(true, mr_cfg, '11111111'B, '00000010'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004876 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004877}
4878
4879testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004880 /* "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 +07004881 var RSL_IE_MultirateCfg mr_cfg := valueof(ts_RSL_MultirateCfg(start_mode := 2,
4882 codec_modes := '00010101'B,
4883 params := '208820'O));
4884 f_TC_assignment_codec_amr(false, mr_cfg, '10010101'B, '00010101'B, start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004885 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004886}
4887
Philipp Maierac09bfc2019-01-08 13:41:39 +01004888private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004889 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4890 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4891 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4892 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004893}
4894
4895private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004896 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4897 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004898}
4899
4900private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004901 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4902 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4903 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4904 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4905 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4906 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004907}
4908
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004909private function f_disable_all_sdcch() runs on test_CT {
4910 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4911 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4912 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4913 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4914}
4915
4916private function f_enable_all_sdcch() runs on test_CT {
4917 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4918 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4919 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4920 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4921}
4922
Philipp Maierac09bfc2019-01-08 13:41:39 +01004923/* Allow HR only */
4924private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4925 g_pars := f_gen_test_hdlr_pars();
4926 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4927 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4928 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4929 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4930 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4931 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4932 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004933 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004934}
4935
4936/* Allow FR only */
4937private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4938 g_pars := f_gen_test_hdlr_pars();
4939 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4940 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4941 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4942 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4943 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4944 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4945 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004946 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004947}
4948
4949/* Allow HR only (expect assignment failure) */
4950private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4951 g_pars := f_gen_test_hdlr_pars();
4952 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4953 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4954 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4955 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4956 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4957 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4958 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004959 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004960}
4961
4962/* Allow FR only (expect assignment failure) */
4963private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4964 g_pars := f_gen_test_hdlr_pars();
4965 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4966 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4967 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4968 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4969 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4970 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4971 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004972 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004973}
4974
4975/* Allow FR and HR, but prefer FR */
4976private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4977 g_pars := f_gen_test_hdlr_pars();
4978 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4979 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4980 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4981 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4982 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4983 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4984 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4985 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004986 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004987}
4988
4989/* Allow FR and HR, but prefer HR */
4990private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4991 g_pars := f_gen_test_hdlr_pars();
4992 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4993 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4994 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4995 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4996 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4997 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4998 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4999 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005000 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005001}
5002
5003/* Allow FR and HR, but prefer FR */
5004private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5005 g_pars := f_gen_test_hdlr_pars();
5006 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5007 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5008 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5009 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5010 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5011 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5012 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5013 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005014 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005015}
5016
5017/* Allow FR and HR, but prefer HR */
5018private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5019 g_pars := f_gen_test_hdlr_pars();
5020 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5021 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5022 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5023 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5024 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5025 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5026 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5027 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005028 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005029}
5030
5031/* Request a HR channel while all FR channels are exhausted, this is expected
5032 * to work without conflicts */
5033testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
5034 var MSC_ConnHdlr vc_conn;
5035 f_init(1, true);
5036 f_sleep(1.0);
5037 f_enable_all_tch();
5038 f_disable_all_tch_f();
5039 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
5040 vc_conn.done;
5041 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005042 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005043}
5044
5045/* Request a FR channel while all FR channels are exhausted, this is expected
5046 * to fail. */
5047testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
5048 var MSC_ConnHdlr vc_conn;
5049 f_init(1, true);
5050 f_sleep(1.0);
5051 f_enable_all_tch();
5052 f_disable_all_tch_f();
5053 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
5054 vc_conn.done;
5055 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005056 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005057}
5058
5059/* Request a FR (prefered) or alternatively a HR channel while all FR channels
5060 * are exhausted, this is expected to be resolved by selecting a HR channel. */
5061testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
5062 var MSC_ConnHdlr vc_conn;
5063 f_init(1, true);
5064 f_sleep(1.0);
5065 f_enable_all_tch();
5066 f_disable_all_tch_f();
5067 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
5068 vc_conn.done;
5069 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005070 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005071}
5072
5073/* Request a HR (prefered) or alternatively a FR channel while all FR channels
5074 * are exhausted, this is expected to work without conflicts. */
5075testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
5076 var MSC_ConnHdlr vc_conn;
5077 f_init(1, true);
5078 f_sleep(1.0);
5079 f_enable_all_tch();
5080 f_disable_all_tch_f();
5081 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
5082 vc_conn.done;
5083 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005084 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005085}
5086
5087/* Request a FR channel while all HR channels are exhausted, this is expected
5088 * to work without conflicts */
5089testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
5090 var MSC_ConnHdlr vc_conn;
5091 f_init(1, true);
5092 f_sleep(1.0);
5093 f_enable_all_tch();
5094 f_disable_all_tch_h();
5095 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
5096 vc_conn.done;
5097 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005098 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005099}
5100
5101/* Request a HR channel while all HR channels are exhausted, this is expected
5102 * to fail. */
5103testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
5104 var MSC_ConnHdlr vc_conn;
5105 f_init(1, true);
5106 f_sleep(1.0);
5107 f_enable_all_tch();
5108 f_disable_all_tch_h();
5109 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
5110 vc_conn.done;
5111 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005112 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005113}
5114
5115/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5116 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5117testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5118 var MSC_ConnHdlr vc_conn;
5119 f_init(1, true);
5120 f_sleep(1.0);
5121 f_enable_all_tch();
5122 f_disable_all_tch_h();
5123 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5124 vc_conn.done;
5125 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005126 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005127}
5128
5129/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5130 * are exhausted, this is expected to work without conflicts. */
5131testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5132 var MSC_ConnHdlr vc_conn;
5133 f_init(1, true);
5134 f_sleep(1.0);
5135 f_enable_all_tch();
5136 f_disable_all_tch_h();
5137 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5138 vc_conn.done;
5139 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005140 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005141}
5142
5143/* Allow FR and HR, but prefer HR */
5144private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5145 g_pars := f_gen_test_hdlr_pars();
5146 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5147 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5148 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5149 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5150 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5151 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5152 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5153 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005154 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005155}
5156
5157/* Allow FR and HR, but prefer FR */
5158private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5159 g_pars := f_gen_test_hdlr_pars();
5160 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5161 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5162 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5163 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5164 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5165 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5166 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5167 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005168 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005169}
5170
5171/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5172 * HR, which is the prefered type, is selected. */
5173testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5174 var MSC_ConnHdlr vc_conn;
5175 f_init(1, true);
5176 f_sleep(1.0);
5177 f_enable_all_tch();
5178 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5179 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005180 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005181}
5182
5183/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5184 * FR, which is the prefered type, is selected. */
5185testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5186 var MSC_ConnHdlr vc_conn;
5187 f_init(1, true);
5188 f_sleep(1.0);
5189 f_enable_all_tch();
5190 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5191 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005192 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005193}
5194
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005195/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5196private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5197 g_pars := f_gen_test_hdlr_pars();
5198 g_pars.ra := '02'O; /* RA containing reason=LU */
5199
5200 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5201 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5202 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5203 var template uint3_t tsc := ?;
5204
5205 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5206 f_create_bssmap_exp(l3_enc);
5207 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5208 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5209
5210 /* we should now have a COMPL_L3 at the MSC */
5211 timer T := 10.0;
5212 T.start;
5213 alt {
5214 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5215 [] T.timeout {
5216 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5217 }
5218 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005219
5220 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005221}
5222testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5223 var MSC_ConnHdlr vc_conn;
5224 f_init(1, true);
5225 f_sleep(1.0);
5226 f_disable_all_sdcch();
5227 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5228 vc_conn.done;
5229 f_enable_all_sdcch();
5230 f_shutdown_helper();
5231}
5232
5233/* Request a signalling channel with all SDCCH exhausted, it is
5234 expected that no TCH will be selected for signalling and assigment will fail
5235 because it's dictated by VTY config */
5236testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5237 var RSL_Message rsl_unused, rsl_msg;
5238 var GsmRrMessage rr;
5239 f_init(1, false);
5240 f_sleep(1.0);
5241 f_vty_allow_tch_for_signalling(false, 0);
5242 f_disable_all_sdcch();
5243
5244 /* RA containing reason=LU */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005245 f_ipa_tx(ts_RSL_CHAN_RQD('02'O, 2342));
5246 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005247 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5248 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5249 setverdict(fail, "Expected reject");
5250 }
5251
5252 f_vty_allow_tch_for_signalling(true, 0);
5253 f_enable_all_sdcch();
5254 f_shutdown_helper();
5255}
5256
5257/* Request a voice channel with all SDCCH exhausted, it is
5258 * expected that TCH channel will be allocated since the VTY option is only
5259 * aimed at signalling requests */
5260private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5261 g_pars := f_gen_test_hdlr_pars();
5262 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5263
5264 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5265 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5266 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5267 var template uint3_t tsc := ?;
5268
5269 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5270 f_create_bssmap_exp(l3_enc);
5271 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5272 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5273
5274 /* we should now have a COMPL_L3 at the MSC */
5275 timer T := 10.0;
5276 T.start;
5277 alt {
5278 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5279 [] T.timeout {
5280 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5281 }
5282 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005283 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005284}
5285testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5286 var MSC_ConnHdlr vc_conn;
5287 f_init(1, true);
5288 f_sleep(1.0);
5289 f_vty_allow_tch_for_signalling(false, 0);
5290 f_disable_all_sdcch();
5291
5292 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5293 vc_conn.done;
5294
5295 f_vty_allow_tch_for_signalling(true, 0);
5296 f_enable_all_sdcch();
5297 f_shutdown_helper();
5298}
5299
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005300/* Test Osmux setup BSC<->MSC */
5301testcase TC_assignment_osmux_cn() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005302 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5303 var MSC_ConnHdlr vc_conn;
5304
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005305 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5306 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5307 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiyb9bf00f2022-09-14 15:35:37 +07005308 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02005309 pars.use_osmux_cn := true;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005310
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02005311 g_osmux_enabled_cn := true;
5312 f_init(1, true);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005313 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005314 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005315
5316 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5317 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005318
5319 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005320 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005321}
5322
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005323/* Test Osmux setup BTS<->BSC */
5324testcase TC_assignment_osmux_bts() runs on test_CT {
5325 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5326 var MSC_ConnHdlr vc_conn;
5327
5328 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5329 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5330 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005331 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005332 pars.use_osmux_bts := true;
5333
5334 g_osmux_enabled_bts := true;
5335 f_init(1, true);
5336 f_sleep(1.0);
5337 f_vty_amr_start_mode_set(false, "1");
5338
5339 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5340 vc_conn.done;
5341
5342 f_vty_amr_start_mode_restore(false);
5343 f_shutdown_helper();
5344}
5345
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +02005346/* Test non-AMR codecs still work fine as RTP when Osmux is enabled BTS<->BSC<->MSC */
5347testcase TC_assignment_codec_hr_osmux_on() runs on test_CT {
5348 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5349 var MSC_ConnHdlr vc_conn;
5350
5351 g_osmux_enabled_cn := true;
5352 g_osmux_enabled_bts := true;
5353 f_init(1, true);
5354 f_sleep(1.0);
5355 f_ctrs_bsc_and_bts_assignment_init(1);
5356
5357 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
5358 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5359 vc_conn.done;
5360
5361 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
5362 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
5363 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
5364 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
5365 f_ctrs_bts_verify();
5366
5367 f_shutdown_helper();
5368}
5369
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005370/* Test Osmux setup BTS<->BSC<->MSC */
5371testcase TC_assignment_osmux() runs on test_CT {
5372 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5373 var MSC_ConnHdlr vc_conn;
5374
5375 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5376 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5377 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Vadim Yanitskiy59494702022-09-14 15:29:04 +07005378 pars.expect_mr_conf_ie := c_mr_conf_5_90;
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +02005379 pars.use_osmux_cn := true;
5380 pars.use_osmux_bts := true;
5381
5382 g_osmux_enabled_cn := true;
5383 g_osmux_enabled_bts := true;
5384 f_init(1, true);
5385 f_sleep(1.0);
5386 f_vty_amr_start_mode_set(false, "1");
5387
5388 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5389 vc_conn.done;
5390
5391 f_vty_amr_start_mode_restore(false);
5392 f_shutdown_helper();
5393}
5394
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005395/* test the procedure of the MSC requesting a Classmark Update:
5396 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5397 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005398private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005399 g_pars := f_gen_test_hdlr_pars();
5400
Harald Weltea0630032018-03-20 21:09:55 +01005401 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005402 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005403
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005404 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5405 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5406
Harald Welte898113b2018-01-31 18:32:21 +01005407 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5408 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5409 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005410
5411 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005412}
5413testcase TC_classmark() runs on test_CT {
5414 var MSC_ConnHdlr vc_conn;
5415 f_init(1, true);
5416 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005417 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005418 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005419 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005420}
5421
Harald Welteeddf0e92020-06-21 19:42:15 +02005422/* Send a CommonID from the simulated MSC and verify that the information is used to
5423 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5424private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5425 g_pars := f_gen_test_hdlr_pars();
5426 f_MscConnHdlr_init_vty();
5427
5428 f_create_chan_and_exp();
5429 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005430
5431 /* Send CommonID */
5432 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5433
5434 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5435 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5436 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5437
5438 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005439
5440 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005441}
5442testcase TC_common_id() runs on test_CT {
5443 var MSC_ConnHdlr vc_conn;
5444 f_init(1, true);
5445 f_sleep(1.0);
5446 vc_conn := f_start_handler(refers(f_tc_common_id));
5447 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005448 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005449}
5450
Harald Weltee3bd6582018-01-31 22:51:25 +01005451private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005452 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005453 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005454 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005455
Harald Weltee3bd6582018-01-31 22:51:25 +01005456 /* send the single message we want to send */
5457 f_rsl_send_l3(l3);
5458}
5459
5460private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5461 timer T := sec;
5462 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005463 T.start;
5464 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005465 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5466 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005467 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005468 }
5469 [] T.timeout {
5470 setverdict(pass);
5471 }
5472 }
5473}
5474
Harald Weltee3bd6582018-01-31 22:51:25 +01005475/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5476private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5477 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5478 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005479 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005480}
Harald Welte898113b2018-01-31 18:32:21 +01005481testcase TC_unsol_ass_fail() runs on test_CT {
5482 var MSC_ConnHdlr vc_conn;
5483 f_init(1, true);
5484 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005485 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005486 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005487 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005488}
Harald Welte552620d2017-12-16 23:21:36 +01005489
Harald Welteea99a002018-01-31 20:46:43 +01005490
5491/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5492private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005493 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5494 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005495 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005496}
5497testcase TC_unsol_ass_compl() runs on test_CT {
5498 var MSC_ConnHdlr vc_conn;
5499 f_init(1, true);
5500 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005501 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005502 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005503 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005504}
5505
5506
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005507/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5508private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005509 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5510 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005511 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005512}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005513testcase TC_unsol_ho_fail() runs on test_CT {
5514 var MSC_ConnHdlr vc_conn;
5515 f_init(1, true);
5516 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005517 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005518 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005519 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005520}
5521
5522
Harald Weltee3bd6582018-01-31 22:51:25 +01005523/* short message from MS should be ignored */
5524private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005525 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005526 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005527 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005528
5529 /* send short message */
5530 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5531 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005532 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005533}
5534testcase TC_err_82_short_msg() runs on test_CT {
5535 var MSC_ConnHdlr vc_conn;
5536 f_init(1, true);
5537 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005538 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005539 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005540 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005541}
5542
5543
Harald Weltee9e02e42018-01-31 23:36:25 +01005544/* 24.008 8.4 Unknown message must trigger RR STATUS */
5545private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5546 f_est_single_l3(ts_RRM_UL_REL('00'O));
5547 timer T := 3.0
5548 alt {
5549 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5550 setverdict(pass);
5551 }
5552 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005553 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005554 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005555 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005556}
5557testcase TC_err_84_unknown_msg() runs on test_CT {
5558 var MSC_ConnHdlr vc_conn;
5559 f_init(1, true);
5560 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005561 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005562 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005563 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005564}
5565
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005566/***********************************************************************
5567 * Handover
5568 ***********************************************************************/
5569
Harald Welte94e0c342018-04-07 11:33:23 +02005570/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5571private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5572runs on test_CT {
5573 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5574 " timeslot "&int2str(ts_nr)&" ";
5575 f_vty_transceive(BSCVTY, cmd & suffix);
5576}
5577
Harald Welte261af4b2018-02-12 21:20:39 +01005578/* 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 +07005579private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5580 uint8_t bts_nr, uint8_t trx_nr,
5581 in RslChannelNr chan_nr)
5582{
Harald Welte261af4b2018-02-12 21:20:39 +01005583 /* FIXME: resolve those from component-global state */
5584 var integer ts_nr := chan_nr.tn;
5585 var integer ss_nr;
5586 if (ischosen(chan_nr.u.ch0)) {
5587 ss_nr := 0;
5588 } else if (ischosen(chan_nr.u.lm)) {
5589 ss_nr := chan_nr.u.lm.sub_chan;
5590 } else if (ischosen(chan_nr.u.sdcch4)) {
5591 ss_nr := chan_nr.u.sdcch4.sub_chan;
5592 } else if (ischosen(chan_nr.u.sdcch8)) {
5593 ss_nr := chan_nr.u.sdcch8.sub_chan;
5594 } else {
5595 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005596 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005597 }
5598
5599 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5600 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005601 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005602}
5603
Neels Hofmeyr91401012019-07-11 00:42:35 +02005604/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5605 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5606 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5607 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5608 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005609private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5610 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5611{
5612 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005613}
5614
5615/* intra-BSC hand-over between BTS0 and BTS1 */
5616private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005617 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5618 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005619
5620 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5621 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5622
Harald Weltea0630032018-03-20 21:09:55 +01005623 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005624 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005625
5626 var HandoverState hs := {
5627 rr_ho_cmpl_seen := false,
5628 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005629 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005630 expect_target_tsc := c_BtsParams[1].tsc
Harald Welte261af4b2018-02-12 21:20:39 +01005631 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005632 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005633 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005634 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5635 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005636
5637 /* From the MGW perspective, a handover is is characterized by
5638 * performing one MDCX operation with the MGW. So we expect to see
5639 * one more MDCX during handover. */
5640 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5641
Harald Welte261af4b2018-02-12 21:20:39 +01005642 alt {
5643 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005644 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005645
Philipp Maier4dae0652018-11-12 12:03:26 +01005646 /* Since this is an internal handover we expect the BSC to inform the
5647 * MSC about the event */
5648 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5649
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005650 /* Check the amount of MGCP transactions is still consistant with the
5651 * test expectation */
5652 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005653
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005654 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5655
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005656 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5657 * 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 +02005658 f_verify_encr_info(chan_act);
5659
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005660 f_chan_act_verify_tsc(chan_act, c_BtsParams[1].tsc);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005661
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005662 f_perform_clear(RSL1, RSL1_PROC);
5663
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005664 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005665}
5666
5667testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005668 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005669 var MSC_ConnHdlr vc_conn;
5670 f_init(2, true);
5671 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005672
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005673 pars.expect_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005674
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005675 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005676
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005677 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005678 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005679
5680 /* from f_establish_fully() */
5681 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5682 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5683 /* from handover */
5684 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5685 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5686 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5687 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005688 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5689 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005690 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005691 f_shutdown_helper(ho := true);
Harald Welte261af4b2018-02-12 21:20:39 +01005692}
Harald Weltee9e02e42018-01-31 23:36:25 +01005693
Oliver Smith7eabd312021-07-12 14:18:56 +02005694function 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 +02005695 var MSC_ConnHdlr vc_conn;
5696 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5697 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5698
5699 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005700 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005701 f_sleep(1.0);
5702
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005703 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005704
5705 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5706 vc_conn.done;
5707
5708 /* from f_establish_fully() */
5709 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5710 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5711 /* from handover */
5712 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5713 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5714 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5715 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005716 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5717 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005718 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005719 f_vty_encryption_a5_reset();
Oliver Smith39f53072022-10-27 14:44:04 +02005720 f_shutdown_helper(ho := true);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005721}
5722
5723testcase TC_ho_int_a5_0() runs on test_CT {
5724 f_tc_ho_int_a5('01'O);
5725}
5726
5727testcase TC_ho_int_a5_1() runs on test_CT {
5728 f_tc_ho_int_a5('02'O);
5729}
5730
5731testcase TC_ho_int_a5_3() runs on test_CT {
5732 f_tc_ho_int_a5('08'O);
5733}
5734
5735testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005736 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005737}
5738
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005739/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5740private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5741 g_pars := f_gen_test_hdlr_pars();
5742 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5743 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005744
5745 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5746 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5747
5748 f_establish_fully(ass_cmd, exp_compl);
5749 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5750
5751 var HandoverState hs := {
5752 rr_ho_cmpl_seen := false,
5753 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005754 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005755 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005756 };
5757 /* issue hand-over command on VTY */
5758 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5759 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5760 f_rslem_suspend(RSL1_PROC);
5761
5762 /* From the MGW perspective, a handover is is characterized by
5763 * performing one MDCX operation with the MGW. So we expect to see
5764 * one more MDCX during handover. */
5765 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5766
5767 var RSL_Message rsl;
5768 var PDU_ML3_NW_MS l3;
5769 var RslChannelNr new_chan_nr;
5770 var GsmArfcn arfcn;
5771 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5772 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5773 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5774 setverdict(fail, "Expected handoverCommand");
5775 mtc.stop;
5776 }
5777 }
5778 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5779 new_chan_nr, arfcn);
5780
5781 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5782
5783 /* resume processing of RSL DChan messages, which was temporarily suspended
5784 * before performing a hand-over */
5785 f_rslem_resume(RSL1_PROC);
5786 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5787
5788 f_sleep(1.0);
5789
5790 /* Handover fails because no HANDO DET appears on the new lchan,
5791 * and the old lchan reports a Radio Link Failure. */
5792 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5793
5794 var PDU_BSSAP rx_clear_request;
5795 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5796 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5797 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5798
5799 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5800
5801 var MgcpCommand mgcp;
5802 interleave {
5803 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5804 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005805 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005806 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005807 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005808 }
5809 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005810 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005811 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005812 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005813 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005814 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5815 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5816 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005817 }
5818
5819 f_sleep(0.5);
5820 setverdict(pass);
5821}
5822testcase TC_ho_int_radio_link_failure() runs on test_CT {
5823 var MSC_ConnHdlr vc_conn;
5824 f_init(2, true);
5825 f_sleep(1.0);
5826
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005827 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005828
5829 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5830 vc_conn.done;
5831
5832 /* from f_establish_fully() */
5833 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5834 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5835 /* from handover */
5836 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5837 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5838 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5839 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005840 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5841 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005842 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005843 f_shutdown_helper(ho := true);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005844}
5845
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005846/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005847private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005848 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005849 var template MgcpResponse mgcp_resp;
5850 var MGCP_RecvFrom mrf;
5851 var template MgcpMessage msg_resp;
5852 var template MgcpMessage msg_dlcx := {
5853 command := tr_DLCX()
5854 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005855
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005856 if (g_pars.aoip) {
5857 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005858 log("Got first DLCX: ", mgcp);
5859 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005860 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005861
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005862 MGCP.receive(tr_DLCX()) -> value mgcp {
5863 log("Got second DLCX: ", mgcp);
5864 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5865 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005866 } else {
5867 /* For SCCPLite, BSC doesn't handle the MSC-side */
5868 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5869 log("Got first DLCX: ", mrf.msg.command);
5870 msg_resp := {
5871 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5872 }
5873 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5874 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005875 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005876}
5877
Oliver Smithc9a5f532022-10-21 11:32:23 +02005878private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit,
5879 boolean skip_meas_rep := false) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005880
Oliver Smithc9a5f532022-10-21 11:32:23 +02005881 if (not skip_meas_rep) {
5882 var NcellReports neighbor_rep := {
5883 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5884 };
5885 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5886 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5887 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005888
Oliver Smithc9a5f532022-10-21 11:32:23 +02005889 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
5890 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005891
5892 f_sleep(0.5);
5893 /* The MSC negotiates Handover Request and Handover Request Ack with
5894 * the other BSS and comes back with a BSSMAP Handover Command
5895 * containing an RR Handover Command coming from the target BSS... */
5896
5897 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5898 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5899 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5900 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5901 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5902
5903 /* expect the Handover Command to go out on RR */
5904 var RSL_Message rsl_ho_cmd
5905 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5906 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5907 var RSL_IE_Body rsl_ho_cmd_l3;
5908 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5909 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5910 setverdict(fail);
5911 } else {
5912 log("Found L3 Info: ", rsl_ho_cmd_l3);
5913 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5914 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5915 setverdict(fail);
5916 } else {
5917 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5918 setverdict(pass);
5919 }
5920 }
5921
5922 /* When the other BSS has reported a completed handover, this side is
5923 * torn down. */
5924
5925 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5926 var BssmapCause cause := enum2int(cause_val);
5927 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5928
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005929 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005930
5931 interleave {
5932 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5933 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5934 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005935 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5936 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5937 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005938 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005939 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005940}
5941
5942private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5943 g_pars := f_gen_test_hdlr_pars();
5944 var PDU_BSSAP ass_req := f_gen_ass_req();
5945 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5946 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5947 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5948 f_establish_fully(ass_req, exp_compl);
5949
5950 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005951}
5952testcase TC_ho_out_of_this_bsc() runs on test_CT {
5953 var MSC_ConnHdlr vc_conn;
5954
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005955 f_init_vty();
5956 f_bts_0_cfg(BSCVTY,
5957 {"neighbor-list mode automatic",
5958 "handover 1",
5959 "handover algorithm 2",
5960 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005961 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005962 "neighbor lac 99 arfcn 123 bsic any"});
5963 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5964
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005965 f_init(1, true);
5966 f_sleep(1.0);
5967
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005968 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005969
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005970 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5971 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005972
5973 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5974 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5975 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5976 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5977 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5978 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5979 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02005980 f_shutdown_helper(ho := true);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005981}
5982
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005983private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5984 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005985 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005986 octetstring l3 := '0123456789'O)
5987runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005988 /* The old lchan and conn should still be active. See that arbitrary L3
5989 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005990 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005991 var template PDU_BSSAP exp_data := {
5992 discriminator := '1'B,
5993 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005994 dlci := dlci,
5995 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005996 pdu := {
5997 dtap := l3
5998 }
5999 };
6000 BSSAP.receive(exp_data);
6001 setverdict(pass);
6002}
6003
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006004private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
6005 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006006 template (value) OCT1 dlci := '00'O,
6007 octetstring l3 := '0123456789'O)
6008runs on MSC_ConnHdlr {
6009 BSSAP.send(PDU_BSSAP:{
6010 discriminator := '1'B,
6011 spare := '0000000'B,
6012 dlci := dlci,
6013 lengthIndicator := lengthof(l3),
6014 pdu := {
6015 dtap := l3
6016 }
6017 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00006018 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07006019 setverdict(pass);
6020}
6021
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006022/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
6023 * simply never sends a BSSMAP Handover Command. */
6024private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006025 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006026
6027 var PDU_BSSAP ass_req := f_gen_ass_req();
6028 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6029 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6030 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6031 f_establish_fully(ass_req, exp_compl);
6032
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006033 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006034 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6035
6036 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6037
6038 /* osmo-bsc should time out 10 seconds after the handover started.
6039 * Let's give it a bit extra. */
6040 f_sleep(15.0);
6041
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006042 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006043 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006044 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006045}
6046testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
6047 var MSC_ConnHdlr vc_conn;
6048
6049 f_init(1, true);
6050 f_sleep(1.0);
6051
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006052 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006053
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006054 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
6055 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006056
6057 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6058 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6059 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6060 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6061 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6062 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6063 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006064 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006065}
6066
6067/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
6068 * RR Handover Failure. */
6069private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006070 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006071
6072 var PDU_BSSAP ass_req := f_gen_ass_req();
6073 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6074 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6075 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6076 f_establish_fully(ass_req, exp_compl);
6077
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006078 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006079 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6080
6081 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6082
6083 f_sleep(0.5);
6084 /* The MSC negotiates Handover Request and Handover Request Ack with
6085 * the other BSS and comes back with a BSSMAP Handover Command
6086 * containing an RR Handover Command coming from the target BSS... */
6087
6088 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6089 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6090 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6091 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6092 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6093
6094 /* expect the Handover Command to go out on RR */
6095 var RSL_Message rsl_ho_cmd
6096 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6097 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6098 var RSL_IE_Body rsl_ho_cmd_l3;
6099 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6100 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6101 setverdict(fail);
6102 } else {
6103 log("Found L3 Info: ", rsl_ho_cmd_l3);
6104 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6105 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6106 setverdict(fail);
6107 } else {
6108 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6109 setverdict(pass);
6110 }
6111 }
6112
6113 f_sleep(0.2);
6114 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6115
6116 /* Should tell the MSC about the failure */
6117 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6118
6119 f_sleep(1.0);
6120
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07006121 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006122 f_sleep(1.0);
6123
6124 setverdict(pass);
6125 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006126 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006127}
6128testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
6129 var MSC_ConnHdlr vc_conn;
6130
6131 f_init(1, true);
6132 f_sleep(1.0);
6133
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006134 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006135
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006136 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
6137 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006138
6139 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6140 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6141 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6142 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6143 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6144 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
6145 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006146 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006147}
6148
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006149/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
6150 * (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 +02006151 * and the lchan is released. */
6152private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006153 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006154
6155 var PDU_BSSAP ass_req := f_gen_ass_req();
6156 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6157 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6158 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6159 f_establish_fully(ass_req, exp_compl);
6160
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006161 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006162 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6163
6164 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6165
6166 f_sleep(0.5);
6167 /* The MSC negotiates Handover Request and Handover Request Ack with
6168 * the other BSS and comes back with a BSSMAP Handover Command
6169 * containing an RR Handover Command coming from the target BSS... */
6170
6171 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6172 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6173 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6174 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6175 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6176
6177 /* expect the Handover Command to go out on RR */
6178 var RSL_Message rsl_ho_cmd
6179 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6180 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6181 var RSL_IE_Body rsl_ho_cmd_l3;
6182 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6183 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6184 setverdict(fail);
6185 } else {
6186 log("Found L3 Info: ", rsl_ho_cmd_l3);
6187 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6188 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6189 setverdict(fail);
6190 } else {
6191 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6192 setverdict(pass);
6193 }
6194 }
6195
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006196 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6197 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6198 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006199
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006200 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006201 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6202 log("Got BSSMAP Clear Request");
6203 /* Instruct BSC to clear channel */
6204 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6205 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6206
6207 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006208 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006209 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6210 log("Got Deact SACCH");
6211 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006212 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006213 log("Got RR Release");
6214 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006215 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006216 log("Got RF Chan Rel");
6217 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006218 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006219 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006220 }
6221
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006222 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006223 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006224 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006225
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006226 setverdict(pass);
6227 f_sleep(1.0);
6228}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006229testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006230 var MSC_ConnHdlr vc_conn;
6231
6232 f_init(1, true);
6233 f_sleep(1.0);
6234
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006235 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006236
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006237 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006238 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006239
6240 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6241 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6242 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6243 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6244 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6245 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6246 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006247 f_shutdown_helper(ho := true);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006248}
6249
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006250private 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 +01006251 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006252 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6253 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6254 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6255 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6256 * before we get started. */
6257 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6258 f_rslem_register(0, new_chan_nr);
6259 g_chan_nr := new_chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06006260 var uint3_t expect_target_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006261 f_sleep(1.0);
6262
6263 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6264 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006265 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006266
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006267 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6268 cell_id_source := g_pars.cell_id_source,
6269 oldToNewBSSIEs := oldToNewBSSIEs,
6270 enc := g_pars.encr);
6271 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6272 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6273 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6274 } else {
6275 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6276 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6277 BSSAP.send(ho_req);
6278 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006279
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006280 alt {
6281 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6282 if (g_pars.expect_ho_fail) {
6283 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6284 "Expected Handover Request to fail, but got Handover Request Ack")
6285 }
6286 }
6287 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6288 if (not g_pars.expect_ho_fail) {
6289 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6290 "Expected Handover Request to succeed, but got Handover Failure")
6291 }
6292 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6293 // For now just accept any cause.
6294 BSSAP.receive(tr_BSSMAP_ClearRequest);
6295 setverdict(pass);
6296 return;
6297 }
6298 }
6299
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006300 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6301
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006302 /* we're sure that the channel activation is done now, verify the parameters in it */
6303 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6304 f_verify_encr_info(chan_act);
6305 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006306
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006307 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6308 if (not g_pars.aoip) {
6309 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6310 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6311 }
6312 /* TODO: check actual codecs? */
6313 } else {
6314 if (g_pars.aoip) {
6315 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6316 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6317 }
6318 }
6319
6320 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6321 if (not g_pars.aoip) {
6322 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6323 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6324 }
6325 /* TODO: check actual codec? */
6326 } else {
6327 if (g_pars.aoip) {
6328 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6329 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6330 }
6331 }
6332
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006333 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006334 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6335 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6336 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6337 log("L3 Info in HO Request Ack is ", ho_command);
6338
6339 var GsmArfcn arfcn;
6340 var RslChannelNr actual_new_chan_nr;
6341 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6342 actual_new_chan_nr, arfcn);
6343
6344 if (actual_new_chan_nr != new_chan_nr) {
6345 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6346 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6347 setverdict(fail);
6348 return;
6349 }
6350 log("Handover Command chan_nr is", actual_new_chan_nr);
6351
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006352 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6353 if (not match(got_tsc, expect_target_tsc)) {
6354 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6355 expect_target_tsc, " got ", got_tsc);
6356 mtc.stop;
6357 } else {
6358 log("handoverCommand: verified TSC = ", got_tsc);
6359 }
6360
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006361 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6362 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6363 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6364 var template (present) CipherModeSetting_TV tr_cms := {
6365 sC := '0'B, /* no ciphering by default */
6366 algorithmIdentifier := '000'B,
6367 elementIdentifier := ?
6368 };
6369 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6370 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6371 tr_cms.sC := '1'B;
6372 }
6373 if (not match(cms, tr_cms)) {
6374 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6375 cms, ", expected: ", tr_cms);
6376 }
6377 } else {
6378 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6379 }
6380
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006381 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6382 * tells the MS to handover to the new lchan. Here comes the new MS on
6383 * the new lchan with a Handover RACH: */
6384
6385 /* send handover detect */
6386
6387 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6388
6389 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6390
6391 /* send handover complete over the new channel */
6392
6393 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6394 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6395 enc_PDU_ML3_MS_NW(l3_tx)));
6396
6397 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006398 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006399 setverdict(pass);
6400}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006401
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006402private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006403 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006404 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6405 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6406 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006407 }
6408 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006409 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006410 } else {
6411 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006412 }
6413 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006414 if (g_pars.expect_ho_fail) {
6415 f_perform_clear_no_lchan();
6416 } else {
6417 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6418 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006419 setverdict(pass);
6420}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006421function 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 +01006422 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006423
6424 f_init(1, true);
6425 f_sleep(1.0);
6426
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006427 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006428 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006429
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006430 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6431 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006432
6433 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6434 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006435
6436 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006437 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006438 if (pars.expect_ho_fail) {
6439 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6440 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6441 } else {
6442 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6443 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6444 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006445 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006446
6447 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006448}
6449
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006450testcase TC_ho_into_this_bsc() runs on test_CT {
6451 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6452 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006453 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006454}
6455
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006456function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6457 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006458 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006459 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006460 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006461 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Oliver Smith39f53072022-10-27 14:44:04 +02006462 f_shutdown_helper(ho := true);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006463}
6464
6465testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006466 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006467}
6468
6469testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006470 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006471}
6472
6473testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006474 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006475}
6476
6477testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006478 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006479}
6480
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006481/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6482 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6483 *
6484 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6485 * omitted.
6486 *
6487 * Related: SYS#5839
6488 */
6489testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6490 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6491}
6492
6493testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6494 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6495}
6496
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006497/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6498testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6499 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6500 expect_fail := true); // 0x18 = A5/3 and A5/4
6501}
6502
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006503testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6504 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6505 pars.host_aoip_tla := "::6";
6506 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006507 f_shutdown_helper(ho := true);
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006508}
6509
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006510/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006511 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006512 channel is later released (RR CHannel Release), should trigger inclusion of
6513 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6514 neighbors. */
6515testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6516 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6517 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006518 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006519 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006520
6521 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6522 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6523 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006524 f_shutdown_helper(ho := true);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006525}
6526
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006527/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6528testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6529 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6530 pars.encr := f_encr_params('08'O); /* only A5/3 */
6531 pars.last_used_eutran_plmn := '323454'O;
6532 pars.exp_fast_return := true;
6533 f_tc_ho_into_this_bsc_main(pars);
6534
6535 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6536 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6537 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006538 f_shutdown_helper(ho := true);
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006539}
6540
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006541/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6542 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6543 list when the channel is released. */
6544testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6545 f_init_vty();
6546 f_vty_allow_srvcc_fast_return(true, 0)
6547
6548 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6549 pars.last_used_eutran_plmn := '323454'O;
6550 pars.exp_fast_return := false;
6551 f_tc_ho_into_this_bsc_main(pars);
6552 f_vty_allow_srvcc_fast_return(false, 0);
6553 f_shutdown_helper();
6554}
6555
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006556/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6557testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6558 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6559 pars.last_used_eutran_plmn := '323454'O;
6560 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6561 f_tc_ho_into_this_bsc_main(pars);
6562
6563 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6564 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6565 f_ctrs_bsc_and_bts_verify();
6566 f_shutdown_helper();
6567}
6568
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006569private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6570 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6571 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6572 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6573 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6574 setverdict(pass);
6575}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006576
6577private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6578 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006579 var MSC_ConnHdlr vc_conn;
6580 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6581
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006582 f_init_vty();
6583 f_bts_0_cfg(BSCVTY,
6584 {"neighbor-list mode automatic",
6585 "handover 1",
6586 "handover algorithm 2",
6587 "handover2 window rxlev averaging 1",
6588 "no neighbors",
6589 "neighbor lac 99 arfcn 123 bsic any"});
6590 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6591
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006592 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006593 if (disable_fast_return) {
6594 f_vty_allow_srvcc_fast_return(true, 0);
6595 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006596 f_sleep(1.0);
6597
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006598 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006599
6600 pars.last_used_eutran_plmn := '323454'O;
6601 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6602 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6603
6604 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6605 vc_conn.done;
6606
6607 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6608 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6609 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6610 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6611 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6612 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006613
6614 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6615 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006616 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006617
6618 if (disable_fast_return) {
6619 f_vty_allow_srvcc_fast_return(false, 0);
6620 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006621 f_shutdown_helper();
6622}
6623
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006624/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6625 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6626 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6627 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6628testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6629 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6630}
6631/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6632 * independently of fast-reture allowed/forbidden in local BTS */
6633testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6634 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6635}
6636
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006637private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6638 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6639 f_rslem_register(0, new_chan_nr);
6640 g_chan_nr := new_chan_nr;
6641 f_sleep(1.0);
6642
6643 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6644 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6645 activate(as_Media());
6646
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006647 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006648 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006649 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006650
6651 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6652
6653 var PDU_BSSAP rx_bssap;
6654 var octetstring ho_command_str;
6655
6656 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6657
6658 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6659 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6660 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6661 log("L3 Info in HO Request Ack is ", ho_command);
6662
6663 var GsmArfcn arfcn;
6664 var RslChannelNr actual_new_chan_nr;
6665 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6666 actual_new_chan_nr, arfcn);
6667
6668 if (actual_new_chan_nr != new_chan_nr) {
6669 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6670 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6671 setverdict(fail);
6672 return;
6673 }
6674 log("Handover Command chan_nr is", actual_new_chan_nr);
6675
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006676 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6677 f_sleep(1.0);
6678
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006679 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6680 * tells the MS to handover to the new lchan. In this case, the MS
6681 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6682 * Handover Failure to the MSC. The procedure according to 3GPP TS
6683 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6684 * BSSMAP Clear Command: */
6685
6686 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6687 var BssmapCause cause := enum2int(cause_val);
6688 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6689
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006690 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006691 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006692 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006693
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006694 setverdict(pass);
6695 f_sleep(1.0);
6696
6697 setverdict(pass);
6698}
6699testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6700 var MSC_ConnHdlr vc_conn;
6701 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6702
6703 f_init(1, true);
6704 f_sleep(1.0);
6705
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006706 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006707
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006708 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6709 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006710
6711 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6712 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006713
6714 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6715 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6716 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6717 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6718 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006719 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006720}
6721
6722private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6723 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6724 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6725 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6726 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6727 * before we get started. */
6728 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6729 f_rslem_register(0, new_chan_nr);
6730 g_chan_nr := new_chan_nr;
6731 f_sleep(1.0);
6732
6733 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6734 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6735 activate(as_Media());
6736
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006737 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006738 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006739 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006740
6741 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6742
6743 var PDU_BSSAP rx_bssap;
6744 var octetstring ho_command_str;
6745
6746 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6747
6748 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6749 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6750 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6751 log("L3 Info in HO Request Ack is ", ho_command);
6752
6753 var GsmArfcn arfcn;
6754 var RslChannelNr actual_new_chan_nr;
6755 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6756 actual_new_chan_nr, arfcn);
6757
6758 if (actual_new_chan_nr != new_chan_nr) {
6759 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6760 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6761 setverdict(fail);
6762 return;
6763 }
6764 log("Handover Command chan_nr is", actual_new_chan_nr);
6765
6766 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6767 * tells the MS to handover to the new lchan. Here comes the new MS on
6768 * the new lchan with a Handover RACH: */
6769
6770 /* send handover detect */
6771
6772 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6773
6774 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6775
6776 /* The MSC chooses to clear the connection now, maybe we got the
6777 * Handover RACH on the new cell but the MS still signaled Handover
6778 * Failure to the old BSS? */
6779
6780 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6781 var BssmapCause cause := enum2int(cause_val);
6782 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6783
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006784 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006785 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006786 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006787
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006788 f_sleep(1.0);
6789}
6790testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6791 var MSC_ConnHdlr vc_conn;
6792 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6793
6794 f_init(1, true);
6795 f_sleep(1.0);
6796
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006797 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006798
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006799 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6800 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006801
6802 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6803 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006804
6805 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6806 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6807 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6808 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6809 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006810 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006811}
6812
6813/* The new BSS's lchan times out before the MSC decides that handover failed. */
6814private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6815 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6816 f_rslem_register(0, new_chan_nr);
6817 g_chan_nr := new_chan_nr;
6818 f_sleep(1.0);
6819
6820 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6821 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006822 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006823
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006824 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006825 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006826 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006827
6828 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6829
6830 var PDU_BSSAP rx_bssap;
6831 var octetstring ho_command_str;
6832
6833 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6834
6835 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6836 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6837 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6838 log("L3 Info in HO Request Ack is ", ho_command);
6839
6840 var GsmArfcn arfcn;
6841 var RslChannelNr actual_new_chan_nr;
6842 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6843 actual_new_chan_nr, arfcn);
6844
6845 if (actual_new_chan_nr != new_chan_nr) {
6846 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6847 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6848 setverdict(fail);
6849 return;
6850 }
6851 log("Handover Command chan_nr is", actual_new_chan_nr);
6852
6853 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6854 * tells the MS to handover to the new lchan. But the MS never shows up
6855 * on the new lchan. */
6856
6857 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6858
6859 /* Did osmo-bsc also send a Clear Request? */
6860 timer T := 0.5;
6861 T.start;
6862 alt {
6863 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6864 [] T.timeout { }
6865 }
6866
6867 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6868 * asked for it, this is a Handover Failure after all). */
6869
6870 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6871 var BssmapCause cause := enum2int(cause_val);
6872 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6873
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006874 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006875 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006876 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006877
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006878 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006879}
6880testcase TC_ho_in_fail_no_detect() runs on test_CT {
6881 var MSC_ConnHdlr vc_conn;
6882 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6883
6884 f_init(1, true);
6885 f_sleep(1.0);
6886
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006887 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006888
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006889 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6890 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006891
6892 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6893 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006894
6895 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6896 f_ctrs_bsc_and_bts_add(0, "handover:error");
6897 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6898 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6899 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006900 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006901}
6902
6903/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6904private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6905 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6906 f_rslem_register(0, new_chan_nr);
6907 g_chan_nr := new_chan_nr;
6908 f_sleep(1.0);
6909
6910 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6911 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006912 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006913
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006914 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006915 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006916 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006917
6918 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6919
6920 var PDU_BSSAP rx_bssap;
6921 var octetstring ho_command_str;
6922
6923 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6924
6925 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6926 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6927 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6928 log("L3 Info in HO Request Ack is ", ho_command);
6929
6930 var GsmArfcn arfcn;
6931 var RslChannelNr actual_new_chan_nr;
6932 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6933 actual_new_chan_nr, arfcn);
6934
6935 if (actual_new_chan_nr != new_chan_nr) {
6936 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6937 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6938 setverdict(fail);
6939 return;
6940 }
6941 log("Handover Command chan_nr is", actual_new_chan_nr);
6942
6943 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6944 * tells the MS to handover to the new lchan. But the MS never shows up
6945 * on the new lchan. */
6946
6947 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6948
6949 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006950 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006951
6952 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006953 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6954 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6955 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006956 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006957 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006958 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006959
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006960 f_sleep(1.0);
6961}
6962testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6963 var MSC_ConnHdlr vc_conn;
6964 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6965
6966 f_init(1, true);
6967 f_sleep(1.0);
6968
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006969 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006970
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006971 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6972 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006973
6974 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6975 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006976
6977 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6978 f_ctrs_bsc_and_bts_add(0, "handover:error");
6979 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6980 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6981 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02006982 f_shutdown_helper(ho := true);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006983}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006984
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006985/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6986 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6987 * empty N-Connect case. */
6988testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6989 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6990 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6991 f_tc_ho_into_this_bsc_main(pars);
Oliver Smith39f53072022-10-27 14:44:04 +02006992 f_shutdown_helper(ho := true);
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006993}
6994
Neels Hofmeyr91401012019-07-11 00:42:35 +02006995type record of charstring Commands;
6996
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006997private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006998{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006999 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007000 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007001 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007002 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007003 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02007004}
7005
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01007006private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
7007{
7008 f_vty_enter_cfg_cs7_inst(pt, 0);
7009 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
7010 f_vty_transceive(pt, cmds[i]);
7011 }
7012 f_vty_transceive(pt, "end");
7013}
7014
Neels Hofmeyr91401012019-07-11 00:42:35 +02007015private function f_probe_for_handover(charstring log_label,
7016 charstring log_descr,
7017 charstring handover_vty_cmd,
7018 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007019 boolean is_inter_bsc_handover := false,
7020 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02007021runs on MSC_ConnHdlr
7022{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02007023 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
7024 * lchans to be established on bts 1 or bts 2. */
7025 f_rslem_suspend(RSL1_PROC);
7026 f_rslem_suspend(RSL2_PROC);
7027
Neels Hofmeyr91401012019-07-11 00:42:35 +02007028 var RSL_Message rsl;
7029
7030 var charstring log_msg := " (expecting handover)"
7031 if (not expect_handover) {
7032 log_msg := " (expecting NO handover)";
7033 }
7034 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
7035 f_vty_transceive(BSCVTY, handover_vty_cmd);
7036
Neels Hofmeyr91401012019-07-11 00:42:35 +02007037 timer T := 2.0;
7038 T.start;
7039
7040 alt {
7041 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
7042 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
7043 log("Rx L3 from net: ", l3);
7044 if (ischosen(l3.msgs.rrm.handoverCommand)) {
7045 var RslChannelNr new_chan_nr;
7046 var GsmArfcn arfcn;
7047 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
7048 new_chan_nr, arfcn);
7049 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
7050 log(l3.msgs.rrm.handoverCommand);
7051
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007052 /* Verify correct TSC in handoverCommand */
7053 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
7054 if (not match(got_tsc, expect_target_tsc)) {
7055 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
7056 expect_target_tsc, " got ", got_tsc);
7057 mtc.stop;
7058 } else {
7059 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
7060 expect_target_tsc, ")");
7061 }
7062
Neels Hofmeyr91401012019-07-11 00:42:35 +02007063 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
7064 * matter on which BTS it really is, we're not going to follow through an entire handover
7065 * anyway. */
7066 f_rslem_register(0, new_chan_nr, RSL1_PROC);
7067 f_rslem_resume(RSL1_PROC);
7068 f_rslem_register(0, new_chan_nr, RSL2_PROC);
7069 f_rslem_resume(RSL2_PROC);
7070
7071 if (expect_handover and not is_inter_bsc_handover) {
7072 setverdict(pass);
7073 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
7074 } else {
7075 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
7076 & log_label & ": " & log_descr);
7077 }
7078
7079 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
7080 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
7081 * Handover Failure. */
7082 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
7083
7084 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
7085 f_sleep(0.5);
7086 RSL1.clear;
7087 RSL2.clear;
7088 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
7089 break;
7090 } else {
7091 repeat;
7092 }
7093 }
7094 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
7095 if (expect_handover and is_inter_bsc_handover) {
7096 setverdict(pass);
7097 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
7098 } else {
7099 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
7100 & log_label & ": " & log_descr);
7101 }
7102
7103 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
7104
7105 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
7106 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
7107 * setting a short timeout and waiting is the only way. */
7108 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
7109 f_sleep(1.5);
7110 log("f_probe_for_handover(" & log_label & "): ...done");
7111
7112 break;
7113 }
7114 [] T.timeout {
7115 if (expect_handover) {
7116 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
7117 & log_label & ": " & log_descr);
7118 } else {
7119 setverdict(pass);
7120 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
7121 }
7122 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
7123 break;
7124 }
7125 }
7126
7127 f_rslem_resume(RSL1_PROC);
7128 f_rslem_resume(RSL2_PROC);
7129 f_sleep(3.0);
7130 RSL.clear;
7131
7132 log("f_probe_for_handover(" & log_label & "): done clearing");
7133}
7134
7135/* Test the effect of various neighbor configuration scenarios:
7136 *
7137 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
7138 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
7139 */
7140private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
7141 g_pars := f_gen_test_hdlr_pars();
7142 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
7143 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007144
7145 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
7146 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
7147
7148 /* Establish lchan at bts 0 */
7149 f_establish_fully(ass_cmd, exp_compl);
7150
7151 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
7152 f_vty_enter_cfg_network(BSCVTY);
7153 f_vty_transceive(BSCVTY, "timer T7 1");
7154 f_vty_transceive(BSCVTY, "end");
7155}
7156
7157private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
7158 f_tc_ho_neighbor_config_start();
7159
7160 /*
7161 * bts 0 ARFCN 871 BSIC 10
7162 * bts 1 ARFCN 871 BSIC 11
7163 * bts 2 ARFCN 871 BSIC 12
7164 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7165 */
7166
7167 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007168 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007169 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
7170 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007171 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007172
7173 f_probe_for_handover("1.b", "HO to unknown cell does not start",
7174 "handover any to arfcn 13 bsic 39",
7175 false);
7176
7177 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
7178 "handover any to arfcn 871 bsic 12",
7179 false);
7180
7181 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
7182 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007183 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007184
7185 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007186}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007187testcase TC_ho_neighbor_config_1() runs on test_CT {
7188 var MSC_ConnHdlr vc_conn;
7189 f_init(3, true, guard_timeout := 60.0);
7190 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007191 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007192 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7193 vc_conn.done;
7194
7195 /* f_tc_ho_neighbor_config_start() */
7196 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7197 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7198
7199 /* 1.a */
7200 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7201 * handover quickly by sending a Handover Failure message. */
7202 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7203 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7204 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7205 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007206 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7207 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007208
7209 /* 1.b */
7210 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7211 f_ctrs_bsc_and_bts_add(0, "handover:error");
7212
7213 /* 1.c */
7214 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7215 f_ctrs_bsc_and_bts_add(0, "handover:error");
7216
7217 /* 1.d */
7218 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7219 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7220 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7221 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007222 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7223 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007224
7225 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007226 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007227}
7228
Neels Hofmeyr91401012019-07-11 00:42:35 +02007229private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7230 f_tc_ho_neighbor_config_start();
7231
7232 /*
7233 * bts 0 ARFCN 871 BSIC 10
7234 * bts 1 ARFCN 871 BSIC 11
7235 * bts 2 ARFCN 871 BSIC 12
7236 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7237 */
7238
7239 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007240 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007241 f_sleep(0.5);
7242
7243 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7244 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007245 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007246
7247 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7248 "handover any to arfcn 871 bsic 12",
7249 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007250 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007251}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007252testcase TC_ho_neighbor_config_2() runs on test_CT {
7253 var MSC_ConnHdlr vc_conn;
7254 f_init(3, true, guard_timeout := 50.0);
7255 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007256 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007257 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7258 vc_conn.done;
7259
7260 /* f_tc_ho_neighbor_config_start() */
7261 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7262 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7263
7264 /* 2.a */
7265 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7266 * handover quickly by sending a Handover Failure message. */
7267 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7268 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7269 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7270 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007271 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7272 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007273
7274 /* 2.b */
7275 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7276 f_ctrs_bsc_and_bts_add(0, "handover:error");
7277
7278 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007279 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007280}
7281
Neels Hofmeyr91401012019-07-11 00:42:35 +02007282private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7283 f_tc_ho_neighbor_config_start();
7284
7285 /*
7286 * bts 0 ARFCN 871 BSIC 10
7287 * bts 1 ARFCN 871 BSIC 11
7288 * bts 2 ARFCN 871 BSIC 12
7289 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7290 */
7291
7292 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007293 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007294 f_sleep(0.5);
7295
7296 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7297 "handover any to arfcn 871 bsic 11",
7298 false);
7299 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",
7300 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007301 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007302 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007303}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007304testcase TC_ho_neighbor_config_3() runs on test_CT {
7305 var MSC_ConnHdlr vc_conn;
7306 f_init(3, true, guard_timeout := 50.0);
7307 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007308 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007309 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7310 vc_conn.done;
7311
7312 /* f_tc_ho_neighbor_config_start() */
7313 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7314 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7315
7316 /* 3.a */
7317 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7318 f_ctrs_bsc_and_bts_add(0, "handover:error");
7319
7320 /* 3.b */
7321 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7322 * handover quickly by sending a Handover Failure message. */
7323 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7324 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7325 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7326 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007327 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7328 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007329
7330 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007331 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007332}
7333
Neels Hofmeyr91401012019-07-11 00:42:35 +02007334private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7335 f_tc_ho_neighbor_config_start();
7336
7337 /*
7338 * bts 0 ARFCN 871 BSIC 10
7339 * bts 1 ARFCN 871 BSIC 11
7340 * bts 2 ARFCN 871 BSIC 12
7341 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7342 */
7343
7344 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007345 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007346 f_sleep(0.5);
7347
7348 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7349 "handover any to arfcn 871 bsic 11",
7350 false);
7351 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7352 "handover any to arfcn 871 bsic 12",
7353 false);
7354 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7355 "handover any to arfcn 123 bsic 45",
7356 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007357 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007358}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007359testcase TC_ho_neighbor_config_4() runs on test_CT {
7360 var MSC_ConnHdlr vc_conn;
7361 f_init(3, true, guard_timeout := 50.0);
7362 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007363 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007364 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7365 vc_conn.done;
7366
7367 /* f_tc_ho_neighbor_config_start() */
7368 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7369 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7370
7371 /* 4.a */
7372 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7373 f_ctrs_bsc_and_bts_add(0, "handover:error");
7374
7375 /* 4.b */
7376 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7377 f_ctrs_bsc_and_bts_add(0, "handover:error");
7378
7379 /* 4.c */
7380 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7381 * handover quickly by timing out after the Handover Required message */
7382 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7383 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7384 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7385 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7386
7387 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007388 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007389}
7390
Neels Hofmeyr91401012019-07-11 00:42:35 +02007391private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7392 f_tc_ho_neighbor_config_start();
7393
7394 /*
7395 * bts 0 ARFCN 871 BSIC 10
7396 * bts 1 ARFCN 871 BSIC 11
7397 * bts 2 ARFCN 871 BSIC 12
7398 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7399 */
7400
7401 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 +02007402 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007403 f_sleep(0.5);
7404
7405 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7406 "handover any to arfcn 871 bsic 12",
7407 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007408 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007409}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007410testcase TC_ho_neighbor_config_5() runs on test_CT {
7411 var MSC_ConnHdlr vc_conn;
7412 f_init(3, true);
7413 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007414 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007415 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7416 vc_conn.done;
7417
7418 /* f_tc_ho_neighbor_config_start() */
7419 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7420 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7421
7422 /* 5 */
7423 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7424 * handover quickly by timing out after the Handover Required message */
7425 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7426 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7427 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7428 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7429
7430 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007431 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007432}
7433
Neels Hofmeyr91401012019-07-11 00:42:35 +02007434private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7435 f_tc_ho_neighbor_config_start();
7436
7437 /*
7438 * bts 0 ARFCN 871 BSIC 10
7439 * bts 1 ARFCN 871 BSIC 11
7440 * bts 2 ARFCN 871 BSIC 12
7441 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7442 */
7443
7444 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7445 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007446 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007447 f_sleep(0.5);
7448
7449 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7450 "handover any to arfcn 871 bsic 12",
7451 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007452 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007453}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007454testcase TC_ho_neighbor_config_6() runs on test_CT {
7455 var MSC_ConnHdlr vc_conn;
7456 f_init(3, true);
7457 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007458 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007459 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7460 vc_conn.done;
7461
7462 /* f_tc_ho_neighbor_config_start() */
7463 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7464 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7465
7466 /* 6.a */
7467 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7468 * handover quickly by timing out after the Handover Required message */
7469 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7470 f_ctrs_bsc_and_bts_add(0, "handover:error");
7471
7472 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007473 f_shutdown_helper(ho := true);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007474}
7475
Neels Hofmeyr91401012019-07-11 00:42:35 +02007476private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7477 f_tc_ho_neighbor_config_start();
7478
7479 /*
7480 * bts 0 ARFCN 871 BSIC 10
7481 * bts 1 ARFCN 871 BSIC 11
7482 * bts 2 ARFCN 871 BSIC 12
7483 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7484 */
7485
7486 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7487 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007488 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007489 f_sleep(0.5);
7490
7491 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7492 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007493 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007494 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7495 "handover any to arfcn 123 bsic 45",
7496 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007497 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007498}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007499testcase TC_ho_neighbor_config_7() runs on test_CT {
7500 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007501 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007502 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007503 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007504 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7505 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007506
7507 /* f_tc_ho_neighbor_config_start() */
7508 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7509 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7510
7511 /* 7.a */
7512 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7513 * handover quickly by sending a Handover Failure message. */
7514 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7515 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7516 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7517 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007518 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7519 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007520
7521 /* 7.b */
7522 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7523 * handover quickly by timing out after the Handover Required message */
7524 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7525 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7526 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7527 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7528
7529 f_ctrs_bsc_and_bts_verify();
Oliver Smith39f53072022-10-27 14:44:04 +02007530 f_shutdown_helper(ho := true);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007531}
7532
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007533/* OS#3041: Open and close N connections in a normal fashion, and expect no
7534 * BSSMAP Reset just because of that. */
7535testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7536 var default d;
7537 var integer i;
7538 var DchanTuple dt;
7539
7540 f_init();
7541
7542 /* Wait for initial BSSMAP Reset to pass */
7543 f_sleep(4.0);
7544
7545 d := activate(no_bssmap_reset());
7546
7547 /* Setup up a number of connections and RLSD them again from the MSC
7548 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7549 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007550 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007551 /* Since we're doing a lot of runs, give each one a fresh
7552 * T_guard from the top. */
7553 T_guard.start;
7554
7555 /* Setup a BSSAP connection and clear it right away. This is
7556 * the MSC telling the BSC about a planned release, it's not an
7557 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007558 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007559
7560 /* MSC disconnects (RLSD). */
7561 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7562 }
7563
7564 /* In the buggy behavior, a timeout of 2 seconds happens between above
7565 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7566 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7567 f_sleep(4.0);
7568
7569 deactivate(d);
7570 f_shutdown_helper();
7571}
Harald Welte552620d2017-12-16 23:21:36 +01007572
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007573/* OS#3041: Open and close N connections in a normal fashion, and expect no
7574 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7575 * the MSC. */
7576testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7577 var default d;
7578 var integer i;
7579 var DchanTuple dt;
7580 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007581 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7582 var BssmapCause cause := enum2int(cause_val);
7583
7584 f_init();
7585
7586 /* Wait for initial BSSMAP Reset to pass */
7587 f_sleep(4.0);
7588
7589 d := activate(no_bssmap_reset());
7590
7591 /* Setup up a number of connections and RLSD them again from the MSC
7592 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7593 * Let's do it some more times for good measure. */
7594 for (i := 0; i < 8; i := i+1) {
7595 /* Since we're doing a lot of runs, give each one a fresh
7596 * T_guard from the top. */
7597 T_guard.start;
7598
7599 /* Setup a BSSAP connection and clear it right away. This is
7600 * the MSC telling the BSC about a planned release, it's not an
7601 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007602 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007603
7604 /* Instruct BSC to clear channel */
7605 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7606
7607 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007608 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007609 }
7610
7611 /* In the buggy behavior, a timeout of 2 seconds happens between above
7612 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7613 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7614 f_sleep(4.0);
7615
7616 deactivate(d);
7617 f_shutdown_helper();
7618}
7619
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007620/* OS#3041: Open and close N connections in a normal fashion, and expect no
7621 * BSSMAP Reset just because of that. Close connections from the MS side with a
7622 * Release Ind on RSL. */
7623testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7624 var default d;
7625 var integer i;
7626 var DchanTuple dt;
7627 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007628 var integer j;
7629
7630 f_init();
7631
7632 /* Wait for initial BSSMAP Reset to pass */
7633 f_sleep(4.0);
7634
7635 d := activate(no_bssmap_reset());
7636
7637 /* Setup up a number of connections and RLSD them again from the MSC
7638 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7639 * Let's do it some more times for good measure. */
7640 for (i := 0; i < 8; i := i+1) {
7641 /* Since we're doing a lot of runs, give each one a fresh
7642 * T_guard from the top. */
7643 T_guard.start;
7644
7645 /* Setup a BSSAP connection and clear it right away. This is
7646 * the MSC telling the BSC about a planned release, it's not an
7647 * erratic loss of a connection. */
7648 dt := f_est_dchan('23'O, 23, '00010203040506'O);
7649
7650 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007651 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007652
7653 /* expect Clear Request on MSC side */
7654 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7655
7656 /* Instruct BSC to clear channel */
7657 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7658 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7659
7660 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007661 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007662 }
7663
7664 /* In the buggy behavior, a timeout of 2 seconds happens between above
7665 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7666 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7667 f_sleep(4.0);
7668
7669 deactivate(d);
7670 f_shutdown_helper();
7671}
7672
Harald Welte94e0c342018-04-07 11:33:23 +02007673/***********************************************************************
7674 * IPA style dynamic PDCH
7675 ***********************************************************************/
7676
7677private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7678 template (omit) RSL_Cause nack := omit)
7679runs on test_CT {
7680 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7681 var RSL_Message rsl_unused;
7682 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7683 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7684 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007685 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007686 if (istemplatekind(nack, "omit")) {
7687 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007688 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007689 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007690 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007691 }
7692}
7693
7694private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7695 template (omit) RSL_Cause nack := omit)
7696runs on test_CT {
7697 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7698 var RSL_Message rsl_unused;
7699 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7700 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7701 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007702 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_DEACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007703 if (istemplatekind(nack, "omit")) {
7704 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007705 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007706 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007707 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007708 }
7709}
7710
7711private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7712runs on test_CT return charstring {
7713 var charstring cmd, resp;
7714 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007715 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007716}
7717
7718private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7719 template charstring exp)
7720runs on test_CT {
7721 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7722 if (not match(mode, exp)) {
7723 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007724 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007725 }
7726}
7727
7728private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7729runs on test_CT {
7730 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7731 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7732 f_vty_transceive(BSCVTY, "end");
7733}
7734
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007735
7736private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7737 var integer i;
7738 for (i := 0; i < 8; i := i + 1) {
7739 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7740 }
7741}
7742
Harald Welte94e0c342018-04-07 11:33:23 +02007743private const charstring TCHF_MODE := "TCH/F mode";
7744private const charstring TCHH_MODE := "TCH/H mode";
7745private const charstring PDCH_MODE := "PDCH mode";
7746private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007747private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007748
7749/* Test IPA PDCH activation / deactivation triggered by VTY */
7750testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7751 var RSL_Message rsl_unused;
7752
7753 /* change Timeslot 6 before f_init() starts RSL */
7754 f_init_vty();
7755 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7756 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7757
7758 f_init(1, false);
7759 f_sleep(1.0);
7760
7761 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7762
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007763 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007764 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7765 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007766 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7767 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007768 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007769 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007770 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7771
7772 /* De-activate it via VTY */
7773 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7774 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007775 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007776 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7777
7778 /* re-activate it via VTY */
7779 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7780 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007781 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007782 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7783
7784 /* and finally de-activate it again */
7785 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7786 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007787 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007788 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7789
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007790 /* clean up config */
7791 f_ts_set_chcomb(0, 0, 6, "PDCH");
7792
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007793 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007794}
7795
7796/* Test IPA PDCH activation NACK */
7797testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7798 var RSL_Message rsl_unused;
7799
7800 /* change Timeslot 6 before f_init() starts RSL */
7801 f_init_vty();
7802 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7803 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7804
7805 f_init(1, false);
7806 f_sleep(1.0);
7807
7808 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7809
7810 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7811 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007812 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7813 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007814 f_sleep(1.0);
7815 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7816
7817 /* De-activate it via VTY */
7818 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7819 f_sleep(1.0);
7820 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7821
7822 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7823 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7824 f_sleep(1.0);
7825 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7826
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007827 /* clean up config */
7828 f_ts_set_chcomb(0, 0, 6, "PDCH");
7829
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007830 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007831}
7832
7833
7834/***********************************************************************
7835 * Osmocom style dynamic PDCH
7836 ***********************************************************************/
7837
7838private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7839 template (omit) RSL_Cause nack := omit)
7840runs on test_CT {
7841 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7842 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007843 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007844 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7845 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007846 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT(chan_nr, ?));
Harald Welte94e0c342018-04-07 11:33:23 +02007847 if (istemplatekind(nack, "omit")) {
7848 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007849 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007850 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007851 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007852 }
7853}
7854
7855private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7856 template (omit) RSL_Cause nack := omit)
7857runs on test_CT {
7858 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7859 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007860 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007861 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7862 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007863 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007864 if (istemplatekind(nack, "omit")) {
7865 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007866 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007867 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007868 //f_ipa_tx(ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007869 }
7870}
7871
7872/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7873testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7874 var RSL_Message rsl_unused;
7875
7876 /* change Timeslot 6 before f_init() starts RSL */
7877 f_init_vty();
7878 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7879 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7880
7881 f_init(1, false);
7882 f_sleep(1.0);
7883
7884 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7885
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007886 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007887 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7888 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007889 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007890
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007891 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007892 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007893 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 +02007894 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7895
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007896 /* clean up config */
7897 f_ts_set_chcomb(0, 0, 6, "PDCH");
7898
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007899 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007900}
7901
7902/* Test Osmocom dyn PDCH activation NACK behavior */
7903testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7904 var RSL_Message rsl_unused;
7905
7906 /* change Timeslot 6 before f_init() starts RSL */
7907 f_init_vty();
7908 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7909 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7910
7911 f_init(1, false);
7912 f_sleep(1.0);
7913
7914 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7915
7916 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7917 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007918 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007919
7920 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007921 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte94e0c342018-04-07 11:33:23 +02007922 f_sleep(1.0);
7923 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7924
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007925 /* clean up config */
7926 f_ts_set_chcomb(0, 0, 6, "PDCH");
7927
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007928 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007929}
7930
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007931/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7932testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7933 var RSL_Message rsl_unused, rsl_msg;
7934 var DchanTuple dt;
7935 var BSSAP_N_CONNECT_ind rx_c_ind;
7936
7937 /* change Timeslot 6 before f_init() starts RSL */
7938 f_init_vty();
7939 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7940 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7941
7942 f_init(1, false);
7943 f_sleep(1.0);
7944
7945 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7946
7947 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7948 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7949 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007950 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007951
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007952 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007953 f_sleep(1.0);
7954 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7955 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7956
7957 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7958 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007959 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007960 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007961 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007962 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007963 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007964 }
7965
7966 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007967 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7968 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7969 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007970
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007971 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007972 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007973 dt.idx := {0, 0};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007974
7975 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007976 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7977 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007978 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7979
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007980 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 +02007981 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7982 dt.sccp_conn_id := rx_c_ind.connectionId;
7983 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7984
7985 /* Instruct BSC to clear channel */
7986 var BssmapCause cause := 0;
7987 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007988 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007989
7990 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007991 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
7992 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007993 f_sleep(1.0);
7994 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7995
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007996 /* Clean up SDCCH lchans */
7997 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
7998 f_perform_clear_test_ct(sdcch_cleanup[i]);
7999 }
8000
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02008001 /* clean up config */
8002 f_ts_set_chcomb(0, 0, 6, "PDCH");
8003
8004 f_shutdown_helper();
8005}
8006
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008007/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
8008testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
8009 var ASP_RSL_Unitdata rsl_ud;
8010 var integer i;
8011 var integer chreq_total, chreq_nochan;
8012
8013 f_init_vty();
8014 for (i := 1; i < 8; i := i + 1) {
8015 if (i == 2) {
8016 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8017 } else {
8018 f_ts_set_chcomb(0, 0, i, "PDCH");
8019 }
8020 }
8021 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8022
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008023 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008024
8025 /* The dyn TS want to activate PDCH mode, ACK that. */
8026 var RslChannelNr chan_nr;
8027 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008028 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
8029 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008030
8031 f_sleep(1.0);
8032
8033 /* Exhaust all dedicated SDCCH lchans.
8034 /* GSM 44.018 Table 9.1.8.2:
8035 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
8036 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008037 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008038 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008039 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008040 }
8041
8042 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008043 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008044 /* Also occupy the seven other SDCCH of the dyn TS */
8045 for (i := 0; i < 7; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008046 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
8047 }
8048
8049 /* Clean up SDCCH lchans */
8050 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8051 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02008052 }
8053
8054 /* clean up config */
8055 f_ts_reset_chcomb(0);
8056
8057 f_shutdown_helper();
8058}
8059
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008060/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
8061 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
8062 it as TCH directly instead. SYS#5309. */
8063testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
8064 var RSL_Message rsl_unused, rsl_msg;
8065 var DchanTuple dt;
8066 var BSSAP_N_CONNECT_ind rx_c_ind;
8067 var integer i;
8068
8069 /* change Timeslot 6 before f_init() starts RSL */
8070 f_init_vty();
8071 for (i := 1; i < 8; i := i + 1) {
8072 if (i == 6) {
8073 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
8074 } else {
8075 f_ts_set_chcomb(0, 0, i, "PDCH");
8076 }
8077 }
8078 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8079
8080 f_init(1, false);
8081 f_sleep(1.0);
8082
8083 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8084
8085 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8086 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8087 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008088 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008089
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008090 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008091 f_sleep(1.0);
8092 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8093 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8094
8095 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8096 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008097 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008098 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008099 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02008100 dt := f_est_dchan(ra, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008101 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008102 }
8103
8104 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008105 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
8106 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8107 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008108
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008109 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008110 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008111 dt.idx := {0, 0};
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008112
8113 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008114 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
8115 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008116 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
8117
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008118 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 +02008119 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
8120 dt.sccp_conn_id := rx_c_ind.connectionId;
8121 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
8122
8123 /* Instruct BSC to clear channel */
8124 var BssmapCause cause := 0;
8125 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008126 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008127
8128 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008129 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8130 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008131 f_sleep(1.0);
8132 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8133
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008134 /* Clean up SDCCH lchans */
8135 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8136 f_perform_clear_test_ct(chan_cleanup[i]);
8137 }
8138
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008139 /* clean up config */
8140 f_ts_reset_chcomb(0);
8141 /* TODO: clean up other channels? */
8142
8143 f_shutdown_helper();
8144}
8145
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008146/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
8147testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
8148 var RSL_Message rsl_unused, rsl_msg;
8149 var DchanTuple dt;
8150 var BSSAP_N_CONNECT_ind rx_c_ind;
8151 var GsmRrMessage rr;
8152
8153 /* change Timeslot 6 before f_init() starts RSL */
8154 f_init_vty();
8155 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8156 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8157
8158 f_init(1, false);
8159 f_sleep(1.0);
8160
8161 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8162
8163 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8164 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8165 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008166 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008167
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008168 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008169 f_sleep(1.0);
8170 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8171 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8172
8173 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8174 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008175 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008176 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008177 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008178 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008179 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008180 }
8181
8182 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008183 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8184 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8185 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008186
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008187 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008188 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008189 dt.idx := {0, 0};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008190
8191 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008192 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8193 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008194 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8195 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8196 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8197 }
8198
8199 /* FIXME? Currently the TS stays in state BORKEN: */
8200
8201 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008202 /* rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8203 * f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008204 * f_sleep(1.0);
8205 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8206 */
8207
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008208 /* Clean up SDCCH lchans */
8209 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8210 f_perform_clear_test_ct(chan_cleanup[i]);
8211 }
8212
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008213 /* clean up config */
8214 f_ts_set_chcomb(0, 0, 6, "PDCH");
8215
8216 f_shutdown_helper();
8217}
8218
Stefan Sperling0796a822018-10-05 13:01:39 +02008219testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008220 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008221 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8222 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8223 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008224 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008225}
8226
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008227testcase TC_chopped_ipa_payload() runs on test_CT {
8228 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8229 /* TODO: mp_bsc_ctrl_port does not work yet */};
8230 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8231 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8232 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008233 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008234}
8235
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008236/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8237 the BTS does autonomous MS power control loop */
8238testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8239 var MSC_ConnHdlr vc_conn;
8240 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8241 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8242 pars.exp_ms_power_params := true;
8243
8244 f_init(1, true);
8245 f_sleep(1.0);
8246 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8247 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008248 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008249}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008250
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008251/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8252testcase TC_c0_power_red_mode() runs on test_CT {
8253 f_init(1);
8254
8255 for (var integer red := 6; red >= 0; red := red - 2) {
8256 /* Configure BCCH carrier power reduction mode via the VTY */
8257 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8258
8259 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008260 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008261 chan_nr := t_RslChanNr_BCCH(0),
8262 bs_power := tr_RSL_IE_BS_Power(red / 2));
8263 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008264 var RSL_Message unused := f_exp_ipa_rx(tr_rsl_pdu);
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008265
8266 /* Additionally verify the applied value over the CTRL interface */
8267 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8268 if (cred != int2str(red)) {
8269 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8270 cred, " (expected ", red, ")");
8271 }
8272 }
8273
8274 f_shutdown_helper();
8275}
8276
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008277/***********************************************************************
8278 * MSC Pooling
8279 ***********************************************************************/
8280
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008281template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008282 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 +02008283
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008284private 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 +02008285runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008286 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008287 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008288 f_logp(BSCVTY, "Got RSL RR Release");
8289 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008290 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008291 f_logp(BSCVTY, "Got RSL Deact SACCH");
8292 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008293 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008294 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008295 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8296 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008297 break;
8298 }
8299 }
8300}
8301
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008302private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8303 var MgcpCommand mgcp_cmd;
8304 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8305 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8306 repeat;
8307 }
8308}
8309
8310private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8311 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8312 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8313 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8314 repeat;
8315 }
8316}
8317
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008318friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8319 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008320runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008321 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8322 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008323 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008324 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8325 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008326 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008327 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008328 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008329 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008330 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008331 }
8332 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008333 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008334 /* Also drop the SCCP connection */
8335 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8336 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008337 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008338 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008339 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8340 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008341 }
8342 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008343 deactivate(ack_dlcx);
8344 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008345}
8346
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008347friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8348runs on MSC_ConnHdlr {
8349 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8350 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8351 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8352 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8353 interleave {
8354 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8355 f_logp(BSCVTY, "Got RSL Deact SACCH");
8356 }
8357 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8358 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8359 /* Also drop the SCCP connection */
8360 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8361 }
8362 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8363 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8364 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8365 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8366 }
8367 }
8368 deactivate(ack_dlcx);
8369 deactivate(ack_rel_req);
8370}
8371
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008372friend function f_perform_clear_no_lchan()
8373runs on MSC_ConnHdlr {
8374 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8375 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8376 BSSAP.receive(tr_BSSMAP_ClearComplete);
8377 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8378 /* Also drop the SCCP connection */
8379 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8380}
8381
Vadim Yanitskiy65d879d2022-06-23 18:15:39 +07008382friend function f_perform_clear_test_ct(DchanTuple dt)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008383 runs on test_CT
8384{
8385 /* Instruct BSC to clear channel */
8386 var BssmapCause cause := 0;
8387 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008388 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008389}
8390
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008391private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8392 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008393runs on MSC_ConnHdlr {
8394 timer T := 10.0;
8395 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8396
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008397 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008398 f_create_bssmap_exp(l3_enc);
8399
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008400 /* RSL_Emulation.f_chan_est() on rsl_pt:
8401 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008402 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8403 */
8404 var RSL_Message rx_rsl;
8405 var GsmRrMessage rr;
8406
8407 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008408 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008409 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008410 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008411 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8412 */
8413 timer Tt := 10.0;
8414
8415 /* request a channel to be established */
8416 Tt.start;
8417 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008418 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008419 Tt.stop;
8420 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008421 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008422 setverdict(fail, "Unexpected RSL message on DCHAN");
8423 mtc.stop;
8424 }
8425 [] Tt.timeout {
8426 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8427 mtc.stop;
8428 }
8429 }
8430 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8431 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008432 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008433
8434
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008435 if (expect_bssmap_l3) {
8436 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8437 var template PDU_BSSAP exp_l3_compl;
8438 exp_l3_compl := tr_BSSMAP_ComplL3()
8439 if (g_pars.aoip == false) {
8440 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8441 } else {
8442 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8443 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008444
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008445 var PDU_BSSAP bssap;
8446 T.start;
8447 alt {
8448 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8449 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8450 log("rx exp_l3_compl = ", bssap);
8451 }
8452 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8453 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8454 }
8455 [] T.timeout {
8456 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8457 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008458 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008459
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008460 /* start ciphering, if requested */
8461 if (ispresent(g_pars.encr)) {
8462 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008463 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008464 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008465 }
8466
8467 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008468 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008469 }
8470 setverdict(pass);
8471 f_sleep(1.0);
8472}
8473
8474private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8475 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8476 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008477 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008478 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008479 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008480 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008481 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008482 }
8483}
8484
8485/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8486private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8487 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008488 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8489 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8490 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8491 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 +02008492}
8493testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8494
8495 f_init(1, true);
8496 f_sleep(1.0);
8497 var MSC_ConnHdlr vc_conn;
8498 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008499
8500 f_ctrs_msc_init();
8501
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008502 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8503 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008504
8505 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008506 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008507}
8508
8509/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8510/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8511 * just as well using only RSL. */
8512testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8513
8514 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8515 f_sleep(1.0);
8516
8517 /* Control which MSC gets chosen next by the round-robin, otherwise
8518 * would be randomly affected by which other tests ran before this. */
8519 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8520
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008521 f_ctrs_msc_init();
8522
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008523 var MSC_ConnHdlr vc_conn1;
8524 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8525 pars1.mscpool.rsl_idx := 0;
8526 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8527 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8528 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008529 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008530
8531 var MSC_ConnHdlr vc_conn2;
8532 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8533 pars2.mscpool.rsl_idx := 1;
8534 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8535 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8536 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008537 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008538
8539 /* Test round-robin wrap to the first MSC */
8540 var MSC_ConnHdlr vc_conn3;
8541 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8542 pars3.mscpool.rsl_idx := 2;
8543 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8544 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8545 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008546 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008547 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008548}
8549
8550/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8551 * (configured in osmo-bsc.cfg). */
8552/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8553 * just as well using only RSL. */
8554testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8555
8556 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8557 f_sleep(1.0);
8558
8559 /* Control which MSC gets chosen next by the round-robin, otherwise
8560 * would be randomly affected by which other tests ran before this. */
8561 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8562
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008563 f_ctrs_msc_init();
8564
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008565 var MSC_ConnHdlr vc_conn1;
8566 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8567 pars1.mscpool.rsl_idx := 0;
8568 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8569 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8570 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008571 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008572
8573 var MSC_ConnHdlr vc_conn2;
8574 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8575 pars2.mscpool.rsl_idx := 1;
8576 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8577 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8578 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008579 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008580
8581 /* Test round-robin wrap to the first MSC */
8582 var MSC_ConnHdlr vc_conn3;
8583 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8584 pars3.mscpool.rsl_idx := 2;
8585 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8586 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8587 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008588 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008589 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008590}
8591
8592/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8593 * (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
8594 * NULL-NRI setting is stronger than that. */
8595/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8596 * just as well using only RSL. */
8597testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8598
8599 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8600 f_sleep(1.0);
8601
8602 /* Control which MSC gets chosen next by the round-robin, otherwise
8603 * would be randomly affected by which other tests ran before this. */
8604 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8605
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008606 f_ctrs_msc_init();
8607
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008608 var MSC_ConnHdlr vc_conn1;
8609 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8610 pars1.mscpool.rsl_idx := 0;
8611 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8612 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8613 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008614 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008615
8616 var MSC_ConnHdlr vc_conn2;
8617 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8618 pars2.mscpool.rsl_idx := 1;
8619 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8620 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8621 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008622 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008623
8624 /* Test round-robin wrap to the first MSC */
8625 var MSC_ConnHdlr vc_conn3;
8626 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8627 pars3.mscpool.rsl_idx := 2;
8628 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8629 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8630 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008631 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008632 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008633}
8634
8635/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8636 * assigned to any MSC (configured in osmo-bsc.cfg). */
8637/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8638 * just as well using only RSL. */
8639testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8640
8641 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8642 f_sleep(1.0);
8643
8644 /* Control which MSC gets chosen next by the round-robin, otherwise
8645 * would be randomly affected by which other tests ran before this. */
8646 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8647
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008648 f_ctrs_msc_init();
8649
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008650 var MSC_ConnHdlr vc_conn1;
8651 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8652 pars1.mscpool.rsl_idx := 0;
8653 /* An NRI that is not assigned to any MSC */
8654 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8655 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8656 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008657 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008658
8659 var MSC_ConnHdlr vc_conn2;
8660 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8661 pars2.mscpool.rsl_idx := 1;
8662 /* An NRI that is not assigned to any MSC */
8663 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8664 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8665 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008666 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008667
8668 /* Test round-robin wrap to the first MSC */
8669 var MSC_ConnHdlr vc_conn3;
8670 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8671 pars3.mscpool.rsl_idx := 2;
8672 /* An NRI that is not assigned to any MSC */
8673 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8674 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8675 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008676 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008677 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008678}
8679
8680/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8681 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8682/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8683 * just as well using only RSL. */
8684testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8685
8686 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8687 f_sleep(1.0);
8688
8689 /* Control which MSC gets chosen next by the round-robin, otherwise
8690 * would be randomly affected by which other tests ran before this. */
8691 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8692
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008693 f_ctrs_msc_init();
8694
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008695 var MSC_ConnHdlr vc_conn1;
8696 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8697 pars1.mscpool.rsl_idx := 0;
8698 /* An NRI that is assigned to an unconnected MSC */
8699 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8700 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8701 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008702 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8703 f_ctrs_msc_add(0, "mscpool:subscr:new");
8704 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008705
8706 var MSC_ConnHdlr vc_conn2;
8707 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8708 pars2.mscpool.rsl_idx := 1;
8709 /* An NRI that is assigned to an unconnected MSC */
8710 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8711 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8712 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008713 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8714 f_ctrs_msc_add(1, "mscpool:subscr:new");
8715 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008716
8717 /* Test round-robin wrap to the first MSC */
8718 var MSC_ConnHdlr vc_conn3;
8719 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8720 pars3.mscpool.rsl_idx := 2;
8721 /* An NRI that is assigned to an unconnected MSC */
8722 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8723 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8724 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008725 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8726 f_ctrs_msc_add(0, "mscpool:subscr:new");
8727 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008728 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008729}
8730
8731/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8732 * osmo-bsc.cfg). */
8733/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8734 * just as well using only RSL. */
8735testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8736
8737 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8738 f_sleep(1.0);
8739
8740 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8741 * this is not using round-robin. */
8742 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8743
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008744 f_ctrs_msc_init();
8745
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008746 var MSC_ConnHdlr vc_conn1;
8747 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8748 pars1.mscpool.rsl_idx := 0;
8749 /* An NRI of the second MSC's range (256-511) */
8750 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8751 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8752 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008753 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008754
8755 var MSC_ConnHdlr vc_conn2;
8756 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8757 pars2.mscpool.rsl_idx := 1;
8758 /* An NRI of the second MSC's range (256-511) */
8759 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8760 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8761 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008762 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008763
8764 var MSC_ConnHdlr vc_conn3;
8765 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8766 pars3.mscpool.rsl_idx := 2;
8767 /* An NRI of the second MSC's range (256-511) */
8768 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8769 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8770 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008771 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008772 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008773}
8774
8775/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8776 * while a round-robin remains unaffected by that. */
8777/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8778 * just as well using only RSL. */
8779testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8780
8781 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8782 f_sleep(1.0);
8783
8784 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8785 * this is not using round-robin. */
8786 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8787
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008788 f_ctrs_msc_init();
8789
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008790 var MSC_ConnHdlr vc_conn1;
8791 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8792 pars1.mscpool.rsl_idx := 0;
8793 /* An NRI of the third MSC's range (512-767) */
8794 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8795 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8796 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008797 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008798
8799 var MSC_ConnHdlr vc_conn2;
8800 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8801 pars2.mscpool.rsl_idx := 1;
8802 /* An NRI of the third MSC's range (512-767) */
8803 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8804 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8805 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008806 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008807
8808 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8809 var MSC_ConnHdlr vc_conn3;
8810 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8811 pars3.mscpool.rsl_idx := 2;
8812 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8813 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8814 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008815 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008816 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008817}
8818
8819/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8820/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8821 * just as well using only RSL. */
8822testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8823
8824 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8825 f_sleep(1.0);
8826
8827 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8828 * instead, and hits msc 0. */
8829 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8830
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008831 f_ctrs_msc_init();
8832
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008833 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8834 var MSC_ConnHdlr vc_conn1;
8835 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8836 pars1.mscpool.rsl_idx := 0;
8837 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8838 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8839 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008840 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008841
8842 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8843 var MSC_ConnHdlr vc_conn2;
8844 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8845 pars2.mscpool.rsl_idx := 1;
8846 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8847 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8848 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008849 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008850 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008851}
8852
8853/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8854 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8855private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8856 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8857 //cid_list := { cIl_allInBSS := ''O };
8858 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8859 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8860 var BSSAP_N_UNITDATA_req paging;
8861 var hexstring imsi := '001010000000123'H;
8862
8863 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8864
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008865 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008866 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8867 BSSAP.send(paging);
8868
8869 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8870 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8871 * channel number is picked here. */
8872 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8873 f_rslem_register(0, new_chan_nr);
8874 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8875 f_rslem_unregister(0, new_chan_nr);
8876
8877 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8878 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008879 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008880 f_sleep(1.0);
8881}
8882testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8883 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8884 f_sleep(1.0);
8885
8886 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8887 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8888 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8889
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008890 f_ctrs_msc_init();
8891
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008892 var MSC_ConnHdlr vc_conn1;
8893 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8894 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008895 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8896 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008897 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8898 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008899 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008900 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008901}
8902
8903/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8904 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8905private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8906 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8907 //cid_list := { cIl_allInBSS := ''O };
8908 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8909 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8910 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008911 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008912 var BSSAP_N_UNITDATA_req paging;
8913
8914 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8915
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008916 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008917 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8918 BSSAP.send(paging);
8919
8920 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8921 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8922 * channel number is picked here. */
8923 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8924 f_rslem_register(0, new_chan_nr);
8925 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8926 f_rslem_unregister(0, new_chan_nr);
8927
8928 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8929 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8930 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008931 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 +02008932 f_sleep(1.0);
8933}
8934testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8935 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8936 f_sleep(1.0);
8937
8938 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8939 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8940 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8941
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008942 f_ctrs_msc_init();
8943
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008944 var MSC_ConnHdlr vc_conn1;
8945 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8946 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008947 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8948 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008949 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8950 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008951 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008952 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008953}
8954
8955/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8956/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8957 * just as well using only RSL. */
8958testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8959
8960 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8961 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008962 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8963 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008964
8965 /* Control which MSC gets chosen next by the round-robin, otherwise
8966 * would be randomly affected by which other tests ran before this. */
8967 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8968
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008969 f_ctrs_msc_init();
8970
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008971 var MSC_ConnHdlr vc_conn1;
8972 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8973 pars1.mscpool.rsl_idx := 0;
8974 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8975 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8976 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008977 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008978
8979 var MSC_ConnHdlr vc_conn2;
8980 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8981 pars2.mscpool.rsl_idx := 1;
8982 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8983 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8984 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008985 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008986
8987 var MSC_ConnHdlr vc_conn3;
8988 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8989 pars3.mscpool.rsl_idx := 2;
8990 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8991 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8992 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008993 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008994 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008995}
8996
8997/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8998 * TMSI NRI. */
8999testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
9000
9001 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
9002 f_sleep(1.0);
9003
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00009004 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
9005 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
9006
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009007 /* Control which MSC gets chosen next by the round-robin, otherwise
9008 * would be randomly affected by which other tests ran before this. */
9009 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
9010
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009011 f_ctrs_msc_init();
9012
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009013 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
9014 var MSC_ConnHdlr vc_conn1;
9015 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
9016 pars1.mscpool.rsl_idx := 0;
9017 /* An NRI of the second MSC's range (256-511) */
9018 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
9019 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
9020 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009021 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009022
9023 var MSC_ConnHdlr vc_conn2;
9024 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
9025 pars2.mscpool.rsl_idx := 1;
9026 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
9027 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
9028 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009029 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009030
9031 var MSC_ConnHdlr vc_conn3;
9032 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
9033 pars3.mscpool.rsl_idx := 2;
9034 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
9035 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
9036 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02009037 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009038 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009039}
9040
Philipp Maier783681c2020-07-16 16:47:06 +02009041/* Allow/Deny emergency calls globally via VTY */
9042private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
9043 f_vty_enter_cfg_msc(BSCVTY, 0);
9044 if (allow) {
9045 f_vty_transceive(BSCVTY, "allow-emergency allow");
9046 } else {
9047 f_vty_transceive(BSCVTY, "allow-emergency deny");
9048 }
9049 f_vty_transceive(BSCVTY, "exit");
9050 f_vty_transceive(BSCVTY, "exit");
9051}
9052
9053/* Allow/Deny emergency calls per BTS via VTY */
9054private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
9055 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9056 if (allow) {
9057 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
9058 } else {
9059 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
9060 }
9061 f_vty_transceive(BSCVTY, "exit");
9062 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00009063 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02009064}
9065
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02009066/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
9067private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
9068 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9069 if (allow) {
9070 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
9071 } else {
9072 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
9073 }
9074 f_vty_transceive(BSCVTY, "exit");
9075 f_vty_transceive(BSCVTY, "exit");
9076 f_vty_transceive(BSCVTY, "exit");
9077}
9078
Pau Espin Pedrol14475352021-07-22 15:48:16 +02009079/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
9080private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
9081 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9082 if (allow) {
9083 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
9084 } else {
9085 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
9086 }
9087 f_vty_transceive(BSCVTY, "exit");
9088 f_vty_transceive(BSCVTY, "exit");
9089 f_vty_transceive(BSCVTY, "exit");
9090}
9091
Philipp Maier783681c2020-07-16 16:47:06 +02009092/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
9093private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
9094 var PDU_ML3_MS_NW emerg_setup;
9095 var octetstring emerg_setup_enc;
9096 var RSL_Message emerg_setup_data_ind;
9097
9098 f_establish_fully(omit, omit);
9099
9100 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
9101 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
9102 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
9103
9104 RSL.send(emerg_setup_data_ind);
9105}
9106
9107/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
9108 * CALLS are permitted by the BSC config. */
9109private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
9110 var PDU_BSSAP emerg_setup_data_ind_bssap;
9111 var PDU_ML3_MS_NW emerg_setup;
9112 timer T := 3.0;
9113
9114 f_assignment_emerg_setup()
9115
9116 T.start;
9117 alt {
9118 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
9119 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
9120 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
9121 setverdict(fail, "no emergency setup");
9122 }
9123 }
9124 [] BSSAP.receive {
9125 setverdict(fail, "unexpected BSSAP message!");
9126 }
9127 [] T.timeout {
9128 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
9129 }
9130 }
9131
9132 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009133 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02009134}
9135
9136/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
9137 * forbidden by the BSC config. */
9138private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
9139 var PDU_BSSAP emerg_setup_data_ind_bssap;
9140 timer T := 3.0;
9141
9142 f_assignment_emerg_setup()
9143
9144 T.start;
9145 alt {
9146 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9147 setverdict(pass);
9148 }
9149 [] RSL.receive {
9150 setverdict(fail, "unexpected RSL message!");
9151 }
9152 [] T.timeout {
9153 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
9154 }
9155 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009156 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01009157 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02009158}
9159
9160/* EMERGENCY CALL situation #1, allowed globally and by BTS */
9161testcase TC_assignment_emerg_setup_allow() runs on test_CT {
9162 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9163 var MSC_ConnHdlr vc_conn;
9164
9165 f_init(1, true);
9166 f_sleep(1.0);
9167
9168 f_vty_allow_emerg_msc(true);
9169 f_vty_allow_emerg_bts(true, 0);
9170 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9171 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009172 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009173}
9174
9175/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
9176testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
9177 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9178 var MSC_ConnHdlr vc_conn;
9179
9180 f_init(1, true);
9181 f_sleep(1.0);
9182
9183 f_vty_allow_emerg_msc(false);
9184 f_vty_allow_emerg_bts(true, 0);
9185 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9186 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009187 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009188}
9189
9190/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
9191testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9192 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9193 var MSC_ConnHdlr vc_conn;
9194
9195 /* Note: This simulates a spec violation by the MS, correct MS
9196 * implementations would not try to establish an emergency call because
9197 * the system information tells in advance that emergency calls are
9198 * not forbidden */
9199
9200 f_init(1, true);
9201 f_sleep(1.0);
9202
9203 f_vty_allow_emerg_msc(true);
9204 f_vty_allow_emerg_bts(false, 0);
9205 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9206 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009207 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009208}
9209
Philipp Maier82812002020-08-13 18:48:27 +02009210/* Test what happens when an emergency call arrives while all TCH channels are
9211 * busy, the BSC is expected to terminate one call in favor of the incoming
9212 * emergency call */
9213testcase TC_emerg_premption() runs on test_CT {
9214 var ASP_RSL_Unitdata rsl_ud;
9215 var integer i;
9216 var integer chreq_total, chreq_nochan;
9217 var RSL_Message rx_rsl;
Philipp Maier82812002020-08-13 18:48:27 +02009218
9219 f_init(1);
9220 f_sleep(1.0);
9221
9222 f_vty_allow_emerg_msc(true);
9223 f_vty_allow_emerg_bts(true, 0);
9224
9225 /* Fill up all channels on the BTS */
9226 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9227 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9228 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 +02009229 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009230 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009231 IPA_RSL[0][0].clear;
Philipp Maier82812002020-08-13 18:48:27 +02009232 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9233 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9234
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009235 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9236 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
9237 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009238 f_ipa_tx(ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009239
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009240 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9241 var BSSAP_N_CONNECT_ind rx_c_ind;
9242 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9243 var integer sccp_conn_id := rx_c_ind.connectionId;
9244 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9245
Philipp Maier82812002020-08-13 18:48:27 +02009246 /* Send Channel request for emegergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009247 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier82812002020-08-13 18:48:27 +02009248
9249 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009250 f_expect_chan_rel(first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009251 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009252
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009253 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9254 var BSSAP_N_DATA_ind rx_clear_req;
9255 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9256 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9257 log("XXX ", rx_clear_req);
9258 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9259 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9260 }
9261
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009262 /* Expect the BSC to send activate/assign the channel for the emergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009263 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009264 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9265 setverdict(fail, "different TCH lchan activated than expected");
9266 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009267 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(first_tch, 33));
9268 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009269
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009270 /* complete the BSSMAP Clear to satisfy the conn leak check */
9271 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9272 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9273 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9274 }
9275
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009276 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009277}
9278
9279/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009280private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009281private type record FHParamsTs {
9282 boolean enabled,
9283 uint6_t hsn,
9284 uint6_t maio,
9285 ArfcnList ma
9286};
9287
9288/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009289private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009290 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009291 FHParamsTs ts[8]
9292};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009293
9294/* Randomly generate the hopping parameters for the given timeslot numbers */
9295private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9296runs on test_CT return FHParamsTrx {
9297 var FHParamsTrx fhp;
9298
Philipp Maier798d8952021-10-19 14:43:19 +02009299 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9300 * fall in the GSM900 band. */
9301 fhp.arfcn.arfcn := f_rnd_int(3);
9302 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009303
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009304 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9305 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009306 fhp.ts[tn].enabled := false;
9307 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009308 continue;
9309 }
9310
9311 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009312 fhp.ts[tn].hsn := f_rnd_int(64);
9313 fhp.ts[tn].maio := f_rnd_int(64);
9314 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009315
9316 /* Random Mobile Allocation (hopping channels) */
9317 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9318 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9319 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009320 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009321 }
9322
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009323 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009324 }
9325
9326 log("f_TC_fh_params_gen(): ", fhp);
9327 return fhp;
9328}
9329
9330/* Make sure that the given Channel Description IE matches the hopping configuration */
9331private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9332{
9333 var template (present) ChannelDescription tr_cd;
9334 var template (present) MaioHsn tr_maio_hsn;
9335 var uint3_t tn := cd.chan_nr.tn;
9336
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009337 if (fhp.ts[tn].enabled) {
9338 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009339 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9340 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009341 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009342 }
9343
9344 if (not match(cd, tr_cd)) {
9345 setverdict(fail, "Channel Description IE does not match: ",
9346 cd, " vs expected ", tr_cd);
9347 }
9348}
9349
9350/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9351private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9352 in MobileAllocationLV ma)
9353{
9354 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9355
9356 if (not match(ma, tr_ma)) {
9357 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9358 tn, "): ", ma, " vs expected: ", tr_ma);
9359 } else {
9360 setverdict(pass);
9361 }
9362}
9363
9364private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9365 in MobileAllocationLV ma)
9366return template MobileAllocationLV {
9367 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009368 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009369 return { len := 0, ma := ''B };
9370 }
9371
9372 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9373 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9374 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009375
9376 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009377 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9378 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9379 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009380 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009381 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009382 }
9383 }
9384
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009385 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009386 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009387
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009388 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009389 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9390 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009391 }
9392
9393 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009394 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009395 if (full_mask[i] != '1'B)
9396 { continue; }
9397
9398 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9399 if (slot_mask[i] == '1'B) {
9400 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009401 } else {
9402 ma_mask := ma_mask & '0'B;
9403 }
9404 }
9405
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009406 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9407 if (full_mask[0] == '1'B) {
9408 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9409 if (slot_mask[0] == '1'B) {
9410 ma_mask := ma_mask & '1'B;
9411 } else {
9412 ma_mask := ma_mask & '0'B;
9413 }
9414 }
9415
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009416 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009417 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009418 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9419
9420 return { len := ma_mask_len, ma := ma_mask };
9421}
9422
Philipp Maier798d8952021-10-19 14:43:19 +02009423/* Configure the appropriate band for a given arfcn, exc */
9424private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9425{
9426 var charstring band;
9427 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9428
9429 select (arfcn_) {
9430 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9431 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9432 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9433 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9434 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9435 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9436 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9437 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9438 case else { return; }
9439 }
9440
9441 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9442 f_vty_transceive(BSCVTY, "band " & band);
9443 f_vty_transceive(BSCVTY, "end");
9444}
9445
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009446/* Configure the hopping parameters in accordance with the given record */
9447private function f_TC_fh_params_set(in FHParamsTrx fhp,
9448 uint8_t bts_nr := 0,
9449 uint8_t trx_nr := 0)
9450runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009451
9452 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9453
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009454 /* Enter the configuration node for the given BTS/TRX numbers */
9455 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9456
Philipp Maier798d8952021-10-19 14:43:19 +02009457 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009458
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009459 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009460 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9461
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009462 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009463 f_vty_transceive(BSCVTY, "hopping enabled 0");
9464 f_vty_transceive(BSCVTY, "exit"); /* go back */
9465 continue;
9466 }
9467
9468 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009469 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9470 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009471
9472 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009473 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9474 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009475 }
9476
9477 f_vty_transceive(BSCVTY, "hopping enabled 1");
9478 f_vty_transceive(BSCVTY, "exit"); /* go back */
9479 }
9480
9481 f_vty_transceive(BSCVTY, "end");
9482}
9483
9484/* Disable frequency hopping on all timeslots */
9485private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9486 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009487 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009488 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009489runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009490
9491 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9492
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009493 /* Enter the configuration node for the given BTS/TRX numbers */
9494 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9495
Philipp Maier798d8952021-10-19 14:43:19 +02009496 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009497
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009498 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009499 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9500
9501 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009502 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9503 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009504 }
9505
9506 f_vty_transceive(BSCVTY, "hopping enabled 0");
9507 f_vty_transceive(BSCVTY, "exit"); /* go back */
9508 }
9509
9510 f_vty_transceive(BSCVTY, "end");
9511 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9512}
9513
9514/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9515 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9516testcase TC_fh_params_chan_activ() runs on test_CT {
9517 var FHParamsTrx fhp := f_TC_fh_params_gen();
9518 var RSL_Message rsl_msg;
9519 var RSL_IE_Body ie;
9520
9521 f_init_vty();
9522
9523 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9524 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9525
9526 f_init(1);
9527
9528 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9529 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009530 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9531 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009532
9533 /* Make sure that Channel Identification IE is present */
9534 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9535 setverdict(fail, "RSL Channel Identification IE is absent");
9536 continue;
9537 }
9538
9539 /* Make sure that hopping parameters (HSN/MAIO) match */
9540 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9541
9542 /* "Mobile Allocation shall be included but empty" - let's check this */
9543 if (ie.chan_ident.ma.v.len != 0) {
9544 setverdict(fail, "Mobile Allocation IE is not empty: ",
9545 ie.chan_ident.ma, ", despite it shall be");
9546 continue;
9547 }
9548 }
9549
9550 /* Disable frequency hopping */
9551 f_TC_fh_params_unset(fhp);
9552
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009553 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009554}
9555
9556/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9557testcase TC_fh_params_imm_ass() runs on test_CT {
9558 var FHParamsTrx fhp := f_TC_fh_params_gen();
9559 var RSL_Message rsl_msg;
9560 var RSL_IE_Body ie;
9561
9562 f_init_vty();
9563
9564 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9565 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9566
9567 f_init(1);
9568
9569 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9570 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009571 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9572 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009573
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009574 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9575 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009576
9577 /* Make sure that Full Immediate Assign Info IE is present */
9578 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9579 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9580 continue;
9581 }
9582
9583 /* Decode the actual Immediate Assignment message */
9584 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9585 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9586 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9587 continue;
9588 }
9589
9590 /* Make sure that hopping parameters (HSN/MAIO) match */
9591 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9592
9593 /* Make sure that the Mobile Allocation IE matches */
9594 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9595 rr_msg.payload.imm_ass.mobile_allocation);
9596 }
9597
9598 /* Disable frequency hopping */
9599 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009600
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009601 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009602}
9603
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009604/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9605testcase TC_fh_params_assignment_cmd() runs on test_CT {
9606 var FHParamsTrx fhp := f_TC_fh_params_gen();
9607 var RSL_Message rsl_msg;
9608 var RSL_IE_Body ie;
9609
9610 f_init_vty();
9611
9612 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9613 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9614
9615 f_init(1);
9616
9617 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +02009618 vc_MGCP[0].stop;
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009619
9620 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9621 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9622
9623 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9624 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9625 for (var integer i := 0; i < 3; i := i + 1) {
9626 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
9627 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
9628
9629 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9630 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009631 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009632
9633 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009634 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9635 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009636
9637 /* Make sure that L3 Information IE is present */
9638 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9639 setverdict(fail, "RSL L3 Information IE is absent");
9640 continue;
9641 }
9642
9643 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9644 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9645 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9646 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9647 continue;
9648 }
9649
9650 /* Make sure that hopping parameters (HSN/MAIO) match */
9651 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9652 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9653
9654 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9655 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009656 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009657 continue;
9658 }
9659
9660 /* Make sure that the Mobile Allocation IE matches (if present) */
9661 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9662 if (chan_desc.h and ma_present) {
9663 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9664 l3_msg.payload.ass_cmd.mobile_allocation.v);
9665 } else if (chan_desc.h and not ma_present) {
9666 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9667 continue;
9668 } else if (not chan_desc.h and ma_present) {
9669 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9670 continue;
9671 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009672
9673 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009674 }
9675
9676 /* Give the IUT some time to release all channels */
9677 f_sleep(3.0);
9678
9679 /* Disable frequency hopping */
9680 f_TC_fh_params_unset(fhp);
9681
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009682 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009683}
9684
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009685/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9686private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9687runs on test_CT {
9688 var RSL_Message rsl_msg;
9689 var RSL_IE_Body ie;
9690 var DchanTuple dt;
9691
9692 /* Establish a dedicated channel, so we can trigger handover */
9693 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009694 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009695
9696 /* Trigger handover from BTS0 to BTS1 */
9697 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9698 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9699
9700 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009701 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx := {1, 0});
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009702
9703 /* ACKnowledge channel activation and expect (RR) Handover Command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009704 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33), idx := {1, 0});
9705 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009706
9707 /* Make sure that L3 Information IE is present */
9708 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9709 setverdict(fail, "RSL L3 Information IE is absent");
9710 return;
9711 }
9712
9713 /* Decode the L3 message and make sure it is (RR) Handover Command */
9714 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9715 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9716 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9717 return;
9718 }
9719
9720 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9721 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9722 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9723 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9724 return;
9725 }
9726
9727 /* Make sure that hopping parameters (HSN/MAIO) match */
9728 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9729
9730 /* Make sure that Cell Channel Description IE is present */
9731 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9732 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9733 return;
9734 }
9735
9736 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9737 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9738 if (ma_present) {
9739 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9740 l3_msg.payload.ho_cmd.mobile_allocation.v);
9741 } else {
9742 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9743 return;
9744 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009745
9746 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009747}
9748testcase TC_fh_params_handover_cmd() runs on test_CT {
9749 var FHParamsTrx fhp := f_TC_fh_params_gen();
9750
9751 f_init_vty();
9752
9753 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9754 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9755
9756 f_vty_transceive(BSCVTY, "timeslot 0");
9757 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9758 f_vty_transceive(BSCVTY, "exit"); /* go back */
9759
9760 f_vty_transceive(BSCVTY, "timeslot 1");
9761 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9762 f_vty_transceive(BSCVTY, "end"); /* we're done */
9763
9764 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9765 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9766
9767 f_init(2);
9768
9769 f_TC_fh_params_handover_cmd(fhp);
9770
9771 /* Disable frequency hopping on BTS1 */
9772 f_TC_fh_params_unset(fhp, 1);
9773
9774 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9775 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9776
9777 f_vty_transceive(BSCVTY, "timeslot 0");
9778 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9779 f_vty_transceive(BSCVTY, "exit"); /* go back */
9780
9781 f_vty_transceive(BSCVTY, "timeslot 1");
9782 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9783 f_vty_transceive(BSCVTY, "end"); /* we're done */
9784
9785 f_shutdown_helper();
9786}
9787
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009788/* Verify the hopping parameters in System Information Type 4 */
9789testcase TC_fh_params_si4_cbch() runs on test_CT {
9790 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9791 var ASP_RSL_Unitdata rx_rsl_ud;
9792 timer T := 5.0;
9793
9794 f_init_vty();
9795
9796 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9797 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9798
9799 f_vty_transceive(BSCVTY, "timeslot 0");
9800 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9801 f_vty_transceive(BSCVTY, "exit"); /* go back */
9802
9803 f_vty_transceive(BSCVTY, "timeslot 1");
9804 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9805 f_vty_transceive(BSCVTY, "end"); /* we're done */
9806
9807 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9808 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9809
9810 f_init(1);
9811
9812 T.start;
9813 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009814 [] 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 +07009815 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9816 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9817
9818 /* Make sure that what we decoded is System Information Type 4 */
9819 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9820 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9821 repeat;
9822 }
9823
9824 /* Make sure that CBCH Channel Description IE is present */
9825 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9826 setverdict(fail, "CBCH Channel Description IE is absent");
9827 break;
9828 }
9829
9830 /* Finally, check the hopping parameters (HSN, MAIO) */
9831 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9832 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9833
9834 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9835 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9836 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9837 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9838 break;
9839 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9840 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9841 si.payload.si4.cbch_mobile_alloc.v);
9842 }
9843 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009844 [] IPA_RSL[0][0].receive { repeat; }
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009845 [] T.timeout {
9846 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9847 }
9848 }
9849
9850 /* Disable frequency hopping */
9851 f_TC_fh_params_unset(fhp);
9852
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009853 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009854 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9855
9856 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009857 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009858 f_vty_transceive(BSCVTY, "exit"); /* go back */
9859
9860 f_vty_transceive(BSCVTY, "timeslot 1");
9861 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9862 f_vty_transceive(BSCVTY, "end"); /* we're done */
9863
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009864 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009865}
9866
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009867template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9868 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9869
9870private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9871 template (present) BSSLAP_PDU expect_bsslap)
9872{
9873 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9874 if (not match(bsslap, expect_bsslap)) {
9875 log("EXPECTING BSSLAP: ", expect_bsslap);
9876 log("GOT BSSLAP: ", bsslap);
9877 setverdict(fail, "BSSLAP is not as expected");
9878 mtc.stop;
9879 }
9880 setverdict(pass);
9881}
9882
9883/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9884const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9885
9886private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9887 var PDU_BSSAP_LE rx_bsslap;
9888 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9889 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9890}
9891
9892/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9893 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9894private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9895 f_sleep(1.0);
9896
9897 f_establish_fully(omit, omit);
9898 f_bssap_le_register_imsi(g_pars.imsi, omit);
9899
9900 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9901 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9902
9903 var PDU_BSSAP_LE plr;
9904 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9905
9906 if (not do_ta_request) {
9907 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9908 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9909 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9910 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9911 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9912 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9913 mtc.stop;
9914 }
9915 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9916 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9917 if (not match(bsslap, expect_ta_layer3)) {
9918 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9919 log("GOT BSSLAP: ", bsslap);
9920 setverdict(fail, "BSSLAP is not as expected");
9921 mtc.stop;
9922 }
9923 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9924 * has no need to request the TA from the BSC and directly responds. */
9925 } else {
9926 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9927 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9928 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9929 }
9930
9931 /* SMLC got the TA from the BSC, now responds with geo information data. */
9932 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9933 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9934 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9935
9936 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9937 f_mo_l3_transceive();
9938
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009939 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009940
9941 f_sleep(2.0);
9942 setverdict(pass);
9943}
9944
9945/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9946 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9947private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9948 f_lcs_loc_req_for_active_ms(false);
9949}
9950testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9951 var MSC_ConnHdlr vc_conn;
9952 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9953
9954 f_init(1, true);
9955 f_sleep(1.0);
9956 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9957 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009958 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009959}
9960
9961/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9962 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9963private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9964 f_lcs_loc_req_for_active_ms(true);
9965}
9966testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9967 var MSC_ConnHdlr vc_conn;
9968 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9969
9970 f_init(1, true);
9971 f_sleep(1.0);
9972 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9973 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009974 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009975}
9976
9977/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9978 * conn without an active lchan. */
9979private function f_clear_A_conn() runs on MSC_ConnHdlr
9980{
9981 var BssmapCause cause := 0;
9982 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9983 BSSAP.receive(tr_BSSMAP_ClearComplete);
9984 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9985
9986 timer no_more_bssap := 5.0;
9987 no_more_bssap.start;
9988 alt {
9989 [] no_more_bssap.timeout { break; }
9990 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9991 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9992 mtc.stop;
9993 }
9994 }
9995 setverdict(pass);
9996}
9997
9998/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9999 * for LCS, for cases where there is only an A conn without an active lchan. */
10000private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
10001{
10002 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
10003
10004 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
10005 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
10006 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
10007 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10008 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10009 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10010
10011 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
10012 f_clear_A_conn();
10013 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10014 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10015}
10016
10017/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
10018 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
10019 */
10020private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
10021 f_sleep(1.0);
10022
10023 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10024 f_bssap_le_register_imsi(g_pars.imsi, omit);
10025
10026 /* Register to receive the Paging Command */
10027 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10028 g_chan_nr := new_chan_nr;
10029 f_rslem_register(0, g_chan_nr);
10030
10031 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10032 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10033 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10034 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10035
10036 var PDU_BSSAP_LE plr;
10037 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10038
10039 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10040 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10041
10042 /* OsmoBSC needs to Page */
10043 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
10044 f_logp(BSCVTY, "got Paging Command");
10045
10046 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
10047 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010048 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);
10049 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010050
10051 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
10052
10053 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10054
10055 /* SMLC got the TA from the BSC, now responds with geo information data. */
10056 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10057 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10058
10059 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10060
10061 /* The lchan is gone, the A-interface conn was created for the LCS only.
10062 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
10063 f_verify_active_A_conn_and_clear();
10064
10065 f_sleep(2.0);
10066 setverdict(pass);
10067}
10068testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
10069 var MSC_ConnHdlr vc_conn;
10070 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10071
10072 f_init(1, true);
10073 f_sleep(1.0);
10074
10075 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10076 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10077
10078 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
10079 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010080 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010081}
10082
10083/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
10084 */
10085private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
10086 f_sleep(1.0);
10087
10088 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10089 f_bssap_le_register_imsi(g_pars.imsi, omit);
10090
10091 /* provoke an abort by omitting both IMSI and IMEI */
10092 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10093 valueof(ts_BSSMAP_Perform_Location_Request(omit,
10094 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
10095 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10096
10097 /* BSC tells MSC about failure */
10098 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10099 locationEstimate := omit, positioningData := omit,
10100 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
10101
10102 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10103 f_verify_active_A_conn_and_clear();
10104
10105 f_sleep(2.0);
10106 setverdict(pass);
10107}
10108testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
10109 var MSC_ConnHdlr vc_conn;
10110 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10111
10112 f_init(1, true);
10113 f_sleep(1.0);
10114
10115 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10116 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10117
10118 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
10119 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010120 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010121}
10122
10123/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10124 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
10125private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
10126 f_sleep(1.0);
10127
10128 f_establish_fully(omit, omit);
10129 f_bssap_le_register_imsi(g_pars.imsi, omit);
10130
10131 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10132 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10133
10134 var PDU_BSSAP_LE plr;
10135 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10136
10137 if (do_ta) {
10138 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10139 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10140 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10141 }
10142
10143 /* SMLC fails to respond, BSC runs into timeout */
10144 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
10145 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10146
10147 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10148 locationEstimate := omit, positioningData := omit,
10149 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
10150
10151 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10152 f_verify_active_A_conn_and_clear();
10153
10154 f_sleep(2.0);
10155 setverdict(pass);
10156}
10157
10158/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10159 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
10160private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
10161 f_lcs_loc_req_for_active_ms_le_timeout(false);
10162}
10163
10164testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
10165 var MSC_ConnHdlr vc_conn;
10166 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10167
10168 f_init(1, true);
10169 f_sleep(1.0);
10170 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
10171 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010172 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010173}
10174
10175/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10176 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
10177private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
10178 f_lcs_loc_req_for_active_ms_le_timeout(true);
10179}
10180
10181testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
10182 var MSC_ConnHdlr vc_conn;
10183 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10184
10185 f_init(1, true);
10186 f_sleep(1.0);
10187 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10188 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010189 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010190}
10191
10192/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10193private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10194 f_sleep(1.0);
10195
10196 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10197 f_bssap_le_register_imsi(g_pars.imsi, omit);
10198
10199 /* Register to receive the Paging Command */
10200 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10201 g_chan_nr := new_chan_nr;
10202 f_rslem_register(0, g_chan_nr);
10203
10204 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10205 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10206 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10207 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10208
10209 var PDU_BSSAP_LE plr;
10210 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10211
10212 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10213 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10214
10215 /* OsmoBSC needs to Page */
10216 var PDU_BSSAP_LE rx_bsslap;
10217 alt {
10218 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10219 f_logp(BSCVTY, "got Paging Command");
10220 repeat;
10221 }
10222 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10223 /* MS does not respond to Paging, TA Req runs into timeout. */
10224 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10225 }
10226 }
10227
10228 /* SMLC responds with failure */
10229 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10230 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10231
10232 /* BSC tells MSC about failure */
10233 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10234 locationEstimate := omit, positioningData := omit,
10235 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10236
10237 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10238 f_verify_active_A_conn_and_clear();
10239
10240 f_sleep(2.0);
10241 setverdict(pass);
10242}
10243testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10244 var MSC_ConnHdlr vc_conn;
10245 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10246
10247 f_init(1, true);
10248 f_sleep(1.0);
10249
10250 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10251 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10252
10253 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10254 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010255 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010256}
10257
10258/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10259 * over. */
10260private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10261 f_sleep(1.0);
10262
10263 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10264 f_bssap_le_register_imsi(g_pars.imsi, omit);
10265
10266 /* Register to receive the Paging Command */
10267 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10268 g_chan_nr := new_chan_nr;
10269 f_rslem_register(0, g_chan_nr);
10270
10271 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10272 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10273 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10274 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10275
10276 var PDU_BSSAP_LE plr;
10277 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10278
10279 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10280 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010281 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 +020010282 do_clear := false, expect_bssmap_l3 := true);
10283
10284 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10285 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10286
10287 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10288 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10289
10290 /* SMLC got the TA from the BSC, now responds with geo information data. */
10291 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10292 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10293 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10294
10295 /* The lchan should still exist, it was from a CM Service Request. */
10296 f_mo_l3_transceive();
10297
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010298 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010299
10300 f_sleep(2.0);
10301 setverdict(pass);
10302}
10303testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10304 var MSC_ConnHdlr vc_conn;
10305 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10306
10307 f_init(1, true);
10308 f_sleep(1.0);
10309
10310 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10311 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10312
10313 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10314 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010315 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010316}
10317
10318/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10319 * the new lchan after handover. */
10320private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10321 f_sleep(1.0);
10322
10323 f_establish_fully(omit, omit);
10324 f_bssap_le_register_imsi(g_pars.imsi, omit);
10325
10326 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10327 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10328
10329 var PDU_BSSAP_LE plr;
10330 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10331
10332 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10333 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10334
10335 var HandoverState hs := {
10336 rr_ho_cmpl_seen := false,
10337 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010338 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010339 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010340 };
10341 /* issue hand-over command on VTY */
10342 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10343 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10344 f_rslem_suspend(RSL1_PROC);
10345
10346 /* From the MGW perspective, a handover is is characterized by
10347 * performing one MDCX operation with the MGW. So we expect to see
10348 * one more MDCX during handover. */
10349 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10350
10351 alt {
10352 [] as_handover(hs);
10353 }
10354
10355 var PDU_BSSAP_LE rx_bsslap;
10356
10357 interleave {
10358 /* Expect the BSC to inform the MSC about the handover */
10359 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10360
10361 /* Expect the BSC to inform the SMLC about the handover */
10362 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10363 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10364 }
10365 }
10366
10367 /* SMLC now responds with geo information data. */
10368 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10369 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10370 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10371
10372 /* lchan still active */
10373 f_mo_l3_transceive(RSL1);
10374
10375 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010376 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010377
10378 f_sleep(2.0);
10379 setverdict(pass);
10380}
10381testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10382 var MSC_ConnHdlr vc_conn;
10383 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10384
10385 f_init(2, true);
10386 f_sleep(1.0);
10387 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10388 vc_conn.done;
Oliver Smith39f53072022-10-27 14:44:04 +020010389 f_shutdown_helper(ho := true);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010390}
10391
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010392private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10393{
10394 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10395 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10396 * another lchan. */
10397 g_pars.ra := 'b7'O;
10398 f_assignment_emerg_setup();
10399
10400 var PDU_BSSAP emerg_setup_data_ind_bssap;
10401 timer T := 3.0;
10402 T.start;
10403 alt {
10404 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10405 var PDU_ML3_MS_NW verify_emerg_setup;
10406 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10407 if (not isbound(verify_emerg_setup.msgs.cc.emergencySetup)) {
10408 setverdict(fail, "no emergency setup");
10409 }
10410 }
10411 [] BSSAP.receive {
10412 setverdict(fail, "unexpected BSSAP message!");
10413 }
10414 [] T.timeout {
10415 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10416 }
10417 }
10418
10419 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10420
10421 /* Do a Location Request in-between the CC call setup */
10422 f_bssap_le_register_imsi(g_pars.imsi, omit);
10423 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10424 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10425 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10426 /* SMLC got the TA from the BSC, now responds with geo information data. */
10427 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10428 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10429 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10430
10431 /* Go on with voice call assignment */
10432 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10433 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10434
10435 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
10436 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
10437 * seems a good idea to see how osmo-bsc reacts to this. */
10438 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
10439 elementIdentifier := '0B'O, /* overwritten */
10440 lengthIndicator := 0, /* overwritten */
10441 speechOrDataIndicator := '0001'B, /* speech */
10442 spare1_4 := '0000'B,
10443 channelRateAndType := ChRate_TCHForH_Fpref,
10444 speechId_DataIndicator := 'c2918105'O
10445 };
10446 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
10447 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
10448
10449 f_rslem_dchan_queue_enable();
10450
10451 var ExpectCriteria mgcpcrit := {
10452 connid := omit,
10453 endpoint := omit,
10454 transid := omit
10455 };
10456 f_create_mgcp_expect(mgcpcrit);
10457
10458 BSSAP.send(ass_cmd);
10459
10460 var AssignmentState st := valueof(ts_AssignmentStateInit);
10461 st.voice_call := true;
10462 st.is_assignment := false;
10463 alt {
10464 [] as_modify(st);
10465 [] as_Media();
10466 [st.modify_done] BSSAP.receive(exp_compl) {
10467 setverdict(pass);
10468 }
10469 }
10470
10471 /* Voice call carries on ... */
10472 f_sleep(2.0);
10473
10474 setverdict(pass);
10475 f_perform_clear();
10476}
10477
10478testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10479 var MSC_ConnHdlr vc_conn;
10480 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10481
10482 f_init(1, true);
10483 f_sleep(1.0);
10484 f_vty_allow_emerg_msc(true);
10485 f_vty_allow_emerg_bts(true, 0);
10486 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10487 vc_conn.done;
10488 f_shutdown_helper();
10489}
10490
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010491private altstep no_bssmap_clear_req() runs on MSC_ConnHdlr {
10492 [] BSSAP.receive(tr_BSSMAP_ClearRequest) {
10493 setverdict(fail, "unexpected BSSMAP Clear Request");
10494 mtc.stop;
10495 }
10496}
10497
10498private type enumerated RslRel {
10499 RSLREL_REL_IND,
10500 RSLREL_CONN_FAIL
10501};
10502
10503private function f_emerg_call_and_lcs_loc_req_early_lchan_release(RslRel rsl_rel) runs on MSC_ConnHdlr
10504{
10505 g_pars.ra := f_rnd_ra_emerg();
10506 f_assignment_emerg_setup();
10507
10508 var PDU_BSSAP emerg_setup_data_ind_bssap;
10509 timer T := 3.0;
10510 T.start;
10511 alt {
10512 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10513 var PDU_ML3_MS_NW verify_emerg_setup;
10514 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10515 if (not ischosen(verify_emerg_setup.msgs.cc.emergencySetup)) {
10516 setverdict(fail, "no emergency setup");
10517 }
10518 }
10519 [] BSSAP.receive {
10520 setverdict(fail, "unexpected BSSAP message!");
10521 }
10522 [] T.timeout {
10523 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10524 }
10525 }
10526
10527 /* Start a Location Request to locate the emergency */
10528 f_bssap_le_register_imsi(g_pars.imsi, omit);
10529 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10530 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10531 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10532
10533 /* 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
10534 * do a Clear Command when the Location Response arrives. */
10535 activate(no_bssmap_clear_req());
10536
10537 /* the lchan gets interrupted while the Location Request has no response */
10538 select (rsl_rel) {
10539 case (RSLREL_REL_IND) {
10540 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10541 f_expect_lchan_rel(RSL, RSL_PROC);
10542 }
10543 case (RSLREL_CONN_FAIL) {
10544 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
10545 }
10546 case else {
10547 setverdict(fail, "Unknown RslRel type");
10548 mtc.stop;
10549 }
10550 }
10551
10552 /* Still expect the Location Response to find its way to the MSC. */
10553 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10554 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10555 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10556
10557 setverdict(pass);
10558
10559 select (rsl_rel) {
10560 case (RSLREL_REL_IND) {
10561 f_perform_clear_no_lchan();
10562 }
10563 case (RSLREL_CONN_FAIL) {
10564 f_perform_clear();
10565 }
10566 }
10567}
10568
10569private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind(charstring id) runs on MSC_ConnHdlr
10570{
10571 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_REL_IND);
10572}
10573
10574testcase TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() runs on test_CT {
10575 var MSC_ConnHdlr vc_conn;
10576 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10577
10578 f_init(1, true);
10579 f_sleep(1.0);
10580 f_vty_allow_emerg_msc(true);
10581 f_vty_allow_emerg_bts(true, 0);
10582 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind), pars);
10583 vc_conn.done;
10584 f_shutdown_helper();
10585}
10586
10587private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail(charstring id) runs on MSC_ConnHdlr
10588{
10589 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_CONN_FAIL);
10590}
10591
10592testcase TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() runs on test_CT {
10593 var MSC_ConnHdlr vc_conn;
10594 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10595
10596 f_init(1, true);
10597 f_sleep(1.0);
10598 f_vty_allow_emerg_msc(true);
10599 f_vty_allow_emerg_bts(true, 0);
10600 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail), pars);
10601 vc_conn.done;
10602 f_shutdown_helper();
10603}
10604
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010605/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10606private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10607 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10608
10609 /* Also disable attach for the single connected MSC */
10610 f_vty_msc_allow_attach(BSCVTY, { false });
10611
10612 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) ));
10613 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10614
10615 /* No MSC is found, expecting a proper release on RSL */
10616 interleave {
10617 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10618 f_logp(BSCVTY, "Got RSL RR Release");
10619 }
10620 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10621 f_logp(BSCVTY, "Got RSL Deact SACCH");
10622 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010623 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010624 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10625 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010626 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010627 }
10628 }
10629 setverdict(pass);
10630}
10631testcase TC_no_msc() runs on test_CT {
10632
10633 f_init(1, true);
10634 f_sleep(1.0);
10635 var MSC_ConnHdlr vc_conn;
10636 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10637
10638 f_ctrs_bsc_init(counternames_bsc_mscpool);
10639
10640 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10641 vc_conn.done;
10642
10643 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10644 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010645 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010646}
10647
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010648/* Dyn PDCH todo:
10649 * activate OSMO as TCH/F
10650 * activate OSMO as TCH/H
10651 * does the BSC-located PCU socket get the updated INFO?
10652 * what if no PCU is connected at the time?
10653 * is the info correct on delayed PCU (re)connect?
10654 */
Harald Welte94e0c342018-04-07 11:33:23 +020010655
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010656private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +020010657 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020010658 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010659
10660 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10661 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10662 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10663 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10664 g_pars.ass_codec_list.codecElements[0];
10665 if (isvalue(g_pars.expect_mr_s0_s7)) {
10666 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10667 g_pars.expect_mr_s0_s7;
10668 }
10669 }
10670 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10671 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10672 log("expecting ASS COMPL like this: ", exp_compl);
10673
10674 f_establish_fully(ass_cmd, exp_compl);
10675
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010676 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 +000010677
10678 var RSL_Message rsl;
10679
10680 timer T := 5.0;
10681 T.start;
10682 alt {
10683 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10684 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10685 log("Rx L3 from net: ", l3);
10686 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10687 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10688 mtc.stop;
10689 }
10690 }
10691 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10692 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10693 mtc.stop;
10694 }
10695 [] T.timeout {
10696 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10697 setverdict(pass);
10698 }
10699 }
10700 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010701
10702 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010703}
10704
10705/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10706 * osmo-bsc. */
10707testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10708 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10709 var MSC_ConnHdlr vc_conn;
10710
10711 f_init(1, true);
10712 f_sleep(1.0);
10713
10714 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10715 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10716 vc_conn.done;
10717 f_shutdown_helper();
10718}
10719
10720/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10721 */
10722testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10723 f_init_vty();
10724
10725 f_init(1, false);
10726 f_sleep(1.0);
10727
10728 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10729
10730 var ASP_RSL_Unitdata rx_rsl_ud;
10731 timer T := 5.0;
10732
10733 T.start;
10734 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010735 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010736 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10737 T.stop;
10738 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10739 mtc.stop;
10740 }
10741 repeat;
10742 }
10743 [] T.timeout {
10744 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10745 setverdict(pass);
10746 }
10747 }
10748}
10749
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010750private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10751 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010752 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010753
10754 /* Trigger re-assignment to another lchan */
10755 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10756
10757 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10758 * one MDCX on MGCP. */
10759 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10760
10761 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10762 * as the old lchan used. */
10763 g_media.bts.ipa_crcx_seen := false;
10764 g_media.bts.ipa_mdcx_seen := false;
10765
10766 /* Send different BTS side RTP port number for the new lchan */
10767 g_media.bts.bts.port_nr := 4223;
10768
10769 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10770
10771 /* Trigger re-assignment. */
10772 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10773
10774 timer T := 5.0;
10775 T.start;
10776 alt {
10777 [] as_assignment(assignment_st);
10778 [] as_Media();
10779 [] T.timeout {
10780 break;
10781 }
10782 }
10783
10784 if (not assignment_st.assignment_done) {
10785 setverdict(fail, "Assignment did not complete");
10786 mtc.stop;
10787 }
10788
10789 f_check_mgcp_expectations()
10790 setverdict(pass);
10791
10792 f_sleep(2.0);
10793 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10794
10795 /* Instruct BSC to clear channel */
10796 var BssmapCause cause := 0;
10797 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10798 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010799 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10800 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010801 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010802 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010803 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010804 }
10805 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10806 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10807 }
10808 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010809 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010810
10811 f_sleep(0.5);
10812}
10813
10814testcase TC_reassignment_fr() runs on test_CT {
10815 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10816 var MSC_ConnHdlr vc_conn;
10817
10818 f_init(1, true);
10819 f_sleep(1.0);
10820
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010821 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010822
10823 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10824 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10825 vc_conn.done;
10826
10827 /* from f_establish_fully() */
10828 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10829 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10830 /* from re-assignment */
10831 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10832 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10833 f_ctrs_bsc_and_bts_verify();
10834 f_shutdown_helper();
10835}
10836
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010837const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10838const charstring REEST_CLEAR := "REEST_CLEAR";
10839const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10840
10841/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10842 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10843 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10844 * the MSC as the CM Re-Establishment is handled.
10845 *
10846 * MS bts0 bts1 bsc msc test-component
10847 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10848 * | | _1 wait a bit, to settle down
10849 * |<-x x--| | _1 "lose connection"
10850 * | | REEST_LOST_CONNECTION
10851 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10852 * | | REEST_CLEAR
10853 * | |<-0---| _1 Clear Command on first A-conn
10854 * | |--0-->| _1 Clear Complete
10855 * | |<----------------->| | _1 Release first channel
10856 * | | REEST_CLEAR_DONE
10857 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10858 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10859 *
10860 */
10861private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10862 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10863 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10864
10865 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10866 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10867
10868 f_establish_fully(ass_cmd, exp_compl);
10869
10870 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10871 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10872 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10873 f_sleep(2.0);
10874 COORD.send(REEST_LOST_CONNECTION);
10875
10876 alt {
10877 [] COORD.receive(REEST_CLEAR);
10878 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10879 setverdict(fail, "Unexpected channel release");
10880 mtc.stop;
10881 }
10882 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10883 setverdict(fail, "Unexpected channel release");
10884 mtc.stop;
10885 }
10886 }
10887 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010888 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010889 COORD.send(REEST_CLEAR_DONE);
10890}
10891
10892private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10893 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10894
10895 /* The MS lost the connection on the first channel, now establishes another one */
10896 COORD.receive(REEST_LOST_CONNECTION);
10897
10898 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10899 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10900 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10901
10902 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010903 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 +020010904 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10905
10906 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10907 COORD.send(REEST_CLEAR);
10908 COORD.receive(REEST_CLEAR_DONE);
10909
10910 f_sleep(2.0);
10911
10912 /* Answer the CM Re-Establishment with an Assignment Command. */
10913 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10914 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10915 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10916 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10917
10918 var AssignmentState st := valueof(ts_AssignmentStateInit);
10919 st.voice_call := true;
10920 st.is_assignment := true;
10921
10922 var ExpectCriteria mgcpcrit := {
10923 connid := omit,
10924 endpoint := omit,
10925 transid := omit
10926 };
10927 f_create_mgcp_expect(mgcpcrit);
10928
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010929 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010930
10931 BSSAP.send(ass_cmd);
10932
10933 var PDU_BSSAP bssap;
10934
10935 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010936 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10937 [] as_Media_ipacc(RSL1, RSL2);
10938 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010939 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10940 break;
10941 }
10942 }
10943
10944 f_sleep(3.0);
10945
10946 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010947 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010948}
10949
10950testcase TC_cm_reestablishment() runs on test_CT {
10951 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10952 var MSC_ConnHdlr vc_conn1;
10953
10954 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10955 var MSC_ConnHdlr vc_conn2;
10956 pars2.imsi := pars1.imsi;
10957 pars2.media_nr := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010958 pars2.expect_tsc := c_BtsParams[1].tsc;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010959
10960 f_init(2, true, guard_timeout := 40.0);
10961 f_sleep(1.0);
10962
10963 vc_conn1 := f_start_handler_create(pars1);
10964 vc_conn2 := f_start_handler_create(pars2);
10965 connect(vc_conn1:COORD, vc_conn2:COORD);
10966 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10967 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10968 vc_conn1.done;
10969 vc_conn2.done;
10970
10971 f_shutdown_helper();
10972}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010973
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010974function f_exp_ipa_rx_nonfatal(template (present) RSL_Message t_rx,
10975 boolean ignore_other_rx := true,
10976 BtsTrxIdx idx := {0, 0},
10977 float Tval := 2.0)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010978runs on test_CT return template (omit) RSL_Message {
10979 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010980 timer T := Tval;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010981
10982 T.start;
10983 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010984 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010985 T.stop;
10986 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010987 [ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
10988 [not ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010989 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10990 T.stop;
10991 return omit;
10992 }
10993 [] T.timeout {
10994 return omit;
10995 }
10996 }
10997 return rx_rsl_ud.rsl;
10998}
10999
11000private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
11001 f_vty_enter_cfg_bts(pt, bts_nr);
11002 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
11003 f_vty_transceive(pt, "exit");
11004 f_vty_transceive(pt, "exit");
11005 f_vty_transceive(pt, "exit");
11006}
11007
11008private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030011009 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011010 template (present) uint12_t arfcn := ?,
11011 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011012{
11013 var RSL_IE_Body full_imm_ass_info;
11014 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
11015 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
11016 mtc.stop;
11017 }
11018
11019 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
11020 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
11021 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011022 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011023 page_mode := ?);
11024 if (not match(rr_imm_ass, expect_imm_ass)) {
11025 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
11026 setverdict(fail, "Failed to match Immediate Assignment");
11027 mtc.stop;
11028 }
11029}
11030
11031testcase TC_imm_ass_post_chan_ack() runs on test_CT {
11032 var RSL_Message chan_act;
11033 var RSL_Message imm_ass;
11034
11035 f_init(1, false);
11036 f_sleep(1.0);
11037
11038 /* (should be the default anyway, just to make things clear) */
11039 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
11040
11041 /* RA containing reason=LU */
11042 var GsmFrameNumber fn := 2342;
11043 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011044 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011045
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011046 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011047
11048 /* First send the Chan Act ACK */
11049 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011050 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011051 var RSL_IE_Body chan_ident_ie;
11052 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11053 setverdict(fail, "RSL Channel Identification IE is absent");
11054 mtc.stop;
11055 }
11056
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011057 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011058
11059 /* Then expect the Immediate Assignment, after we ACKed the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011060 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011061
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011062 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11063 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011064
11065 /* Check that the lchan is working */
11066 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011067 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011068
11069 var BSSAP_N_CONNECT_ind rx_c_ind;
11070 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011071 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011072 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11073
11074 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011075 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011076 f_shutdown_helper();
11077}
11078
11079testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
11080 var RSL_Message chan_act;
11081 var RSL_Message imm_ass;
11082
11083 f_init(1, false);
11084 f_sleep(1.0);
11085
11086 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11087
11088 /* RA containing reason=LU */
11089 var GsmFrameNumber fn := 2342;
11090 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011091 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011092
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011093 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011094 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011095 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011096 var RSL_IE_Body chan_ident_ie;
11097 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11098 setverdict(fail, "RSL Channel Identification IE is absent");
11099 mtc.stop;
11100 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011101
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011102 /* (set bts 0 cfg back to default) */
11103 f_vty_set_imm_ass(BSCVTY);
11104
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011105 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011106 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011107 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11108 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011109
11110 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011111 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011112
11113 /* Check that the lchan is working */
11114 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011115 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011116
11117 var BSSAP_N_CONNECT_ind rx_c_ind;
11118 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011119 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011120 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11121
11122 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011123 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011124 f_shutdown_helper();
11125}
11126
Neels Hofmeyr23158742021-09-07 19:08:07 +020011127testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
11128 var RSL_Message chan_act;
11129 var RSL_Message imm_ass;
11130
11131 f_init(1, false);
11132 f_sleep(1.0);
11133
11134 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11135
11136 /* RA containing reason=LU */
11137 var GsmFrameNumber fn := 2342;
11138 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011139 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011140
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011141 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011142 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011143 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr23158742021-09-07 19:08:07 +020011144 var RSL_IE_Body chan_ident_ie;
11145 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11146 setverdict(fail, "RSL Channel Identification IE is absent");
11147 mtc.stop;
11148 }
11149
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011150 /* (set bts 0 cfg back to default) */
11151 f_vty_set_imm_ass(BSCVTY);
11152
Neels Hofmeyr23158742021-09-07 19:08:07 +020011153 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011154 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011155 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11156 chan_ident_ie.chan_ident.ch_desc.v.tsc);
11157
11158 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011159 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011160
11161 /* Check that the lchan is working */
11162 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011163 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011164
11165 var BSSAP_N_CONNECT_ind rx_c_ind;
11166 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011167 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020011168 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11169
11170 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011171 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020011172 f_shutdown_helper();
11173}
11174
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011175testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
11176 /* change Timeslot 6 before f_init() starts RSL */
11177 f_init_vty();
11178 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11179 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11180
11181 f_init(1, false);
11182 f_sleep(1.0);
11183
11184 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11185 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011186 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11187 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011188
11189 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11190 f_ts_set_chcomb(0, 0, 6, "PDCH");
11191
11192 /* block all static timeslots so that the dyn TS will be used */
11193 f_disable_all_tch_f();
11194 f_disable_all_tch_h();
11195 f_disable_all_sdcch();
11196
11197 var RSL_Message chan_act;
11198 var RSL_Message imm_ass;
11199
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011200 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11201
11202 /* RA containing reason=LU */
11203 var GsmFrameNumber fn := 2342;
11204 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011205 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011206
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011207 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011208 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
11209 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011210
11211 /* Now activation as SDCCH8 */
11212 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011213 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011214
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011215 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011216 var RSL_IE_Body chan_ident_ie;
11217 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11218 setverdict(fail, "RSL Channel Identification IE is absent");
11219 mtc.stop;
11220 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011221
11222 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011223 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011224 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11225 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011226
11227 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011228 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011229
11230 /* Check that the lchan is working */
11231 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011232 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011233
11234 var BSSAP_N_CONNECT_ind rx_c_ind;
11235 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011236 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011237 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11238
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011239 /* (set bts 0 cfg back to default) */
11240 f_vty_set_imm_ass(BSCVTY);
11241
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011242 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011243 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011244 f_shutdown_helper();
11245}
11246
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011247testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
11248 /* change Timeslot 6 before f_init() starts RSL */
11249 f_init_vty();
11250 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11251 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11252
11253 f_init(1, false);
11254 f_sleep(1.0);
11255
11256 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11257 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011258 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11259 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011260
11261 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11262 f_ts_set_chcomb(0, 0, 6, "PDCH");
11263
11264 /* block all static timeslots so that the dyn TS will be used */
11265 f_disable_all_tch_f();
11266 f_disable_all_tch_h();
11267 f_disable_all_sdcch();
11268
11269 var RSL_Message chan_act;
11270 var RSL_Message imm_ass;
11271
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011272 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11273
11274 /* RA containing reason=LU */
11275 var GsmFrameNumber fn := 2342;
11276 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011277 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011278
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011279 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011280 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011281
11282 /* And already the Immediate Assignment even before the PDCH Deact ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011283 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011284
11285 /* continue the Osmo style PDCH Deact (usual chan rel) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011286 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011287
11288 /* Now activation as SDCCH8 */
11289 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011290 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011291
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011292 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011293 var RSL_IE_Body chan_ident_ie;
11294 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11295 setverdict(fail, "RSL Channel Identification IE is absent");
11296 mtc.stop;
11297 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011298 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011299
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011300 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11301 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011302
11303 /* Check that the lchan is working */
11304 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011305 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011306
11307 var BSSAP_N_CONNECT_ind rx_c_ind;
11308 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011309 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011310 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11311
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011312 /* (set bts 0 cfg back to default) */
11313 f_vty_set_imm_ass(BSCVTY);
11314
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011315 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011316 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011317 f_shutdown_helper();
11318}
11319
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011320/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11321testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11322 var MSC_ConnHdlr vc_conn;
11323
11324 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11325 f_sleep(1.0);
11326
11327 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11328 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11329 "0,0,operational,unlocked,on,rsl-up;" &
11330 "1,0,operational,unlocked,on,rsl-up;" &
11331 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011332 "2,1,operational,unlocked,on,rsl-down;" &
11333 "2,2,operational,unlocked,on,rsl-down;" &
11334 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011335 "3,0,inoperational,locked,on,rsl-down;");
11336
11337 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11338 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11339 /* give it a moment to settle the FSM status */
11340 f_sleep(1.0);
11341
11342 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11343 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11344 * of "off"? But that's for a future patch if at all. */
11345 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11346 "0,0,operational,unlocked,on,rsl-up;" &
11347 "1,0,operational,locked,on,rsl-up;" &
11348 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011349 "2,1,operational,unlocked,on,rsl-down;" &
11350 "2,2,operational,unlocked,on,rsl-down;" &
11351 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011352 "3,0,inoperational,locked,on,rsl-down;");
11353
11354 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11355 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11356 f_sleep(1.0);
11357 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11358 "0,0,operational,unlocked,on,rsl-up;" &
11359 "1,0,operational,locked,on,rsl-up;" &
11360 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011361 "2,1,operational,unlocked,on,rsl-down;" &
11362 "2,2,operational,unlocked,on,rsl-down;" &
11363 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011364 "3,0,inoperational,locked,on,rsl-down;");
11365
11366 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11367 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11368 f_sleep(1.0);
11369 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11370 "0,0,operational,unlocked,on,rsl-up;" &
11371 "1,0,operational,unlocked,on,rsl-up;" &
11372 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011373 "2,1,operational,unlocked,on,rsl-down;" &
11374 "2,2,operational,unlocked,on,rsl-down;" &
11375 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011376 "3,0,inoperational,locked,on,rsl-down;");
11377
11378 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11379 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11380 f_sleep(1.0);
11381 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11382 "0,0,operational,unlocked,on,rsl-up;" &
11383 "1,0,operational,unlocked,on,rsl-up;" &
11384 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011385 "2,1,operational,unlocked,on,rsl-down;" &
11386 "2,2,operational,unlocked,on,rsl-down;" &
11387 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011388 "3,0,inoperational,locked,on,rsl-down;");
11389
11390 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11391 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11392 f_sleep(1.0);
11393 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11394 "0,0,operational,unlocked,on,rsl-up;" &
11395 "1,0,operational,unlocked,on,rsl-up;" &
11396 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011397 "2,1,operational,unlocked,on,rsl-down;" &
11398 "2,2,operational,unlocked,on,rsl-down;" &
11399 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011400 "3,0,inoperational,locked,on,rsl-down;");
11401
11402 f_shutdown_helper();
11403}
11404
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011405const CounterNameVals counternames_cm_serv_rej := {
11406 { "cm_serv_rej", 0 },
11407 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11408 { "cm_serv_rej:illegal_ms", 0 },
11409 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11410 { "cm_serv_rej:imei_not_accepted", 0 },
11411 { "cm_serv_rej:illegal_me", 0 },
11412 { "cm_serv_rej:plmn_not_allowed", 0 },
11413 { "cm_serv_rej:loc_not_allowed", 0 },
11414 { "cm_serv_rej:roaming_not_allowed", 0 },
11415 { "cm_serv_rej:network_failure", 0 },
11416 { "cm_serv_rej:synch_failure", 0 },
11417 { "cm_serv_rej:congestion", 0 },
11418 { "cm_serv_rej:srv_opt_not_supported", 0 },
11419 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11420 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11421 { "cm_serv_rej:call_can_not_be_identified", 0 },
11422 { "cm_serv_rej:incorrect_message", 0 },
11423 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11424 { "cm_serv_rej:msg_type_not_implemented", 0 },
11425 { "cm_serv_rej:msg_type_not_compatible", 0 },
11426 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11427 { "cm_serv_rej:condtional_ie_error", 0 },
11428 { "cm_serv_rej:msg_not_compatible", 0 },
11429 { "cm_serv_rej:protocol_error", 0 },
11430 { "cm_serv_rej:retry_in_new_cell", 0 }
11431};
11432
11433private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11434{
11435 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011436 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011437 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011438 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11439 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011440 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011441}
11442testcase TC_cm_serv_rej() runs on test_CT {
11443 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11444 var MSC_ConnHdlr vc_conn;
11445
11446 f_init(1, true);
11447 f_sleep(1.0);
11448
11449 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11450
11451 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11452 vc_conn.done;
11453
11454 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11455 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11456 f_ctrs_bts_verify();
11457
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011458 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011459 f_shutdown_helper();
11460}
11461
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011462/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11463 * Activ Ack (SYS#5627). */
11464private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11465 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011466
11467 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11468 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011469
11470 var BSSMAP_FIELD_CodecType codecType;
11471 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11472
11473 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11474
11475 /* First establish a signalling lchan */
11476 f_create_chan_and_exp();
11477 f_rslem_dchan_queue_enable();
11478
11479 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011480
11481 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011482 activate(as_Media_mgw(fail_on_dlcx := false));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011483
11484 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11485 f_rslem_register(0, chan_nr);
11486
11487 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11488 BSSAP.send(ass_cmd);
11489
11490
11491 /* Wait for the Channel Activ for the TCH channel */
11492 var ASP_RSL_Unitdata rx_rsl_ud;
11493 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11494
11495 /* make the original SDCCH disappear */
11496 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11497
11498 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11499 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11500
11501 interleave {
11502 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11503 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11504 }
11505
11506 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11507 BSSAP.receive(tr_BSSMAP_ClearComplete);
11508 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11509
11510 var MgcpCommand mgcp;
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011511 var MGCP_RecvFrom mrf;
11512 var template MgcpMessage msg_dlcx := { command := tr_DLCX };
11513 alt {
11514 [g_pars.aoip] MGCP.receive(tr_DLCX) -> value mgcp {
11515 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11516 }
11517 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
11518 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
11519 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
11520 }));
11521 }
11522 }
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011523
11524 f_sleep(0.5);
11525}
11526testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11527 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11528 var MSC_ConnHdlr vc_conn;
11529
11530 f_init(1, true);
11531 f_sleep(1.0);
11532
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011533 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11534 vc_conn.done;
11535
11536 f_shutdown_helper();
11537}
11538
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011539const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11540 { "all_allocated:sdcch", 0 },
11541 { "all_allocated:static_sdcch", 0 },
11542 { "all_allocated:tch", 0 },
11543 { "all_allocated:static_tch", 0 }
11544}
11545
11546private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11547{
11548 /* Make sure counters settle first */
11549 f_sleep(1.0);
11550
11551 /* Take a baseline of counters */
11552 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11553
11554 /* Elapse some time so that we see changes in counters, hopefully where expected */
11555 f_sleep(2.0);
11556
11557 /* Get new counters */
11558 var charstring_list all_changed := {};
11559 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11560 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11561
11562 /* Compare with expectations */
11563 var charstring_list all_expect_changed := {};
11564 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11565 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11566 }
11567 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11568}
11569
11570testcase TC_ratectr_all_available_allocated() runs on test_CT {
11571 var ASP_RSL_Unitdata rsl_ud;
11572 var integer i;
11573 var integer chreq_total, chreq_nochan;
11574
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011575 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011576 f_sleep(1.0);
11577
11578 /* Exhaust all dedicated SDCCH lchans.
11579 /* GSM 44.018 Table 9.1.8.2:
11580 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11581 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011582 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011583 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011584 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011585 }
11586
11587 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11588 * level.
11589 * All SDCCH are now occupied. */
11590 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11591
11592 /* Also fill up all remaining (TCH) channels */
11593 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011594 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011595 }
11596
11597 /* All TCH are now also occupied */
11598 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11599 "all_allocated:tch", "all_allocated:static_tch"});
11600
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011601 /* Clean up SDCCH lchans */
11602 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11603 f_perform_clear_test_ct(chan_cleanup[i]);
11604 }
11605
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011606 f_shutdown_helper();
11607}
11608
11609testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11610 var ASP_RSL_Unitdata rsl_ud;
11611 var integer i;
11612 var integer chreq_total, chreq_nochan;
11613
11614 f_init_vty();
11615 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11616 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11617 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11618
11619 f_init(1, guard_timeout := 60.0);
11620 f_sleep(1.0);
11621
11622 /* The dyn TS wants to activate PDCH mode, ACK that. */
11623 var RslChannelNr chan_nr;
11624 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011625 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11626 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011627
11628 /* Exhaust all dedicated SDCCH lchans.
11629 /* GSM 44.018 Table 9.1.8.2:
11630 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11631 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011632 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011633 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011634 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011635 }
11636
11637 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11638 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11639 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11640
11641 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11642 * Will release them later, so remember all the DchanTuples. */
11643 var DchanTuples dyn_sddch := {};
11644 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11645
11646 /* Also occupy the seven other SDCCH of the dyn TS */
11647 for (i := 0; i < 7; i := i+1) {
11648 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11649 }
11650
11651 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11652 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11653
11654 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11655 for (i := 0; i < 5; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011656 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011657 }
11658
11659 /* All TCH lchans are now also occupied, both static and dynamic */
11660 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11661 "all_allocated:tch", "all_allocated:static_tch"});
11662
11663 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11664 * incrementing. */
11665 var BssmapCause cause := 0;
11666 var DchanTuple dt := dyn_sddch[0];
11667 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011668 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011669
11670 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11671 * count as occupied, so those still both increment. */
11672 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11673 "all_allocated:tch", "all_allocated:static_tch"});
11674
11675 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11676 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11677 dt := dyn_sddch[i];
11678 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011679 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011680 }
11681
11682 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11683 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011684 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11685 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011686
11687 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11688 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11689
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011690 /* Clean up SDCCH lchans */
11691 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11692 f_perform_clear_test_ct(chan_cleanup[i]);
11693 }
11694
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011695 /* clean up config */
11696 f_ts_reset_chcomb(0);
11697
11698 f_shutdown_helper();
11699}
11700
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011701private function f_TC_chan_alloc_algo(DchanTuple dt, BtsTrxIdx idx)
11702runs on test_CT {
11703 /* MSC sends an Assignment Request */
11704 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11705 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11706 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11707 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
11708
11709 /* Expect the BSC to allocate a TCH channel on the given BTS/TRX */
11710 var RSL_Message rsl_chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
11711 /* Send CHAN ACT NACK, so that the requested TCH channel becomes BORKEN */
11712 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(rsl_chan_act.ies[0].body.chan_nr, RSL_ERR_EQUIPMENT_FAIL), idx);
11713 /* Expect to receive an Assignment Failure */
11714 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail));
11715}
11716
11717testcase TC_chan_alloc_algo_ascending() runs on test_CT {
11718 /* We need to access BTS2, which has 4 TRXs */
11719 f_init(nr_bts := 3);
11720
11721 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011722 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011723
11724 f_vty_enter_cfg_bts(BSCVTY, 2);
11725 f_vty_transceive(BSCVTY, "channel allocator ascending");
11726 f_vty_transceive(BSCVTY, "end");
11727
11728 /* Expect the BSC to allocate 4 x TCH/F channels on BTS2/TRX0 */
11729 for (var integer i := 0; i < 4; i := i + 1) {
11730 var DchanTuple dt := f_est_dchan('23'O, 23, '00000000'O, {2, 0});
11731 f_TC_chan_alloc_algo(dt, {2, 0});
11732 f_perform_clear_test_ct(dt);
11733 }
11734
11735 /* At this point all 4 x TCH/F channels are BORKEN, but they will be
11736 * resurrected upon the A-bis/OML link re-establishment. */
11737 f_shutdown_helper();
11738}
11739
11740testcase TC_chan_alloc_algo_descending() runs on test_CT {
11741 /* We need to access BTS2, which has 4 TRXs */
11742 f_init(nr_bts := 3);
11743
11744 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011745 vc_MGCP[0].stop;
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011746
11747 f_vty_enter_cfg_bts(BSCVTY, 2);
11748 f_vty_transceive(BSCVTY, "channel allocator descending");
11749 f_vty_transceive(BSCVTY, "end");
11750
11751 /* Expect the BSC to allocate 5 x TCH/F channels on BTS2/TRX3 */
11752 for (var integer i := 0; i < 5; i := i + 1) {
11753 var DchanTuple dt := f_est_dchan('23'O, 23, '00000000'O, {2, 0});
11754 f_TC_chan_alloc_algo(dt, {2, 3});
11755 f_perform_clear_test_ct(dt);
11756 }
11757
11758 /* At this point all 5 x TCH/F channels are BORKEN, but they will be
11759 * resurrected upon the A-bis/OML link re-establishment. */
11760 f_shutdown_helper();
11761}
11762
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011763testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
11764 const BtsTrxIdx TRX0 := {2, 0};
11765 const BtsTrxIdx TRX3 := {2, 3};
11766
11767 /* We need to access BTS2, which has 4 TRXs */
11768 f_init(nr_bts := 3);
11769
11770 /* HACK: work around "Couldn't find Expect for CRCX" */
Pau Espin Pedrol3c630532022-10-20 19:00:11 +020011771 vc_MGCP[0].stop;
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011772
11773 f_vty_enter_cfg_bts(BSCVTY, 2);
11774 f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
11775 f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
11776 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
11777 f_vty_transceive(BSCVTY, "end");
11778
11779 var DchanTuple dt;
11780
11781 f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
11782 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11783 f_TC_chan_alloc_algo(dt, TRX0);
11784 f_perform_clear_test_ct(dt);
11785
11786 f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
11787 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11788 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11789 ts_RSL_IE_UplinkMeas(30, 0),
11790 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011791 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011792 f_TC_chan_alloc_algo(dt, TRX0);
11793 f_perform_clear_test_ct(dt);
11794
11795 f_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
11796 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11797 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11798 ts_RSL_IE_UplinkMeas(45, 0),
11799 ts_RSL_IE_BS_Power(0)), TRX0);
11800 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11801 ts_RSL_IE_UplinkMeas(48, 0),
11802 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011803 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011804 f_TC_chan_alloc_algo(dt, TRX0);
11805 f_perform_clear_test_ct(dt);
11806
11807 f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
11808 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11809 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11810 ts_RSL_IE_UplinkMeas(50, 0),
11811 ts_RSL_IE_BS_Power(0)), TRX0);
11812 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11813 ts_RSL_IE_UplinkMeas(58, 0),
11814 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011815 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011816 f_TC_chan_alloc_algo(dt, TRX3);
11817 f_perform_clear_test_ct(dt);
11818
11819 f_vty_enter_cfg_bts(BSCVTY, 2);
11820 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
11821 f_vty_transceive(BSCVTY, "end");
11822
11823 f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
11824 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11825 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11826 ts_RSL_IE_UplinkMeas(50, 0),
11827 ts_RSL_IE_BS_Power(0)), TRX0);
11828 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11829 ts_RSL_IE_UplinkMeas(58, 0),
11830 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011831 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011832 f_TC_chan_alloc_algo(dt, TRX0);
11833 f_perform_clear_test_ct(dt);
11834
11835 f_vty_enter_cfg_bts(BSCVTY, 2);
11836 f_vty_transceive(BSCVTY, "channel allocator ascending");
11837 f_vty_transceive(BSCVTY, "end");
11838
11839 /* At this point some TCH/F channels are BORKEN, but they will be
11840 * resurrected upon the A-bis/OML link re-establishment. */
11841 f_shutdown_helper();
11842}
11843
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020011844private function f_vty_mgw_enable(integer mgw_nr := 1) runs on test_CT {
11845 var rof_charstring cmds := {
11846 "remote-ip " & mp_test_ip,
11847 "remote-port " & int2str(2427 + mgw_nr)
11848 };
11849 f_vty_config3(BSCVTY, {"network", "mgw " & int2str(mgw_nr)}, cmds);
11850 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " reconnect")
11851}
11852private function f_vty_mgw_disable(integer mgw_nr := 1) runs on test_CT {
11853 f_vty_config3(BSCVTY, {"network"}, { "no mgw " &int2str(mgw_nr) });
11854}
11855private function f_vty_mgw_block(integer mgw_nr := 1, boolean blocked := true) runs on test_CT {
11856 var charstring arg;
11857 if (blocked) {
11858 arg := "block";
11859 } else {
11860 arg := "unblock";
11861 }
11862 f_vty_transceive(BSCVTY, "mgw " & int2str(mgw_nr) & " " & arg);
11863}
11864private const charstring COORD_CMD_ESTABLISHED := "COORD_CMD_ESTABLISHED";
11865private function f_TC_mgwpool_call_seq_1(charstring id) runs on MSC_ConnHdlr {
11866 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11867 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11868 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11869 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11870
11871 f_establish_fully(ass_cmd, exp_compl);
11872 COORD.send(COORD_CMD_ESTABLISHED);
11873
11874 COORD.receive(COORD_CMD_ESTABLISHED);
11875 f_perform_clear()
11876 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11877}
11878private function f_TC_mgwpool_call_seq_2(charstring id) runs on MSC_ConnHdlr {
11879 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11880 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11881 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11882 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11883
11884
11885 COORD.receive(COORD_CMD_ESTABLISHED);
11886 f_establish_fully(ass_cmd, exp_compl);
11887 COORD.send(COORD_CMD_ESTABLISHED);
11888
11889 f_perform_clear()
11890 f_create_mgcp_delete_ep(g_media.mgcp_ep);
11891}
11892/* Test load is spread around 2 available MGWs */
11893testcase TC_mgwpool_all_used() runs on test_CT {
11894 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11895 var MSC_ConnHdlr vc_conn1;
11896 pars1.mgwpool_idx := 0;
11897
11898 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11899 var MSC_ConnHdlr vc_conn2;
11900 pars2.mgwpool_idx := 1;
11901
11902 f_init(1, true, nr_mgw := 2);
11903 f_sleep(1.0);
11904
11905 f_vty_mgw_enable(1);
11906
11907 vc_conn1 := f_start_handler_create(pars1);
11908 vc_conn2 := f_start_handler_create(pars2);
11909 connect(vc_conn1:COORD, vc_conn2:COORD);
11910 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11911 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11912 vc_conn1.done;
11913 vc_conn2.done;
11914
11915 f_vty_mgw_disable(1);
11916
11917 f_shutdown_helper();
11918}
11919
11920/* Test blocked MGW in the pool are not selected */
11921testcase TC_mgwpool_blocked_not_used() runs on test_CT {
11922 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11923 var MSC_ConnHdlr vc_conn1;
11924 pars1.mgwpool_idx := 0;
11925
11926 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11927 var MSC_ConnHdlr vc_conn2;
11928 pars2.mgwpool_idx := 0; /* expect it in the first one, since the second will be blocked */
11929 pars2.media_nr := 2;
11930
11931 f_init(1, true, nr_mgw := 2);
11932 f_sleep(1.0);
11933
11934 f_vty_mgw_enable(1);
11935 f_vty_mgw_block(1, true);
11936
11937 vc_conn1 := f_start_handler_create(pars1);
11938 vc_conn2 := f_start_handler_create(pars2);
11939 connect(vc_conn1:COORD, vc_conn2:COORD);
11940 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11941 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11942 vc_conn1.done;
11943 vc_conn2.done;
11944
11945 f_vty_mgw_disable(1);
11946
11947 f_shutdown_helper();
11948}
11949
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020011950/* Test BTS pinning to an MGW is applied */
11951testcase TC_mgwpool_pin_bts() runs on test_CT {
11952 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
11953 var MSC_ConnHdlr vc_conn1;
11954 pars1.mgwpool_idx := 0;
11955
11956 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
11957 var MSC_ConnHdlr vc_conn2;
11958 pars2.mgwpool_idx := 0; /* expect it in the first one, since the BTS is pinned to the first MGW */
11959 pars2.media_nr := 2;
11960
11961 f_init(1, true, nr_mgw := 2);
11962 f_sleep(1.0);
11963
11964 f_vty_mgw_enable(1);
11965 f_vty_cfg_bts(BSCVTY, 0, { "mgw pool-target 0" });
11966
11967 vc_conn1 := f_start_handler_create(pars1);
11968 vc_conn2 := f_start_handler_create(pars2);
11969 connect(vc_conn1:COORD, vc_conn2:COORD);
11970 f_start_handler_run(vc_conn1, refers(f_TC_mgwpool_call_seq_1), pars1);
11971 f_start_handler_run(vc_conn2, refers(f_TC_mgwpool_call_seq_2), pars2);
11972 vc_conn1.done;
11973 vc_conn2.done;
11974
11975 f_vty_cfg_bts(BSCVTY, 0, { "no mgw pool-target" } );
Vadim Yanitskiy389d7e02022-10-25 17:44:05 +070011976 f_vty_mgw_disable(1);
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020011977
11978 f_shutdown_helper();
11979}
11980
Oliver Smithc9a5f532022-10-21 11:32:23 +020011981private function f_tc_ho_meas_rep_multi_band(charstring id) runs on MSC_ConnHdlr {
11982 g_pars := f_gen_test_hdlr_pars();
11983 var PDU_BSSAP ass_req := f_gen_ass_req();
11984 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11985 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11986 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
11987 f_establish_fully(ass_req, exp_compl);
11988
11989 /* Send a measurement report with bad rxlev except on 3rd entry. The
11990 * measurement report is divided into two sub lists, as described in
11991 * 3GPP TS 04.08 § 10.5.2.20. */
11992 var NcellReports neighbor_rep := {
11993 /* Sub list 1: same band */
Oliver Smitha6773042022-10-24 12:56:30 +020011994 { rxlev := 0, bcch_freq := 0, bsic := 12 }, /* ARFCN 800, band 1800, LAC 98 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020011995 /* Sub list 2: different band */
Oliver Smitha6773042022-10-24 12:56:30 +020011996 { rxlev := 0, bcch_freq := 1, bsic := 13 }, /* ARFCN 200, band 850, LAC 97 */
11997 { rxlev := 40, bcch_freq := 2, bsic := 14 }, /* ARFCN 1000, band 900, LAC 99 */
11998 { rxlev := 0, bcch_freq := 3, bsic := 11 } /* ARFCN 0, band 900, LAC 96 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020011999 };
12000 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
12001 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
12002 l3_mr, 0));
12003
12004 /* Expect a handover to the third entry. If the BSC parsed the report
Oliver Smitha6773042022-10-24 12:56:30 +020012005 * correctly, the third entry has LAC 99. */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012006 var template BSSMAP_FIELD_CellIdentificationList cid_list := {
Oliver Smitha6773042022-10-24 12:56:30 +020012007 cIl_LAC := { ts_BSSMAP_CI_LAC(99) }
Oliver Smithc9a5f532022-10-21 11:32:23 +020012008 };
12009 alt {
12010 [] BSSAP.receive(tr_BSSMAP_HandoverRequired(cid_list := cid_list)) {
12011 setverdict(pass);
12012 }
12013 [] BSSAP.receive(tr_BSSMAP_HandoverRequired()) {
12014 setverdict(fail, "Handover has unexpected LAC in Cell Identification List. The BSC probably"
12015 & " didn't parse the multi-band measurement report correctly.");
12016 }
12017 }
12018
12019 f_ho_out_of_this_bsc(skip_meas_rep := true);
12020}
12021testcase TC_ho_meas_rep_multi_band() runs on test_CT {
12022 /* Verify that the BSC parses the measurement report correctly when
12023 * neighbors in multiple bands are configured (OS#5717). See
12024 * gsm_arfcn2band_rc() in libosmocore src/gsm/gsm_utils.c for the
12025 * ARFCN -> band mapping. The MS is connected to band 1800. */
12026 var MSC_ConnHdlr vc_conn;
12027
12028 f_init_vty();
12029 f_bts_0_cfg(BSCVTY,
12030 {"neighbor-list mode automatic",
12031 "handover 1",
12032 "handover algorithm 2",
12033 "handover2 window rxlev averaging 1",
12034 "no neighbors",
12035 "neighbor lac 99 arfcn 1000 bsic any", /* band 900 */
12036 "neighbor lac 98 arfcn 800 bsic any", /* band 1800 */
12037 "neighbor lac 97 arfcn 200 bsic any", /* band 850 */
Oliver Smitha6773042022-10-24 12:56:30 +020012038 "neighbor lac 96 arfcn 0 bsic any"}); /* band 900 */
Oliver Smithc9a5f532022-10-21 11:32:23 +020012039 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
12040
12041 f_init(1, true);
12042 f_sleep(1.0);
12043
12044 f_ctrs_bsc_and_bts_handover_init();
12045
12046 vc_conn := f_start_handler(refers(f_tc_ho_meas_rep_multi_band));
12047 vc_conn.done;
12048
12049 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
12050 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
12051 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
12052 f_ctrs_bsc_and_bts_add(0, "handover:completed");
12053 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
12054 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
12055 f_ctrs_bsc_and_bts_verify();
12056 f_shutdown_helper(ho := true);
12057}
12058
Harald Welte28d943e2017-11-25 15:00:50 +010012059control {
Harald Welte898113b2018-01-31 18:32:21 +010012060 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010012061 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010012062 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020012063 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
12064 * these in the AoIP test suite. */
12065 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12066 execute( TC_stat_num_msc_connected_1() );
12067 execute( TC_stat_num_msc_connected_2() );
12068 execute( TC_stat_num_msc_connected_3() );
12069 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020012070 execute( TC_stat_num_bts_connected_1() );
12071 execute( TC_stat_num_bts_connected_2() );
12072 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010012073 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012074 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020012075 execute( TC_ctrl_location() );
12076 }
Harald Welte898113b2018-01-31 18:32:21 +010012077
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012078 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020012079 execute( TC_si2quater_2_earfcns() );
12080 execute( TC_si2quater_3_earfcns() );
12081 execute( TC_si2quater_4_earfcns() );
12082 execute( TC_si2quater_5_earfcns() );
12083 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020012084 execute( TC_si2quater_12_earfcns() );
12085 execute( TC_si2quater_23_earfcns() );
12086 execute( TC_si2quater_32_earfcns() );
12087 execute( TC_si2quater_33_earfcns() );
12088 execute( TC_si2quater_42_earfcns() );
12089 execute( TC_si2quater_48_earfcns() );
12090 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020012091 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020012092 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020012093
Harald Welte898113b2018-01-31 18:32:21 +010012094 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010012095 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010012096 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010012097 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020012098 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020012099 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010012100 execute( TC_chan_act_ack_est_ind_noreply() );
12101 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010012102 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010012103 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070012104 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010012105 execute( TC_chan_rel_rll_rel_ind() );
12106 execute( TC_chan_rel_conn_fail() );
12107 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020012108 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
12109 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010012110 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010012111 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020012112 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010012113 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010012114 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020012115 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010012116
Harald Weltecfe2c962017-12-15 12:09:32 +010012117 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010012118
12119 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010012120 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010012121 execute( TC_assignment_csd() );
12122 execute( TC_assignment_ctm() );
12123 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012124 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12125 execute( TC_assignment_aoip_tla_v6() );
12126 }
Harald Welte235ebf12017-12-15 14:18:16 +010012127 execute( TC_assignment_fr_a5_0() );
12128 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012129 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020012130 execute( TC_assignment_fr_a5_1_codec_missing() );
12131 }
Harald Welte235ebf12017-12-15 14:18:16 +010012132 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020012133 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020012134 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020012135 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012136 execute( TC_ciph_mode_a5_0() );
12137 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020012138 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020012139 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020012140 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020012141 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010012142
Harald Welte60aa5762018-03-21 19:33:13 +010012143 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020012144 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010012145 execute( TC_assignment_codec_hr() );
12146 execute( TC_assignment_codec_efr() );
12147 execute( TC_assignment_codec_amr_f() );
12148 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012149
Neels Hofmeyrf246a922020-05-13 02:27:10 +020012150 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010012151 execute( TC_assignment_codec_amr_f_S1() );
12152 execute( TC_assignment_codec_amr_h_S1() );
12153 execute( TC_assignment_codec_amr_f_S124() );
12154 execute( TC_assignment_codec_amr_h_S124() );
12155 execute( TC_assignment_codec_amr_f_S0() );
12156 execute( TC_assignment_codec_amr_f_S02() );
12157 execute( TC_assignment_codec_amr_f_S024() );
12158 execute( TC_assignment_codec_amr_f_S0247() );
12159 execute( TC_assignment_codec_amr_h_S0() );
12160 execute( TC_assignment_codec_amr_h_S02() );
12161 execute( TC_assignment_codec_amr_h_S024() );
12162 execute( TC_assignment_codec_amr_h_S0247() );
12163 execute( TC_assignment_codec_amr_f_S01234567() );
12164 execute( TC_assignment_codec_amr_f_S0234567() );
12165 execute( TC_assignment_codec_amr_f_zero() );
12166 execute( TC_assignment_codec_amr_f_unsupp() );
12167 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000012168 execute( TC_assignment_codec_amr_f_start_mode_auto() );
12169 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000012170 execute( TC_assignment_codec_amr_f_start_mode_4() );
12171 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000012172 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010012173 }
Harald Welte60aa5762018-03-21 19:33:13 +010012174
Philipp Maierac09bfc2019-01-08 13:41:39 +010012175 execute( TC_assignment_codec_fr_exhausted_req_hr() );
12176 execute( TC_assignment_codec_fr_exhausted_req_fr() );
12177 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
12178 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
12179 execute( TC_assignment_codec_hr_exhausted_req_fr() );
12180 execute( TC_assignment_codec_hr_exhausted_req_hr() );
12181 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
12182 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
12183 execute( TC_assignment_codec_req_hr_fr() );
12184 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020012185 execute( TC_assignment_sdcch_exhausted_req_signalling() );
12186 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
12187 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010012188
Pau Espin Pedrolcd6077f2022-09-19 20:23:37 +020012189 execute( TC_assignment_codec_hr_osmux_on() );
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020012190 execute( TC_assignment_osmux() );
Pau Espin Pedrol29c6dfb2022-08-08 18:37:56 +020012191 execute( TC_assignment_osmux_cn() );
12192 execute( TC_assignment_osmux_bts() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020012193
Harald Welte898113b2018-01-31 18:32:21 +010012194 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010012195 execute( TC_rll_est_ind_inact_lchan() );
12196 execute( TC_rll_est_ind_inval_sapi1() );
12197 execute( TC_rll_est_ind_inval_sapi3() );
12198 execute( TC_rll_est_ind_inval_sacch() );
12199
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070012200 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
12201 execute( TC_tch_dlci_link_id_sapi() );
12202
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012203 /* SAPI N Reject triggered by RLL establishment failures */
12204 execute( TC_rll_rel_ind_sapi_n_reject() );
12205 execute( TC_rll_err_ind_sapi_n_reject() );
12206 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070012207 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070012208
Harald Welte898113b2018-01-31 18:32:21 +010012209 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010012210 execute( TC_paging_imsi_nochan() );
12211 execute( TC_paging_tmsi_nochan() );
12212 execute( TC_paging_tmsi_any() );
12213 execute( TC_paging_tmsi_sdcch() );
12214 execute( TC_paging_tmsi_tch_f() );
12215 execute( TC_paging_tmsi_tch_hf() );
12216 execute( TC_paging_imsi_nochan_cgi() );
12217 execute( TC_paging_imsi_nochan_lac_ci() );
12218 execute( TC_paging_imsi_nochan_ci() );
12219 execute( TC_paging_imsi_nochan_lai() );
12220 execute( TC_paging_imsi_nochan_lac() );
12221 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010012222 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
12223 execute( TC_paging_imsi_nochan_rnc() );
12224 execute( TC_paging_imsi_nochan_lac_rnc() );
12225 execute( TC_paging_imsi_nochan_lacs() );
12226 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010012227 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010012228 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010012229 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010012230 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010012231 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020012232 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020012233 execute( TC_paging_450req_no_paging_load_ind() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010012234
12235 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010012236 execute( TC_rsl_unknown_unit_id() );
12237
12238 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012239
12240 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020012241 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010012242 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010012243 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010012244 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010012245 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010012246 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012247
Harald Welte261af4b2018-02-12 21:20:39 +010012248 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020012249 execute( TC_ho_int_a5_0() );
12250 execute( TC_ho_int_a5_1() );
12251 execute( TC_ho_int_a5_3() );
12252 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000012253 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012254
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012255 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020012256 execute( TC_ho_out_fail_no_msc_response() );
12257 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020012258 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012259
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010012260 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020012261 execute( TC_ho_into_this_bsc_a5_0() );
12262 execute( TC_ho_into_this_bsc_a5_1() );
12263 execute( TC_ho_into_this_bsc_a5_3() );
12264 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010012265 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
12266 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010012267 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020012268 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12269 execute( TC_ho_into_this_bsc_tla_v6() );
12270 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020012271 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030012272 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010012273 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020012274 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020012275 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
12276 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010012277 execute( TC_ho_in_fail_msc_clears() );
12278 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
12279 execute( TC_ho_in_fail_no_detect() );
12280 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010012281 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012282
Neels Hofmeyr91401012019-07-11 00:42:35 +020012283 execute( TC_ho_neighbor_config_1() );
12284 execute( TC_ho_neighbor_config_2() );
12285 execute( TC_ho_neighbor_config_3() );
12286 execute( TC_ho_neighbor_config_4() );
12287 execute( TC_ho_neighbor_config_5() );
12288 execute( TC_ho_neighbor_config_6() );
12289 execute( TC_ho_neighbor_config_7() );
12290
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010012291 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010012292 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010012293 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020012294
12295 execute( TC_dyn_pdch_ipa_act_deact() );
12296 execute( TC_dyn_pdch_ipa_act_nack() );
12297 execute( TC_dyn_pdch_osmo_act_deact() );
12298 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010012299 execute( TC_dyn_ts_sdcch8_act_deact() );
12300 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
12301 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
12302 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012303
Stefan Sperling0796a822018-10-05 13:01:39 +020012304 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020012305 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020012306
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010012307 /* Power control related */
12308 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020012309 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020012310
12311 /* MSC pooling */
12312 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
12313 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
12314 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
12315 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
12316 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
12317 execute( TC_mscpool_L3Compl_on_1_msc() );
12318 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
12319 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
12320 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
12321 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
12322 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
12323 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
12324 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
12325 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
12326 execute( TC_mscpool_paging_and_response_imsi() );
12327 execute( TC_mscpool_paging_and_response_tmsi() );
12328 execute( TC_mscpool_no_allow_attach_round_robin() );
12329 execute( TC_mscpool_no_allow_attach_valid_nri() );
12330 }
12331
Harald Welte99f3ca02018-06-14 13:40:29 +020012332 execute( TC_early_conn_fail() );
12333 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020012334 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020012335
Philipp Maier783681c2020-07-16 16:47:06 +020012336 /* Emergency call handling (deny / allow) */
12337 execute( TC_assignment_emerg_setup_allow() );
12338 execute( TC_assignment_emerg_setup_deny_msc() );
12339 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020012340 execute( TC_emerg_premption() );
12341
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070012342 /* Frequency hopping parameters handling */
12343 execute( TC_fh_params_chan_activ() );
12344 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070012345 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070012346 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070012347 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012348
12349 if (mp_enable_lcs_tests) {
12350 execute( TC_lcs_loc_req_for_active_ms() );
12351 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
12352 execute( TC_lcs_loc_req_for_idle_ms() );
12353 execute( TC_lcs_loc_req_no_subscriber() );
12354 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
12355 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
12356 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
12357 execute( TC_cm_service_during_lcs_loc_req() );
12358 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020012359 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020012360 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() );
12361 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012362 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000012363
12364 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000012365
12366 execute( TC_refuse_chan_act_to_vamos() );
12367 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000012368
12369 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020012370
12371 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020012372
12373 execute( TC_imm_ass_post_chan_ack() );
12374 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020012375 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020012376 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020012377 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020012378
12379 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012380
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020012381 execute( TC_ratectr_all_available_allocated() );
12382 execute( TC_ratectr_all_available_allocated_dyn() );
12383
Neels Hofmeyrb7581872021-11-07 14:02:49 +010012384 execute( TC_cm_serv_rej() );
12385
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012386 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012387
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012388 /* Channel allocator */
12389 execute( TC_chan_alloc_algo_ascending() );
12390 execute( TC_chan_alloc_algo_descending() );
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012391 execute( TC_chan_alloc_algo_ass_dynamic() );
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012392
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012393 /* MGW pool */
12394 /* TODO: this conditional canbe dropped once osmo-bsc >1.10.0 is released: */
12395 if (Misc_Helpers.f_osmo_repo_is("nightly")) {
12396 execute( TC_mgwpool_all_used() );
12397 execute( TC_mgwpool_blocked_not_used() );
Pau Espin Pedrol3f41e322022-10-20 19:34:43 +020012398 execute( TC_mgwpool_pin_bts() );
Pau Espin Pedrold2355e82022-10-20 19:34:43 +020012399 }
12400
Oliver Smithc9a5f532022-10-21 11:32:23 +020012401 execute( TC_ho_meas_rep_multi_band() );
12402
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012403 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
12404 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
12405 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010012406}
12407
12408}