blob: 46fb952817deb641e5e95bbfe09ff39b370587cb [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;
Harald Welteae026692017-12-09 01:03:01 +010084const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010085
Harald Welte799c97b2017-12-14 17:50:30 +010086/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020087const integer NUM_TCHH_PER_BTS := 2;
88const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020089const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010090
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060091friend type record BtsTrxIdx {
92 uint8_t bts,
93 uint8_t trx
94}
95
96private type record BtsParams {
97 integer trx_num,
98 integer tsc
99}
100
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200101/* Default Training Sequence Code expected for bts[i]:
102 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
103 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
104 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
105 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
106 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600107private const BtsParams c_BtsParams[NUM_BTS_CFG] := {
108 /* BTS0 */ { trx_num := 1, tsc := 2 },
109 /* BTS1 */ { trx_num := 1, tsc := 3 },
Vadim Yanitskiy7a3d2932022-05-29 20:37:46 +0600110 /* BTS2 */ { trx_num := 4, tsc := 4 },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600111 /* BTS3 */ { trx_num := 1, tsc := 4 }
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200112}
Harald Welte4003d112017-12-09 22:35:39 +0100113
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +0200114private const RSL_IE_Body mr_conf_amr_5_90 :=
115 valueof(RSL_IE_Body:{multirate_cfg := ts_RSL_MultirateCfg(true, 0, '00000100'B /* 5,90k */)});
116
Harald Welte21b46bd2017-12-17 19:46:32 +0100117/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100118type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100119 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100120 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100121}
122
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200123/* Default list of counters for an 'msc' entity. */
124const CounterNameVals counternames_msc_mscpool := {
125 { "mscpool:subscr:new", 0 },
126 { "mscpool:subscr:known", 0 },
127 { "mscpool:subscr:reattach", 0 },
128 { "mscpool:subscr:attach_lost", 0 },
129 { "mscpool:subscr:paged", 0 }
130};
131
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000132/* List of global mscpool counters, not related to a specific 'msc' entity. */
133const CounterNameVals counternames_bsc_mscpool := {
134 { "mscpool:subscr:no_msc", 0 }
135};
136
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000137/* Default list of counters for 'bsc' and 'bts' entities. */
138const CounterNameVals counternames_bsc_bts_handover := {
139 { "assignment:attempted", 0 },
140 { "assignment:completed", 0 },
141 { "assignment:stopped", 0 },
142 { "assignment:no_channel", 0 },
143 { "assignment:timeout", 0 },
144 { "assignment:failed", 0 },
145 { "assignment:error", 0 },
146
147 { "handover:attempted", 0 },
148 { "handover:completed", 0 },
149 { "handover:stopped", 0 },
150 { "handover:no_channel", 0 },
151 { "handover:timeout", 0 },
152 { "handover:failed", 0 },
153 { "handover:error", 0 },
154
155 { "intra_cell_ho:attempted", 0 },
156 { "intra_cell_ho:completed", 0 },
157 { "intra_cell_ho:stopped", 0 },
158 { "intra_cell_ho:no_channel", 0 },
159 { "intra_cell_ho:timeout", 0 },
160 { "intra_cell_ho:failed", 0 },
161 { "intra_cell_ho:error", 0 },
162
163 { "intra_bsc_ho:attempted", 0 },
164 { "intra_bsc_ho:completed", 0 },
165 { "intra_bsc_ho:stopped", 0 },
166 { "intra_bsc_ho:no_channel", 0 },
167 { "intra_bsc_ho:timeout", 0 },
168 { "intra_bsc_ho:failed", 0 },
169 { "intra_bsc_ho:error", 0 },
170
171 { "interbsc_ho_out:attempted", 0 },
172 { "interbsc_ho_out:completed", 0 },
173 { "interbsc_ho_out:stopped", 0 },
174 { "interbsc_ho_out:timeout", 0 },
175 { "interbsc_ho_out:failed", 0 },
176 { "interbsc_ho_out:error", 0 },
177
178 { "interbsc_ho_in:attempted", 0 },
179 { "interbsc_ho_in:completed", 0 },
180 { "interbsc_ho_in:stopped", 0 },
181 { "interbsc_ho_in:no_channel", 0 },
182 { "interbsc_ho_in:timeout", 0 },
183 { "interbsc_ho_in:failed", 0 },
184 { "interbsc_ho_in:error", 0 }
185};
186
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100187const CounterNameVals counternames_bts_handover := {
188 { "incoming_intra_bsc_ho:attempted", 0 },
189 { "incoming_intra_bsc_ho:completed", 0 },
190 { "incoming_intra_bsc_ho:stopped", 0 },
191 { "incoming_intra_bsc_ho:no_channel", 0 },
192 { "incoming_intra_bsc_ho:timeout", 0 },
193 { "incoming_intra_bsc_ho:failed", 0 },
194 { "incoming_intra_bsc_ho:error", 0 }
195};
196
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200197/* Set of all System Information received during one RSL port's startup.
198 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
199 * broadcast that SI type. That will be reflected as 'omit' here.
200 */
201type record SystemInformationConfig {
202 SystemInformationType1 si1 optional,
203 SystemInformationType2 si2 optional,
204 SystemInformationType2bis si2bis optional,
205 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200206 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200207 SystemInformationType3 si3 optional,
208 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100209 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200210 SystemInformationType5 si5 optional,
211 SystemInformationType5bis si5bis optional,
212 SystemInformationType5ter si5ter optional,
213 SystemInformationType6 si6 optional
214};
215
216const SystemInformationConfig SystemInformationConfig_omit := {
217 si1 := omit,
218 si2 := omit,
219 si2bis := omit,
220 si2ter := omit,
221 si2quater := omit,
222 si3 := omit,
223 si4 := omit,
224 si13 := omit,
225 si5 := omit,
226 si5bis := omit,
227 si5ter := omit,
228 si6 := omit
229};
230
231/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
232template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
233 template uint3_t meas_bw := 3)
234:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
235 meas_bw_presence := '1'B,
236 meas_bw := meas_bw);
237
238/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200239template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200240 template uint3_t prio := 3,
241 template (present) uint5_t thresh_high := 20,
242 template uint5_t thresh_low := 10,
243 template uint5_t qrxlevmin := 22)
244:= tr_EUTRAN_NeighbourCells(
245 cell_desc_list := cell_desc_list,
246 prio_presence := '1'B,
247 prio := prio,
248 thresh_high := thresh_high,
249 thresh_low_presence := '1'B,
250 thresh_low := thresh_low,
251 qrxlevmin_presence := '1'B,
252 qrxlevmin := qrxlevmin);
253
254template SystemInformationConfig SystemInformationConfig_default := {
255 si1 := {
256 cell_chan_desc := '8FB38000000000000000000000000000'O,
257 rach_control := {
258 max_retrans := RACH_MAX_RETRANS_7,
259 tx_integer := '1001'B,
260 cell_barr_access := false,
261 re_not_allowed := true,
262 acc := '0000010000000000'B
263 },
264 rest_octets := ?
265 },
266 si2 := {
267 bcch_freq_list := '00000000000000000000000000000000'O,
268 ncc_permitted := '11111111'B,
269 rach_control := {
270 max_retrans := RACH_MAX_RETRANS_7,
271 tx_integer := '1001'B,
272 cell_barr_access := false,
273 re_not_allowed := true,
274 acc := '0000010000000000'B
275 }
276 },
277 si2bis := omit,
278 si2ter := {
279 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
280 rest_octets := ?
281 },
282 si2quater := {
283 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
284 },
285 si3 := {
286 cell_id := 0,
287 lai := {
288 mcc_mnc := '001F01'H,
289 lac := 1
290 },
291 ctrl_chan_desc := {
292 msc_r99 := true,
293 att := true,
294 bs_ag_blks_res := 1,
295 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
296 si22ind := false,
297 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
298 spare := '00'B,
299 bs_pa_mfrms := 3,
300 t3212 := 30
301 },
302 cell_options := {
303 dn_ind := false,
304 pwrc := false,
305 dtx := MS_SHALL_USE_UL_DTX,
306 radio_link_tout_div4 := 7
307 },
308 cell_sel_par := {
309 cell_resel_hyst_2dB := 2,
310 ms_txpwr_max_cch := 7,
311 acs := '0'B,
312 neci := true,
313 rxlev_access_min := 0
314 },
315 rach_control := {
316 max_retrans := RACH_MAX_RETRANS_7,
317 tx_integer := '1001'B,
318 cell_barr_access := false,
319 re_not_allowed := true,
320 acc := '0000010000000000'B
321 },
322 rest_octets := {
323 sel_params := {
324 presence := '0'B,
325 params := omit
326 },
327 pwr_offset := {
328 presence := '0'B,
329 offset := omit
330 },
331 si_2ter_ind := '1'B,
332 early_cm_ind := '0'B,
333 sched_where := {
334 presence := '0'B,
335 where := omit
336 },
337 gprs_ind := {
338 presence := '1'B,
339 ind := {
340 ra_colour := 0,
341 si13_pos := '0'B
342 }
343 },
344 umts_early_cm_ind := '1'B,
345 si2_quater_ind := {
346 presence := '1'B,
347 ind := '0'B
348 },
349 iu_mode_ind := omit,
350 si21_ind := {
351 presence := '0'B,
352 pos := omit
353 }
354 }
355 },
356 si4 := {
357 lai := {
358 mcc_mnc := '001F01'H,
359 lac := 1
360 },
361 cell_sel_par := {
362 cell_resel_hyst_2dB := 2,
363 ms_txpwr_max_cch := 7,
364 acs := '0'B,
365 neci := true,
366 rxlev_access_min := 0
367 },
368 rach_control := {
369 max_retrans := RACH_MAX_RETRANS_7,
370 tx_integer := '1001'B,
371 cell_barr_access := false,
372 re_not_allowed := true,
373 acc := '0000010000000000'B
374 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200375 cbch_chan_desc := {
376 iei := '64'O,
377 v := {
378 chan_nr := {
379 u := {
380 sdcch4 := {
381 tag := '001'B,
382 sub_chan := 2
383 }
384 },
385 tn := 0
386 },
387 tsc := 2,
388 h := false,
389 arfcn := 871,
390 maio_hsn := omit
391 }
392 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200393 cbch_mobile_alloc := omit,
394 rest_octets := {
395 sel_params := {
396 presence := '0'B,
397 params := omit
398 },
399 pwr_offset := {
400 presence := '0'B,
401 offset := omit
402 },
403 gprs_ind := {
404 presence := '1'B,
405 ind := {
406 ra_colour := 0,
407 si13_pos := '0'B
408 }
409 },
410 s_presence := '0'B,
411 s := omit
412 }
413 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100414 si13 := {
415 rest_octets := {
416 presence := '1'B,
417 bcch_change_mark := ?,
418 si_change_field := '0000'B,
419 presence2 := '0'B,
420 si13_change_mark := omit,
421 gprs_ma := omit,
422 zero := '0'B, /* PBCCH not present in cell */
423 rac := 0,
424 spgc_ccch_sup := '0'B,
425 priority_access_thr := '110'B,
426 network_control_order := '00'B,
427 gprs_cell_opts := {
428 nmo := '01'B,
429 t3168 := '011'B,
430 t3192 := '010'B,
431 drx_timer_max := '011'B,
432 access_burst_type := '0'B,
433 control_ack_type := '1'B,
434 bs_cv_max := 15,
435 pan_presence := '1'B,
436 pan_dec := 1,
437 pan_inc := 1,
438 pan_max := '111'B,
439 ext_info_presence := ?,
440 ext_info_length := *,
441 ext_info := *
442 },
443 gprs_pwr_ctrl_params := {
444 alpha := 0,
445 t_avg_w := '10000'B,
446 t_avg_t := '10000'B,
447 pc_meas_chan := '0'B,
448 n_avg_i := '1000'B
449 }
450 }
451 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200452 si5 := {
453 bcch_freq_list := '10000000000000000000000000000000'O
454 },
455 si5bis := omit,
456 si5ter := {
457 extd_bcch_freq_list := '9E050020000000000000000000000000'O
458 },
459 si6 := {
460 cell_id := 0,
461 lai := {
462 mcc_mnc := '001F01'H,
463 lac := 1
464 },
465 cell_options := {
466 dtx_ext := '1'B,
467 pwrc := false,
468 dtx := '01'B,
469 radio_link_timeout := '0111'B
470 },
471 ncc_permitted := '11111111'B,
Vadim Yanitskiy348b07c2022-03-10 17:11:22 +0300472 rest_octets := {
473 pch_nch_info := ?,
474 vbs_vgcs_options := ?,
475 dtm_support := '0'B,
476 rac := omit,
477 max_lapdm := omit,
478 band_ind := '0'B /* C0 ARFCN indicates 1800 band */
479 }
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200480 }
481 };
482
483
484/* List of all the System Information received on all RSL ports */
485type record of SystemInformationConfig SystemInformationConfig_list;
486
487function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
488{
489 var RSL_IE_Body sysinfo_type_ie;
490 var RSL_IE_SysinfoType si_type;
491 var octetstring data;
492
493 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
494 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
495 mtc.stop;
496 }
497 si_type := sysinfo_type_ie.sysinfo_type;
498
499 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
500 var RSL_IE_Body bcch_ie;
501 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
502 data := bcch_ie.other.payload;
503 }
504 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
505 var RSL_IE_Body l3_ie;
506 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
507 data := l3_ie.l3_info.payload;
508 }
509 } else {
510 setverdict(fail, "Don't understand this System Information message");
511 mtc.stop;
512 }
513
514 var boolean handled := false;
515
516 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
517 handled := true;
518
519 if (si_type == RSL_SYSTEM_INFO_1) {
520 if (not isbound(data)) {
521 si.si1 := omit;
522 } else {
523 si.si1 := dec_SystemInformation(data).payload.si1;
524 }
525 } else if (si_type == RSL_SYSTEM_INFO_2) {
526 if (not isbound(data)) {
527 si.si2 := omit;
528 } else {
529 si.si2 := dec_SystemInformation(data).payload.si2;
530 }
531 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
532 if (not isbound(data)) {
533 si.si2bis := omit;
534 } else {
535 si.si2bis := dec_SystemInformation(data).payload.si2bis;
536 }
537 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
538 if (not isbound(data)) {
539 si.si2ter := omit;
540 } else {
541 si.si2ter := dec_SystemInformation(data).payload.si2ter;
542 }
543 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
544 if (not isbound(data)) {
545 si.si2quater := {};
546 } else {
547 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
548 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
549 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
550 }
551 } else if (si_type == RSL_SYSTEM_INFO_3) {
552 if (not isbound(data)) {
553 si.si3 := omit;
554 } else {
555 si.si3 := dec_SystemInformation(data).payload.si3;
556 }
557 } else if (si_type == RSL_SYSTEM_INFO_4) {
558 if (not isbound(data)) {
559 si.si4 := omit;
560 } else {
561 si.si4 := dec_SystemInformation(data).payload.si4;
562 }
563 } else if (si_type == RSL_SYSTEM_INFO_13) {
564 if (not isbound(data)) {
565 si.si13 := omit;
566 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100567 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200568 }
569 } else {
570 handled := false;
571 }
572 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
573 handled := true;
574
575 if (si_type == RSL_SYSTEM_INFO_5) {
576 if (not isbound(data)) {
577 si.si5 := omit;
578 } else {
579 si.si5 := dec_SystemInformation(data).payload.si5;
580 }
581 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
582 if (not isbound(data)) {
583 si.si5bis := omit;
584 } else {
585 si.si5bis := dec_SystemInformation(data).payload.si5bis;
586 }
587 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
588 if (not isbound(data)) {
589 si.si5ter := omit;
590 } else {
591 si.si5ter := dec_SystemInformation(data).payload.si5ter;
592 }
593 } else if (si_type == RSL_SYSTEM_INFO_6) {
594 if (not isbound(data)) {
595 si.si6 := omit;
596 } else {
597 si.si6 := dec_SystemInformation(data).payload.si6;
598 }
599 } else {
600 handled := false;
601 }
602 }
603
604 if (not handled) {
605 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
606 }
607}
608
Harald Weltea4ca4462018-02-09 00:17:14 +0100609type component test_CT extends CTRL_Adapter_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600610 /* Array of per-BTS/TRX state */
611 var BTS_State bts[NUM_BTS][NUM_TRX];
Harald Welte89ab1912018-02-23 18:56:29 +0100612 /* RSL common Channel Port (for RSL_Emulation) */
613 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600614 /* array of per-BTS/TRX RSL test ports */
615 port IPA_RSL_PT IPA_RSL[NUM_BTS][NUM_TRX];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100616 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200617 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
618 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200619 /* Configure/manage IPA_Emulation per-BTS/TRX port: */
620 port IPA_CFG_PT IPA_CFG_PORT[NUM_BTS][NUM_TRX];
Harald Weltea5d2ab22017-12-09 14:21:42 +0100621
Daniel Willmann191e0d92018-01-17 12:44:35 +0100622 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100623 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100624
Daniel Willmannebdecc02020-08-12 15:30:17 +0200625 /* StatsD */
626 var StatsD_Checker_CT vc_STATSD;
627
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200628 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200629 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100630 /* for old legacy-tests only */
631 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200632 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100633
Harald Welte21b46bd2017-12-17 19:46:32 +0100634 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100635 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100636
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200637 /* Osmux is enabled through VTY */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200638 var boolean g_osmux_enabled_cn := false;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200639
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100640 /*Configure T(tias) over VTY, seconds */
641 var integer g_bsc_sccp_timer_ias := 7 * 60;
642 /*Configure T(tiar) over VTY, seconds */
643 var integer g_bsc_sccp_timer_iar := 15 * 60;
644
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200645 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100646 timer T_guard := 30.0;
647
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200648 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000649 var CounterNameValsList g_ctr_bsc;
650 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200651
652 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
653 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100654}
655
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200656type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100657modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100658 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100659 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100660 /* port number to which to establish the IPA OML connections */
661 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100662 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100663 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100664 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100665 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200666 /* port number to which to listen for STATSD metrics */
667 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100668 /* IP address at which the test binds */
669 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100670
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200671 RAN_Configurations mp_bssap_cfg := {
672 {
673 transport := BSSAP_TRANSPORT_AoIP,
674 sccp_service_type := "mtp3_itu",
675 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
676 own_pc := 185, /* 0.23.1 first MSC emulation */
677 own_ssn := 254,
678 peer_pc := 187, /* 0.23.3 osmo-bsc */
679 peer_ssn := 254,
680 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200681 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200682 },
683 {
684 transport := BSSAP_TRANSPORT_AoIP,
685 sccp_service_type := "mtp3_itu",
686 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
687 own_pc := 2, /* 0.0.2 second MSC emulation */
688 own_ssn := 254,
689 peer_pc := 187, /* 0.23.3 osmo-bsc */
690 peer_ssn := 254,
691 sio := '83'O,
692 rctx := 2
693 },
694 {
695 transport := BSSAP_TRANSPORT_AoIP,
696 sccp_service_type := "mtp3_itu",
697 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
698 own_pc := 3, /* 0.0.3 third MSC emulation */
699 own_ssn := 254,
700 peer_pc := 187, /* 0.23.3 osmo-bsc */
701 peer_ssn := 254,
702 sio := '83'O,
703 rctx := 3
704 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100705 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200706
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200707 /* Must match per BTS config in osmo-bsc.cfg */
708 phys_chan_configs phys_chan_config := {
709 "CCCH+SDCCH4+CBCH",
710 "TCH/F",
711 "TCH/F",
712 "TCH/F",
713 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600714 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200715 "PDCH",
716 "PDCH"
717 };
718
Harald Welte47cd0e32020-08-21 12:39:11 +0200719 BSSAP_LE_Configuration mp_bssap_le_cfg := {
720 sccp_service_type := "mtp3_itu",
721 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200722 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200723 own_ssn := 252, /* SMLC side SSN */
724 peer_pc := 187, /* 0.23.3 osmo-bsc */
725 peer_ssn := 250, /* BSC side SSN */
726 sio := '83'O,
727 rctx := 6
728 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200729 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200730
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100731 /* Value set in osmo-bsc.cfg "ms max power" */
732 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600733
734 /* Whether to check for memory leaks */
735 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100736}
737
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200738friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200739
740 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200741 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200742 pars.aoip := true;
743 } else {
744 pars.aoip := false;
745 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100746 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200747 pars.mscpool.bssap_idx := bssap_idx;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600748 pars.expect_tsc := c_BtsParams[0].tsc;
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300749 pars.imsi := f_rnd_imsi('00101'H);
750
751 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200752
Philipp Maier48604732018-10-09 15:00:37 +0200753 return pars;
754}
755
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200756/* Convenience functions for rate counters using g_ctr_msc. */
757
758private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
759 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
760 log("initial msc rate counters: ", g_ctr_msc);
761}
762
763private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200764 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200765}
766
767/* f_ctrs_msc_init();
768 * f_do_thing(on_msc := 0);
769 * f_do_thing(on_msc := 0);
770 * f_do_other(on_msc := 1);
771 * f_ctrs_msc_add(0, "thing", 2);
772 * f_ctrs_msc_add(1, "other");
773 * f_ctrs_msc_verify();
774 */
775private function f_ctrs_msc_verify() runs on test_CT {
776 log("verifying msc rate counters: ", g_ctr_msc);
777 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
778}
779
780/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
781 * f_ctrs_msc_init();
782 * f_do_thing(on_msc := 0);
783 * f_do_thing(on_msc := 0);
784 * f_do_thing(on_msc := 0);
785 * f_ctrs_msc_expect(0, "thing", 3);
786 */
787private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
788 f_ctrs_msc_add(msc_nr, countername, val);
789 f_ctrs_msc_verify();
790}
791
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000792/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
793
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100794private 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 +0000795 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100796 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100797}
798
799function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
800 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000801 f_ctrs_bsc_init(counternames);
802}
803
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100804private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
805 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100806 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100807 f_ctrs_bsc_init(counternames_bsc_bts_handover);
808}
809
810private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000811 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100812}
813
814private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
815 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000816 f_ctrs_bsc_add(countername, val);
817}
818
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100819function f_ctrs_bts_verify() runs on test_CT {
820 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
821}
822
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000823/* f_ctrs_bsc_and_bts_init();
824 * f_do_thing(on_bts := 0);
825 * f_do_thing(on_bts := 0);
826 * f_do_other(on_bts := 1);
827 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
828 * f_ctrs_bsc_and_bts_add(1, "other");
829 * f_ctrs_bsc_and_bts_verify();
830 */
831private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100832 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000833 f_ctrs_bsc_verify();
834}
835
836/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
837 * f_ctrs_bsc_and_bts_init();
838 * f_do_thing(on_bts := 0);
839 * f_do_thing(on_bts := 0);
840 * f_do_thing(on_bts := 0);
841 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
842 */
843private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
844 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
845 f_ctrs_bsc_and_bts_verify();
846}
847
848
849/* Convenience functions for rate counters using g_ctr_bsc. */
850
851private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
852 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
853 log("initial bsc rate counters: ", g_ctr_bsc);
854}
855
856private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
857 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
858}
859
860/* f_ctrs_bsc_init();
861 * f_do_thing();
862 * f_do_thing();
863 * f_do_other();
864 * f_ctrs_bsc_add("thing", 2);
865 * f_ctrs_bsc_add("other");
866 * f_ctrs_bsc_verify();
867 */
868private function f_ctrs_bsc_verify() runs on test_CT {
869 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
870}
871
872/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
873 * f_ctrs_bsc_init();
874 * f_do_thing();
875 * f_ctrs_bsc_expect("thing", 1);
876 */
877private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
878 f_ctrs_bsc_add(countername, val);
879 f_ctrs_bsc_verify();
880}
881
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200882
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200883friend function f_shutdown_helper() runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100884 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600885 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100886 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
887 }
888
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200889 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100890 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200891 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100892}
893
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200894private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100895 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200896 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100897 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200898 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 +0200899 ts_BSSMAP_Reset(0, g_osmux_enabled_cn)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100900 T.start;
901 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200902 [] 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 +0200903 tr_BSSMAP_ResetAck(g_osmux_enabled_cn))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200904 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100905 }
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200906 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200907 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100908 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +0200909 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200910 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100911 repeat;
912 }
913 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200914 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200915 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200916 /* If we received a RESET after ours was sent, it
917 may be a race condition where the other peer beacame
918 available after we sent it, but we are in a desired
919 state anyway, so go forward. */
920 if (not reset_received) {
921 setverdict(fail);
922 }
923 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100924 }
Harald Welte28d943e2017-11-25 15:00:50 +0100925}
926
Harald Welteae026692017-12-09 01:03:01 +0100927type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100928 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100929 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100930 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100931 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100932 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100933 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100934 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100935 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100936}
937
Harald Welte21b46bd2017-12-17 19:46:32 +0100938/*! Start the IPA/RSL related bits for one IPA_Client.
939 * \param clnt IPA_Client for which to establish
940 * \param bsc_host IP address / hostname of the BSC
941 * \param bsc_port TCP port number of the BSC
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600942 * \param idx BTS/TRX index values
Harald Welte21b46bd2017-12-17 19:46:32 +0100943 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600944function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port,
945 BtsTrxIdx idx := {0, 0}, boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100946runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100947 timer T := 10.0;
948
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600949 clnt.id := "IPA-BTS" & int2str(idx.bts) & "-TRX" & int2str(idx.trx) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100950 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100951 clnt.ccm_pars := c_IPA_default_ccm_pars;
952 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600953 clnt.ccm_pars.unit_id := int2str(1234 + idx.bts) & "/0/" & int2str(idx.trx);
Harald Welte624f9632017-12-16 19:26:04 +0100954 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100955 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600956 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[idx.bts]);
Harald Welte624f9632017-12-16 19:26:04 +0100957 }
Harald Welteae026692017-12-09 01:03:01 +0100958
959 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200960 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100961 if (handler_mode) {
962 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
963 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600964 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[idx.bts][idx.trx]);
Harald Welte624f9632017-12-16 19:26:04 +0100965 }
Harald Welteae026692017-12-09 01:03:01 +0100966
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600967 var integer local_port := 10000 + idx.bts * 1000 + idx.trx;
968 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", local_port, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100969 if (handler_mode) {
970 clnt.vc_RSL.start(RSL_Emulation.main());
971 return;
972 }
Harald Welteae026692017-12-09 01:03:01 +0100973
974 /* wait for IPA RSL link to connect and send ID ACK */
975 T.start;
976 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600977 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100978 T.stop;
Harald Welteae026692017-12-09 01:03:01 +0100979 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +0600980 [] IPA_RSL[idx.bts][idx.trx].receive(ASP_IPA_Event:?) { repeat }
981 [] IPA_RSL[idx.bts][idx.trx].receive { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100982 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100983 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200984 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100985 }
986 }
987}
988
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +0200989function f_ipa_rsl_stop(inout IPA_Client clnt, BtsTrxIdx idx := {0, 0}) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100990 var IPL4asp_Types.Result res := {
991 errorCode := omit,
992 connId := omit,
993 os_error_code := omit,
994 os_error_text := omit
995 };
996
Harald Welte12055472018-03-17 20:10:08 +0100997 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
998 return;
999 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001000
1001 /* Alive components don't finish sockets (TCP FIN) when they are
1002 * stopped. Hence, we need to manually call close() on them to make sure
1003 * the IUT knows about it. */
Pau Espin Pedrol80d4b4f2022-06-10 18:39:42 +02001004 f_ipa_cfg_disconnect(IPA_CFG_PORT[idx.bts][idx.trx], res);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01001005
Harald Welte12055472018-03-17 20:10:08 +01001006 clnt.vc_IPA.stop;
1007 if (isbound(clnt.vc_RSL)) {
1008 clnt.vc_RSL.stop;
1009 }
1010}
1011
Harald Welte21b46bd2017-12-17 19:46:32 +01001012/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +01001013function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1014 timer T := secs_max;
1015 T.start;
1016 while (true) {
1017 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1018 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001019 /* the 'degraded' state exists from OML connection time, and we have to wait
1020 * until all MO's are initialized */
1021 T.start(1.0);
1022 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001023 return;
1024 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001025 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001026 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001027 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001028 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001029 }
1030 }
1031}
1032
Harald Welte21b46bd2017-12-17 19:46:32 +01001033/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001034altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001035 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001036 [] T_guard.timeout {
1037 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001038 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001039 }
Harald Welte60e823a2017-12-10 14:10:59 +01001040 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001041 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001042 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001043 ts_BSSMAP_ResetAck(g_osmux_enabled_cn)));
Harald Welte69c1c262017-12-13 21:02:08 +01001044 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001045 }
Harald Welte28d943e2017-11-25 15:00:50 +01001046}
1047
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001048altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001049 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled_cn))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001050 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001051 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001052 }
1053}
1054
Daniel Willmann191e0d92018-01-17 12:44:35 +01001055function f_init_mgcp(charstring id) runs on test_CT {
1056 id := id & "-MGCP";
1057
1058 var MGCPOps ops := {
1059 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1060 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1061 };
1062 var MGCP_conn_parameters mgcp_pars := {
1063 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001064 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001065 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001066 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001067 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1068 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001069 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001070 };
1071
Harald Welte71389132021-12-09 21:58:18 +01001072 vc_MGCP := MGCP_Emulation_CT.create(id) alive;
Daniel Willmann191e0d92018-01-17 12:44:35 +01001073 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1074}
1075
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001076/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1077 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1078 * OsmuxCID IE.
1079 */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001080private function f_vty_allow_osmux_cn(boolean allow) runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001081 f_vty_enter_cfg_msc(BSCVTY, 0);
1082 if (allow) {
1083 f_vty_transceive(BSCVTY, "osmux on");
1084 } else {
1085 f_vty_transceive(BSCVTY, "osmux off");
1086 }
1087 f_vty_transceive(BSCVTY, "exit");
1088 f_vty_transceive(BSCVTY, "exit");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001089}
1090
Max2253c0b2018-11-06 19:28:05 +01001091function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001092 if (BSCVTY.checkstate("Mapped")) {
1093 /* skip initialization if already executed once */
1094 return;
1095 }
Harald Weltebc03c762018-02-12 18:09:38 +01001096 map(self:BSCVTY, system:BSCVTY);
1097 f_vty_set_prompts(BSCVTY);
1098 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001099 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1100 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001101}
1102
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001103friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001104{
1105 // log on TTCN3 log output
1106 log(log_msg);
1107 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001108 if (pt.checkstate("Mapped")) {
1109 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1110 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001111}
1112
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001113private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1114{
1115 if (rsl_idx >= lengthof(g_system_information)) {
1116 g_system_information[rsl_idx] := SystemInformationConfig_omit
1117 }
1118 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1119}
1120
1121altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1122 var ASP_RSL_Unitdata rx_rsl_ud;
1123
1124 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001125 [] 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 +02001126 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1127 repeat;
1128 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001129 [] 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 +02001130 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1131 repeat;
1132 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001133 [] 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 +02001134 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1135 repeat;
1136 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001137 [] 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 +02001138 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1139 repeat;
1140 }
1141
1142 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1143 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1144 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1145 repeat;
1146 }
1147 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1148 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1149 repeat;
1150 }
1151 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1152 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1153 repeat;
1154 }
1155 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1156 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1157 repeat;
1158 }
1159}
1160
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001161/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1162private type record of boolean my_BooleanList;
1163
1164private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1165{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001166 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1167
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001168 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001169 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1170 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1171 * stepping into that config node. */
1172 log("msc ", msc_nr, " is not configured, skipping");
1173 continue;
1174 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001175 f_vty_enter_cfg_msc(pt, msc_nr);
1176 if (allow_attach_list[msc_nr]) {
1177 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1178 f_vty_transceive(pt, "allow-attach", strict := false);
1179 } else {
1180 f_vty_transceive(pt, "no allow-attach", strict := false);
1181 }
1182 f_vty_transceive(pt, "exit");
1183 f_vty_transceive(pt, "exit");
1184 }
1185}
1186
Harald Welte21b46bd2017-12-17 19:46:32 +01001187/* global initialization function
1188 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001189 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1190 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1191 */
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001192function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001193 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001194 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001195
Harald Welteae026692017-12-09 01:03:01 +01001196 if (g_initialized) {
1197 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001198 }
Harald Welteae026692017-12-09 01:03:01 +01001199 g_initialized := true;
1200
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001201 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001202 activate(as_Tguard());
1203
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001204 f_init_vty("VirtMSC");
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02001205 f_vty_allow_osmux_cn(g_osmux_enabled_cn);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001206
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001207 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001208 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1209
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001210 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1211 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1212 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1213 }
1214
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001215 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001216 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001217 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1218 * MSC-side BSSAP emulation */
1219 if (handler_mode) {
1220 var RanOps ranops := MSC_RanOps;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02001221 ranops.use_osmux := g_osmux_enabled_cn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001222 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1223 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1224 f_ran_adapter_start(g_bssap[bssap_idx]);
1225 } else {
1226 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1227 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1228 f_ran_adapter_start(g_bssap[bssap_idx]);
1229 f_legacy_bssap_reset();
1230 }
Harald Welte67089ee2018-01-17 22:19:03 +01001231 }
Harald Welted5833a82018-05-27 16:52:56 +02001232
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001233 if (mp_enable_lcs_tests) {
1234 if (handler_mode) {
1235 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1236 } else {
1237 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1238 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1239 }
1240 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001241 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001242
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001243 /* start the test with exactly all enabled MSCs allowed to attach */
1244 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1245
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001246 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001247
Daniel Willmann191e0d92018-01-17 12:44:35 +01001248 f_init_mgcp("VirtMSC");
1249
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001250 for (var integer i := 0; i < nr_bts; i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001251 f_init_bts(i, c_BtsParams[i].trx_num, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001252 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001253
1254 /* Emit a marker to appear in the SUT's own logging output */
1255 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001256}
Harald Welte696ddb62017-12-08 14:01:43 +01001257
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001258function f_init_bts(integer bts_idx := 0,
1259 integer trx_num := NUM_TRX_CFG,
1260 boolean handler_mode := false)
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001261runs on test_CT {
1262 /* wait until osmo-bts-omldummy has respawned */
1263 f_wait_oml(bts_idx, "degraded", 5.0);
1264
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001265 /* start RSL connection(s) */
1266 for (var integer trx_idx := 0; trx_idx < trx_num; trx_idx := trx_idx + 1) {
1267 f_ipa_rsl_start(bts[bts_idx][trx_idx].rsl,
1268 mp_bsc_ip, mp_bsc_rsl_port,
1269 {bts_idx, trx_idx}, handler_mode);
1270 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001271 /* wait until BSC tells us "connected" */
1272 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001273}
1274
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001275function f_init_bts_and_check_sysinfo(integer bts_idx := 0,
1276 integer trx_num := NUM_TRX_CFG,
1277 boolean handler_mode := false,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001278 template SystemInformationConfig expect_si)
1279runs on test_CT {
1280 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1281
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001282 f_init_bts(bts_idx, trx_num, handler_mode);
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001283
1284 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1285 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1286 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1287 */
1288 f_sleep(5.0);
1289 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1290
1291 deactivate(sysinfo);
1292
1293 if (match(g_system_information[bts_idx], expect_si)) {
1294 setverdict(pass);
1295 } else {
1296 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1297 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1298 setverdict(fail, "received SI does not match expectations");
1299 return;
1300 }
1301}
1302
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001303/* expect to receive a RSL message matching a specified template on a given BTS / TRX */
1304function f_exp_ipa_rx(template (present) RSL_Message t_rx,
1305 BtsTrxIdx idx := {0, 0},
1306 float Tval := 2.0)
Harald Welteae026692017-12-09 01:03:01 +01001307runs on test_CT return RSL_Message {
1308 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001309 timer T := Tval;
Harald Welteae026692017-12-09 01:03:01 +01001310
1311 T.start;
1312 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001313 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001314 T.stop;
1315 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001316 [] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001317 [] T.timeout {
1318 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001319 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001320 }
Harald Welteae026692017-12-09 01:03:01 +01001321 }
1322 return rx_rsl_ud.rsl;
1323}
1324
Harald Welte21b46bd2017-12-17 19:46:32 +01001325/* helper function to transmit RSL on a given BTS/stream */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001326function f_ipa_tx(template (value) RSL_Message t_tx,
1327 BtsTrxIdx idx := {0, 0},
1328 IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001329runs on test_CT {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001330 IPA_RSL[idx.bts][idx.trx].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001331}
1332
1333
Harald Welte4003d112017-12-09 22:35:39 +01001334/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001335testcase TC_chan_act_noreply() runs on test_CT {
1336 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001337 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001338
Harald Welte89d42e82017-12-17 16:42:41 +01001339 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001340
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001341 f_ipa_tx(ts_RSL_CHAN_RQD('23'O, 23));
1342 rsl_unused := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001343 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001344}
1345
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001346const CounterNameVals counternames_bts_chreq := {
1347 { "chreq:total", 0 },
1348 { "chreq:attempted_emerg", 0 },
1349 { "chreq:attempted_call", 0 },
1350 { "chreq:attempted_location_upd", 0 },
1351 { "chreq:attempted_pag", 0 },
1352 { "chreq:attempted_pdch", 0 },
1353 { "chreq:attempted_other", 0 },
1354 { "chreq:attempted_unknown", 0 },
1355 { "chreq:successful", 0 },
1356 { "chreq:successful_emerg", 0 },
1357 { "chreq:successful_call", 0 },
1358 { "chreq:successful_location_upd", 0 },
1359 { "chreq:successful_pag", 0 },
1360 { "chreq:successful_pdch", 0 },
1361 { "chreq:successful_other", 0 },
1362 { "chreq:successful_unknown", 0 },
1363 { "chreq:no_channel", 0 },
1364 { "chreq:max_delay_exceeded", 0 }
1365};
1366
1367/* verify the "chreq:*" counters */
1368private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1369{
1370 var GsmFrameNumber fn := 23;
1371
1372 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1373
1374 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001375 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn));
1376 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001377 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1378
1379 f_ctrs_bts_add(0, "chreq:total");
1380 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1381 f_ctrs_bts_verify();
1382
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001383 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1384 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001385
1386 f_ctrs_bts_add(0, "chreq:successful");
1387 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1388 f_ctrs_bts_verify();
1389
1390 /* test is done, release RSL Conn Fail Ind to clean up */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001391 f_ipa_tx(ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1392 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
1393 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001394 f_sleep(1.0);
1395}
1396
Harald Welte4003d112017-12-09 22:35:39 +01001397testcase TC_chan_act_counter() runs on test_CT {
1398 var BSSAP_N_UNITDATA_ind ud_ind;
1399 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001400 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001401
Harald Welte89d42e82017-12-17 16:42:41 +01001402 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001403
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001404 f_vty_allow_emerg_bts(true, 0);
1405
1406 f_ctrs_bts_init(1, counternames_bts_chreq);
1407
1408 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1409 f_chan_act_counter('a3'O, "emerg");
1410
1411 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1412 f_chan_act_counter('43'O, "call");
1413
1414 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1415 f_chan_act_counter('03'O, "location_upd");
1416
1417 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1418 f_chan_act_counter('23'O, "pag");
1419 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1420 f_chan_act_counter('33'O, "pag");
1421
1422 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1423 /* no PCU, so PDCH not allowed. Skip this test for now. */
1424 /* f_chan_act_counter('7b'O, "pdch"); */
1425
1426 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1427 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001428
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001429 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001430}
1431
Harald Welteae026692017-12-09 01:03:01 +01001432/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001433private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001434 var RSL_Message rx_rsl;
1435
Harald Welteae026692017-12-09 01:03:01 +01001436 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001437 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001438
1439 /* expect BSC to disable the channel again if there's no RLL EST IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001440 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := T3101_MAX);
Harald Welteae026692017-12-09 01:03:01 +01001441
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001442 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001443}
1444
Philipp Maier9c60a622020-07-09 15:08:46 +02001445/* Normal variant */
1446testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001447 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001448 f_TC_chan_act_ack_noest();
1449}
1450
1451/* Emergency call variant */
1452testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1453 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001454 f_init(1);
1455 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001456 f_TC_chan_act_ack_noest(ra := 'A5'O);
1457}
1458
Philipp Maier606f07d2020-08-12 17:21:58 +02001459/* Emergency call variant, but emergency calls are not allowed */
1460testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1461 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1462
1463 var RSL_Message rx_rsl;
1464 var GsmRrMessage rr;
1465
1466 f_init(1);
1467 f_vty_allow_emerg_bts(false, 0);
1468
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001469 IPA_RSL[0][0].clear;
1470 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier606f07d2020-08-12 17:21:58 +02001471
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001472 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Philipp Maier606f07d2020-08-12 17:21:58 +02001473 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1474 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1475 setverdict(pass);
1476 } else {
1477 setverdict(fail, "immediate assignment not rejected");
1478 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001479
1480 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001481}
1482
Harald Welteae026692017-12-09 01:03:01 +01001483/* Test behavior if MSC never answers to CR */
1484testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001485 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1486 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001487 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001488 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001489
Harald Welte89d42e82017-12-17 16:42:41 +01001490 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001491
1492 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001493 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001494
1495 var octetstring l3 := '00010203040506'O
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001496 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welteae026692017-12-09 01:03:01 +01001497
1498 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1499
1500 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001501 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001502 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001503 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001504}
1505
1506/* Test behavior if MSC answers with CREF to CR */
1507testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1508 var BSSAP_N_CONNECT_ind rx_c_ind;
1509 var RSL_Message rx_rsl;
1510
Harald Welte89d42e82017-12-17 16:42:41 +01001511 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001512
1513 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001514 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001515
1516 var octetstring l3 := '00010203040506'O
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001517 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welteae026692017-12-09 01:03:01 +01001518
1519 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1520 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1521
1522 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001523 f_expect_chan_rel(chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001524 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001525}
1526
Harald Welte618ef642017-12-14 14:58:20 +01001527/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1528testcase TC_chan_act_nack() runs on test_CT {
1529 var RSL_Message rx_rsl;
1530 var integer chact_nack;
1531
Harald Welte89d42e82017-12-17 16:42:41 +01001532 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001533
1534 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1535
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001536 f_ipa_tx(ts_RSL_CHAN_RQD('33'O, 33));
1537 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte618ef642017-12-14 14:58:20 +01001538 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1539
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001540 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte618ef642017-12-14 14:58:20 +01001541
1542 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1543 f_sleep(0.5);
1544
1545 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1546
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001547 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001548}
1549
Harald Welte799c97b2017-12-14 17:50:30 +01001550/* Test for channel exhaustion due to RACH overload */
1551testcase TC_chan_exhaustion() runs on test_CT {
1552 var ASP_RSL_Unitdata rsl_ud;
1553 var integer i;
1554 var integer chreq_total, chreq_nochan;
1555
Harald Welte89d42e82017-12-17 16:42:41 +01001556 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001557
1558 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1559 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1560
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001561 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001562 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1563 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001564 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 +01001565 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001566 }
1567
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001568 IPA_RSL[0][0].clear;
Harald Welte799c97b2017-12-14 17:50:30 +01001569
Harald Weltedd8cbf32018-01-28 12:07:52 +01001570 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001571 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001572
1573 /* now expect additional channel activations to fail */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001574 f_ipa_tx(ts_RSL_CHAN_RQD('42'O, 42));
Harald Welte799c97b2017-12-14 17:50:30 +01001575
1576 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001577 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001578 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1579 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001580 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001581 var GsmRrMessage rr;
1582 /* match on IMM ASS REJ */
1583 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1584 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1585 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001586 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001587 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1588 chreq_nochan+1);
1589 setverdict(pass);
1590 } else {
1591 repeat;
1592 }
1593 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001594 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte799c97b2017-12-14 17:50:30 +01001595 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001596 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001597}
1598
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001599/* Test channel deactivation due to silence from MS */
1600testcase TC_chan_deact_silence() runs on test_CT {
1601 var RslChannelNr chan_nr;
1602
1603 f_init(1);
1604
1605 /* Request for a dedicated channel */
1606 chan_nr := f_chreq_act_ack('23'O);
1607
1608 /* Wait some time until the channel is released */
1609 f_sleep(2.0);
1610
1611 /* Expect CHANnel RELease */
1612 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001613 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001614 log("Received CHANnel RELease");
1615 setverdict(pass);
1616 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001617 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001618 /* See OS#3709, OsmoBSC should not send Immediate
1619 * Assignment Reject since a dedicated channel was
1620 * already allocated, and Immediate Assignment was
1621 * already sent. */
1622 setverdict(fail, "Unexpected Immediate Assignment!");
1623 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001624 [] IPA_RSL[0][0].receive {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001625 setverdict(fail, "Unexpected RSL message!");
1626 }
1627 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001628 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001629}
1630
Harald Weltecfe2c962017-12-15 12:09:32 +01001631/***********************************************************************
1632 * Assignment Testing
1633 ***********************************************************************/
1634
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001635/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1636 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001637testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001638 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001639
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001640 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1641 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001642 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001643 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001644}
1645
Harald Welte16a4adf2017-12-14 18:54:01 +01001646/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001647testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001648 var BSSAP_N_CONNECT_ind rx_c_ind;
1649 var RSL_Message rx_rsl;
1650 var DchanTuple dt;
1651
Harald Welte89d42e82017-12-17 16:42:41 +01001652 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001653
1654 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001655 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001656 /* send assignment without AoIP IEs */
1657 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1658 } else {
1659 /* Send assignmetn without CIC in IPA case */
1660 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1661 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1662 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1663 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001664 alt {
1665 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1666 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1667 }
Harald Welte235ebf12017-12-15 14:18:16 +01001668 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001669 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1670 setverdict(pass);
1671 }
1672 [] BSSAP.receive { repeat; }
1673 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001674 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001675 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001676}
1677
Harald Welteed848512018-05-24 22:27:58 +02001678/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001679function 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 +02001680 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001681 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001682 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001683 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001684 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001685 if (osmux_enabled) {
1686 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1687 } else {
1688 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1689 }
Harald Welteed848512018-05-24 22:27:58 +02001690 } else {
1691 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001692 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001693 }
1694 return ass_cmd;
1695}
1696
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001697function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001698 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001699 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1700 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001701 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001702
1703 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1704 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001705 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1706 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001707 if (ispresent(enc)) {
1708 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001709 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1710 if (ispresent(v_enc.enc_alg_chosen)) {
1711 chosenEncryptionAlgorithm := valueof(
1712 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1713 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1714 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001715 if (ispresent(v_enc.enc_kc128)) {
1716 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1717 }
1718 }
1719
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001720 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001721 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001722 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001723 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1724 cell_id_source := cell_id_source,
1725 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001726 encryptionInformation := encryptionInformation,
1727 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001728 kC128 := kc128,
1729 /* on AoIP, allow "all" codecs (until we add more concise
1730 * tests) */
1731 codecList := ts_BSSMAP_IE_CodecList(
1732 {ts_CodecAMR_F, ts_CodecAMR_H,
1733 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001734 } else {
1735 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001736 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1737 cell_id_source := cell_id_source,
1738 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001739 encryptionInformation := encryptionInformation,
1740 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1741 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001742 }
1743 return ho_req;
1744}
1745
Harald Welteed848512018-05-24 22:27:58 +02001746/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001747function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001748 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001749 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001750 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001751 if (expect_osmux) {
1752 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1753 } else {
1754 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1755 }
Harald Welteed848512018-05-24 22:27:58 +02001756 } else {
1757 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001758 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001759 }
1760 return exp_compl;
1761}
1762
Harald Welte235ebf12017-12-15 14:18:16 +01001763/* Run everything required up to sending a caller-specified assignment command and expect response */
1764function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001765runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001766 var BSSAP_N_CONNECT_ind rx_c_ind;
1767 var RSL_Message rx_rsl;
1768 var DchanTuple dt;
1769
Harald Welte89d42e82017-12-17 16:42:41 +01001770 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001771
1772 dt := f_est_dchan('23'O, 23, '00000000'O);
1773 /* send assignment without AoIP IEs */
1774 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1775 alt {
1776 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1777 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1778 setverdict(pass);
1779 } else {
1780 setverdict(fail, fail_text);
1781 }
1782 }
1783 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1784 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1785 setverdict(pass);
1786 } else {
1787 setverdict(fail, fail_text);
1788 }
1789 }
1790 [] BSSAP.receive { repeat; }
1791 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001792 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001793}
1794testcase TC_assignment_csd() runs on test_CT {
1795 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001796 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001797 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1798 //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 +01001799 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1800 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001801 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001802}
1803
1804testcase TC_assignment_ctm() runs on test_CT {
1805 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001806 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001807 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1808 //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 +01001809 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1810 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001811 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001812}
1813
Harald Welte4003d112017-12-09 22:35:39 +01001814type record DchanTuple {
1815 integer sccp_conn_id,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001816 RslChannelNr rsl_chan_nr,
1817 BtsTrxIdx idx
Harald Weltea5d2ab22017-12-09 14:21:42 +01001818}
1819
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001820type record of DchanTuple DchanTuples;
1821
Harald Welted6939652017-12-13 21:02:46 +01001822/* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001823private function f_chreq_act_ack(OCT1 ra := '23'O,
1824 GsmFrameNumber fn := 23,
1825 BtsTrxIdx idx := {0, 0})
Harald Welted6939652017-12-13 21:02:46 +01001826runs on test_CT return RslChannelNr {
1827 var RSL_Message rx_rsl;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001828 f_ipa_tx(ts_RSL_CHAN_RQD(ra, fn), {idx.bts, 0});
1829 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Harald Welted6939652017-12-13 21:02:46 +01001830 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001831 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10), idx);
1832 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Harald Welted6939652017-12-13 21:02:46 +01001833 return chan_nr;
1834}
1835
Harald Welte4003d112017-12-09 22:35:39 +01001836/* helper function to establish a dedicated channel via BTS and MSC */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001837function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1838 BtsTrxIdx idx := {0, 0})
Harald Welte4003d112017-12-09 22:35:39 +01001839runs on test_CT return DchanTuple {
1840 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001841 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001842
Harald Welte4003d112017-12-09 22:35:39 +01001843 /* Send CHAN RQD and wait for allocation; acknowledge it */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001844 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn, idx);
Harald Welte4003d112017-12-09 22:35:39 +01001845
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001846 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 +01001847
1848 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1849 dt.sccp_conn_id := rx_c_ind.connectionId;
1850 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1851
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001852 dt.idx := idx;
Harald Welte4003d112017-12-09 22:35:39 +01001853 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001854}
1855
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001856/* 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 +06001857function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3,
1858 BtsTrxIdx idx := {0, 0})
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001859runs on test_CT return DchanTuple {
1860 var BSSAP_N_CONNECT_ind rx_c_ind;
1861 var DchanTuple dt;
1862
1863 /* Send CHAN RQD */
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});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001866
1867 /* The dyn TS first deactivates PDCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001868 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 +02001869 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001870 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001871
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001872 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001873 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1874
1875 /* Now activates the signalling channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001876 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10), idx);
1877 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0), {idx.bts, 0});
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001878
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001879 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 +02001880
1881 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1882 dt.sccp_conn_id := rx_c_ind.connectionId;
1883 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1884
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001885 dt.idx := idx;
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001886 return dt;
1887}
1888
Harald Welte641fcbe2018-06-14 10:58:35 +02001889/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001890private function f_exp_chan_rel_and_clear(DchanTuple dt)
1891runs on test_CT {
Harald Welte641fcbe2018-06-14 10:58:35 +02001892 var RSL_Message rx_rsl;
1893 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001894 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 +02001895 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001896 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr), dt.idx);
Harald Welte641fcbe2018-06-14 10:58:35 +02001897
1898 /* expect Clear Complete from BSC */
1899 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1900
1901 /* MSC disconnects as instructed. */
1902 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1903}
1904
Harald Welte4003d112017-12-09 22:35:39 +01001905/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1906testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001907 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001908 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001909
Harald Welte89d42e82017-12-17 16:42:41 +01001910 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001911
Harald Welte4003d112017-12-09 22:35:39 +01001912 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1913
1914 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001915 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Harald Welte4003d112017-12-09 22:35:39 +01001916
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001917 /* expect Clear Request on MSC side */
1918 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1919
1920 /* Instruct BSC to clear channel */
1921 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1922 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1923
Harald Welte4003d112017-12-09 22:35:39 +01001924 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001925 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001926
1927 /* wait for SCCP emulation to do its job */
1928 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001929
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001930 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001931}
1932
1933/* Test behavior of channel release after CONN FAIL IND from BTS */
1934testcase TC_chan_rel_conn_fail() runs on test_CT {
1935 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001936 var DchanTuple dt;
1937
Harald Welte89d42e82017-12-17 16:42:41 +01001938 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001939
1940 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1941
1942 /* simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001943 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001944 /* TODO: different cause values? */
1945
Harald Welte4003d112017-12-09 22:35:39 +01001946 /* expect Clear Request from BSC */
1947 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1948
1949 /* Instruct BSC to clear channel */
1950 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1951 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1952
Harald Welte6ff76ea2018-01-28 13:08:01 +01001953 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001954 f_exp_chan_rel_and_clear(dt);
Harald Welte4003d112017-12-09 22:35:39 +01001955
1956 /* wait for SCCP emulation to do its job */
1957 f_sleep(1.0);
1958
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001959 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001960}
1961
Harald Welte99f3ca02018-06-14 13:40:29 +02001962/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1963/* See also https://www.osmocom.org/issues/3182 */
1964testcase TC_early_conn_fail() runs on test_CT {
1965 var RSL_Message rx_rsl;
1966 var DchanTuple dt;
1967
1968 f_init(1);
1969
1970 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001971 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001972
1973 /* BTS->BSC: simulate CONN FAIL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001974 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02001975
1976 /* BTS->BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001977 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02001978
1979 /* BTS<-BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001980 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02001981
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001982 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001983}
1984
1985/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1986/* See also https://www.osmocom.org/issues/3182 */
1987testcase TC_late_conn_fail() runs on test_CT {
1988 var RSL_Message rx_rsl;
1989 var DchanTuple dt;
1990
1991 f_init(1);
1992
1993 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1994
1995 /* BSC<-MSC: Instruct BSC to clear connection */
1996 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1997
1998 /* BTS->BSC: expect BSC to deactivate SACCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06001999 rx_rsl := f_exp_ipa_rx(tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002000
2001 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002002 f_ipa_tx(ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte99f3ca02018-06-14 13:40:29 +02002003
2004 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002005 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), Tval := 10.0);
Harald Welte99f3ca02018-06-14 13:40:29 +02002006 /* BTS->BSC: respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002007 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
Harald Welte99f3ca02018-06-14 13:40:29 +02002008
2009 /* BSC->MSC: expect Clear Complete from BSC */
2010 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
2011
2012 /* BSC<-MSC: MSC disconnects as requested. */
2013 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2014
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002015 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02002016}
2017
Oliver Smithaf03bef2021-08-24 15:34:51 +02002018private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
2019 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
2020 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2021
2022 f_statsd_reset();
2023
2024 /* Establish SDCCH */
2025 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
2026 f_establish_fully(ass_cmd, exp_fail);
2027
2028 /* Expect stats to be 0 */
2029 var StatsDExpects expect := {
2030 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
2031 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
2032 };
2033 f_statsd_expect(expect);
2034
2035 /* Simulate CONN FAIL IND on SDCCH */
2036 RSL.send(ts_ASP_RSL_UD(
2037 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2038 IPAC_PROTO_RSL_TRX0));
2039
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002040 f_sleep(1.0);
2041
Oliver Smithaf03bef2021-08-24 15:34:51 +02002042 /* Expect stats to be 1 */
2043 expect := {
2044 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2045 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2046 };
2047 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002048 BSSAP.receive(tr_BSSMAP_ClearRequest);
2049 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002050}
2051testcase TC_stats_conn_fail() runs on test_CT {
2052 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2053 var MSC_ConnHdlr vc_conn;
2054
2055 f_init(1, true);
2056 f_sleep(1.0);
2057
2058 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2059 vc_conn.done;
2060
2061 f_shutdown_helper();
2062}
2063
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002064function f_expect_chan_rel(RslChannelNr rsl_chan_nr,
2065 BtsTrxIdx idx := {0, 0},
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002066 boolean expect_deact_sacch := true,
2067 boolean expect_rr_chan_rel := true,
2068 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002069 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002070 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002071 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002072 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002073
2074 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002075 var boolean got_deact_sacch := false;
2076 var boolean got_rr_chan_rel := false;
2077 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002078 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002079 var RSL_IE_Body l3_ie;
2080 var PDU_ML3_NW_MS l3;
2081 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002082 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2083 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002084 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002085 [] 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 +01002086 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002087 repeat;
2088 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002089 [] 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 +01002090 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002091
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002092 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2093 setverdict(fail, "cannot find L3");
2094 mtc.stop;
2095 }
2096 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2097
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002098 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002099 var CellSelIndValue cells := dec_CellSelIndValue(
2100 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2101
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002102 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2103 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002104 setverdict(pass);
2105 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002106 log("EXPECTED CELLS: ", expect_cells);
2107 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002108 }
2109 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002110
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002111 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2112 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2113 if (match(got_cause, expect_rr_cause)) {
2114 setverdict(pass);
2115 } else {
2116 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2117 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002118 }
Harald Welte99787102019-02-04 10:41:36 +01002119 repeat;
2120 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002121 [] 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 +01002122 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002123 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002124 if (handle_rll_rel) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002125 f_ipa_tx(ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002126 }
Harald Welte91d54a52018-01-28 15:35:07 +01002127 repeat;
2128 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002129 [] 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 +01002130 /* respond with CHAN REL ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002131 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
Harald Welte91d54a52018-01-28 15:35:07 +01002132 }
2133 /* ignore any user data */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002134 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002135 repeat;
2136 }
2137 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002138
2139 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2140 " got_rll_rel_req=", got_rll_rel_req);
2141
2142 if (expect_deact_sacch != got_deact_sacch) {
2143 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2144 }
2145 if (expect_rr_chan_rel != got_rr_chan_rel) {
2146 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2147 }
2148 if (expect_rll_rel_req != got_rll_rel_req) {
2149 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2150 }
Harald Welte91d54a52018-01-28 15:35:07 +01002151}
2152
Harald Welte4003d112017-12-09 22:35:39 +01002153/* Test behavior of channel release after hard Clear Command from MSC */
2154testcase TC_chan_rel_hard_clear() runs on test_CT {
2155 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002156 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002157
Harald Welte89d42e82017-12-17 16:42:41 +01002158 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002159
2160 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2161
2162 /* Instruct BSC to clear channel */
2163 var BssmapCause cause := 0;
2164 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2165
2166 /* expect Clear Complete from BSC on A */
2167 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2168 /* release the SCCP connection */
2169 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2170 }
2171
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002172 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002173 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002174}
2175
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002176function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2177 var BSSAP_N_DATA_ind rx_di;
2178 var DchanTuple dt;
2179
2180 f_init(1);
2181
2182 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2183 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2184 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2185 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2186
2187 /* Instruct BSC to clear channel */
2188 var BssmapCause cause := 0;
2189 if (tx_csfb_ind) {
2190 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2191 } else {
2192 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2193 }
2194
2195 /* expect Clear Complete from BSC on A */
2196 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2197 /* release the SCCP connection */
2198 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2199 }
2200
2201 /* 1 neighbor is added by default in osmo-bts.cfg and
2202 SystemInformationConfig_default, use that: */
2203 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2204
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002205 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 +02002206 f_shutdown_helper();
2207}
2208
2209/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2210 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2211 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2212 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2213 Indicator or not shouldn't matter at all. */
2214testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2215 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2216}
2217
2218/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2219 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2220 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2221 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2222testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2223 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2224}
2225
2226/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2227 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2228 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2229 CSFB Indicator should not be used anymore, and hence, there should be no
2230 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2231 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002232testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2233 var BSSAP_N_DATA_ind rx_di;
2234 var DchanTuple dt;
2235
2236 f_init(1);
2237
2238 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2239
2240 /* Instruct BSC to clear channel */
2241 var BssmapCause cause := 0;
2242 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2243
2244 /* expect Clear Complete from BSC on A */
2245 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2246 /* release the SCCP connection */
2247 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2248 }
2249
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002250 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002251 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002252}
2253
Harald Welted8c36cd2017-12-09 23:05:31 +01002254/* Test behavior of channel release after hard RLSD from MSC */
2255testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002256 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002257
Harald Welte89d42e82017-12-17 16:42:41 +01002258 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002259
2260 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2261
2262 /* release the SCCP connection */
2263 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2264
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002265 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002266 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002267}
2268
Harald Welte550daf92018-06-11 19:22:13 +02002269/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2270testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2271 var DchanTuple dt;
2272
2273 f_init(1);
2274
2275 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2276
2277 /* release the SCCP connection */
2278 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2279
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002280 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002281 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002282}
2283
Harald Welte85804d42017-12-10 14:11:58 +01002284/* Test behavior of channel release after BSSMAP RESET from MSC */
2285testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002286 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002287
Harald Welte89d42e82017-12-17 16:42:41 +01002288 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002289
2290 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2291
2292 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002293 IPA_RSL[0][0].clear;
Harald Welte85804d42017-12-10 14:11:58 +01002294
2295 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002296 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 +01002297 interleave {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02002298 [] 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 +01002299 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2300 }
2301
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002302 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002303 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002304}
2305
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002306/* Verify T(iar) triggers and releases the channel */
2307testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2308 var DchanTuple dt;
2309
2310 /* Set T(iar) in BSC low enough that it will trigger before other side
2311 has time to keep alive with a T(ias). Keep recommended ratio of
2312 T(iar) >= T(ias)*2 */
2313 g_bsc_sccp_timer_ias := 2;
2314 g_bsc_sccp_timer_iar := 5;
2315
2316 f_init(1);
2317
2318 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002319 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002320 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002321}
2322
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002323private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2324 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002325runs on test_CT
2326{
2327 var DchanTuple dt;
2328
2329 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2330 var BssmapCause cause := 0;
2331 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2332 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2333 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2334 }
2335
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002336 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 +02002337}
2338
2339/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2340testcase TC_chan_rel_rr_cause() runs on test_CT {
2341 f_init(1);
2342
2343 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2344 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2345 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2346 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2347 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2348 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002349
2350 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002351}
2352
Harald Welte5cd20ed2017-12-13 21:03:20 +01002353/* Test behavior if RSL EST IND for non-active channel */
2354testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2355 timer T := 2.0;
2356
Harald Welte89d42e82017-12-17 16:42:41 +01002357 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002358
2359 var octetstring l3 := '00010203040506'O;
2360 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002361 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002362
2363 T.start;
2364 alt {
2365 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2366 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2367 }
2368 [] BSSAP.receive {}
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002369 [] IPA_RSL[0][0].receive {}
Harald Welte5cd20ed2017-12-13 21:03:20 +01002370 [] T.timeout {}
2371 }
2372
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002373 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002374}
2375
2376/* Test behavior if RSL EST IND for invalid SAPI */
2377testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2378 var RslChannelNr chan_nr;
2379
Harald Welte89d42e82017-12-17 16:42:41 +01002380 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002381
2382 chan_nr := f_chreq_act_ack()
2383
2384 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002385 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002386
2387 timer T := 2.0;
2388 T.start;
2389 alt {
2390 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2391 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2392 }
2393 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002394 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002395 [] T.timeout {}
2396 }
2397
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002398 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002399}
2400
2401/* Test behavior if RSL EST IND for invalid SAPI */
2402testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2403 timer T := 2.0;
2404
Harald Welte89d42e82017-12-17 16:42:41 +01002405 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002406
2407 var RslChannelNr chan_nr := f_chreq_act_ack();
2408
2409 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002410 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002411
2412 T.start;
2413 alt {
2414 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2415 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2416 }
2417 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002418 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002419 [] T.timeout {}
2420 }
2421
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002422 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002423}
2424
2425/* Test behavior if RSL EST IND for invalid SACCH */
2426testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2427 timer T := 2.0;
2428
Harald Welte89d42e82017-12-17 16:42:41 +01002429 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002430
2431 var RslChannelNr chan_nr := f_chreq_act_ack();
2432
2433 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002434 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
Harald Welte5cd20ed2017-12-13 21:03:20 +01002435
2436 T.start;
2437 alt {
2438 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2439 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2440 }
2441 [] BSSAP.receive { repeat; }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002442 [] IPA_RSL[0][0].receive { repeat; }
Harald Welte5cd20ed2017-12-13 21:03:20 +01002443 [] T.timeout {}
2444 }
2445
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002446 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002447}
2448
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002449/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2450private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2451 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2452 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2453
2454 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2455 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2456
2457 f_establish_fully(ass_cmd, exp_compl);
2458
2459 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2460 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2461 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2462 BSSAP.receive(PDU_BSSAP:{
2463 discriminator := '1'B,
2464 spare := '0000000'B,
2465 dlci := 'C3'O,
2466 lengthIndicator := ?,
2467 pdu := { dtap := '0904'O }
2468 });
2469
2470 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2471 for (var integer i := 0; i < 32; i := i + 1) {
2472 var octetstring l3 := '09'O & f_rnd_octstring(14);
2473 var template (value) RslLinkId link_id;
2474 var template (value) OCT1 dlci;
2475
2476 if (i mod 2 == 0) {
2477 /* SAPI0 on FACCH or SDCCH */
2478 link_id := ts_RslLinkID_DCCH(0);
2479 dlci := '80'O;
2480 } else {
2481 /* SAPI3 on SACCH */
2482 link_id := ts_RslLinkID_SACCH(3);
2483 dlci := 'C3'O;
2484 }
2485
2486 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002487 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002488 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002489 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002490 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002491 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002492}
2493testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2494 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2495 var MSC_ConnHdlr vc_conn;
2496
2497 f_init(1, true);
2498 f_sleep(1.0);
2499
2500 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2501 vc_conn.done;
2502
2503 f_shutdown_helper();
2504}
2505
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002506private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002507 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002508 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002509 float T_val := 2.0)
2510runs on test_CT {
2511 var BSSAP_N_DATA_ind rx_di;
2512 timer T;
2513
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002514 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2515 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002516
2517 T.start(T_val);
2518 alt {
2519 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2520 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2521 if (not match(rx_cause, tr_cause)) {
2522 setverdict(fail, "Rx unexpected Cause IE: ",
2523 rx_cause, " vs expected ", tr_cause);
2524 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002525
2526 /* Who ever on the earth decided to define this field as two separate bits?!? */
2527 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2528 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2529 if (not match(rx_cc, cc)) {
2530 setverdict(fail, "Rx unexpected Control Channel type: ",
2531 rx_cc, " vs expected ", cc);
2532 }
2533
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002534 setverdict(pass);
2535 }
2536 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2537 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2538 }
2539 [] T.timeout {
2540 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2541 }
2542 }
2543}
2544
2545/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2546testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2547 var octetstring rnd_data := f_rnd_octstring(16);
2548 var RSL_Message rx_rsl;
2549 var DchanTuple dt;
2550
2551 f_init(1);
2552
2553 /* MS establishes a SAPI=0 link on DCCH */
2554 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2555
2556 /* MSC sends some data on (not yet established) SAPI=3 link */
2557 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2558 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002559 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 +07002560
2561 /* MS sends unexpected RELease INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002562 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002563 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2564 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2565
2566 /* Clean up the connection */
2567 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002568 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002569
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002570 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002571}
2572
2573/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2574testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2575 var octetstring rnd_data := f_rnd_octstring(16);
2576 var RSL_Message rx_rsl;
2577 var DchanTuple dt;
2578
2579 f_init(1);
2580
2581 /* MS establishes a SAPI=0 link on DCCH */
2582 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2583
2584 /* MSC sends some data on (not yet established) SAPI=3 link */
2585 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2586 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002587 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 +07002588
2589 /* BTS sends unexpected ERROR INDication on SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002590 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002591 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2592 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2593
2594 /* Clean up the connection */
2595 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002596 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002597
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002598 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002599}
2600
2601/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2602testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2603 var octetstring rnd_data := f_rnd_octstring(16);
2604 var RSL_Message rx_rsl;
2605 var DchanTuple dt;
2606
2607 f_init(1);
2608
2609 /* MS establishes a SAPI=0 link on DCCH */
2610 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2611
2612 /* MSC sends some data on (not yet established) SAPI=3 link */
2613 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2614 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002615 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 +07002616
2617 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2618 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2619
2620 /* Clean up the connection */
2621 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002622 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002623
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002624 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002625}
2626
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002627/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2628testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
2629 var octetstring rnd_data := f_rnd_octstring(16);
2630 var RSL_Message rx_rsl;
2631 var DchanTuple dt;
2632
2633 f_init(1);
2634
2635 /* MS establishes a SAPI=0 link on DCCH */
2636 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2637
2638 /* MSC sends some data on (not yet established) SAPI=3 link */
2639 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2640 /* BSC attempts to establish a SAPI=3 link on DCCH */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002641 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 +07002642
2643 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002644 f_ipa_tx(ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002645 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002646
2647 /* Clean up the connection */
2648 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002649 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002650
2651 f_shutdown_helper();
2652}
2653
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002654testcase TC_si_default() runs on test_CT {
2655 f_init(0);
2656 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002657 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002658}
Harald Welte4003d112017-12-09 22:35:39 +01002659
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002660/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2661 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2662private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2663{
2664 select (earfcn_index) {
2665 case (0) {
2666 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2667 return 111;
2668 }
2669 case (1) {
2670 return 1;
2671 }
2672 case (2) {
2673 return 0;
2674 }
2675 case (3) {
2676 return 65535;
2677 }
2678 case else {
2679 return 23 * (earfcn_index - 3);
2680 }
2681 }
2682}
2683
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002684function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2685 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002686
2687 f_init(0);
2688
2689 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2690 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002691 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2692 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002693 }
2694
2695 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2696
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002697 if (not istemplatekind(expect_cells, "omit")) {
2698 /* Also check that RR Channel Release contains these EARFCNs.
2699 * (copied code from TC_chan_rel_hard_clear_csfb) */
2700 var BSSAP_N_DATA_ind rx_di;
2701 var DchanTuple dt;
2702
2703 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002704 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2705 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2706 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002707
2708 /* Instruct BSC to clear channel */
2709 var BssmapCause cause := 0;
2710 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2711
2712 /* expect Clear Complete from BSC on A */
2713 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2714 /* release the SCCP connection */
2715 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2716 }
2717
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002718 f_expect_chan_rel(dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002719 }
2720
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002721 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002722 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 +02002723 }
2724}
2725
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002726private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2727{
2728 var template SI2quaterRestOctetsList si2quater := {};
2729 var integer si2quater_count := (count + 2) / 3;
2730
2731 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002732 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002733 var integer index := i / 3;
2734 var integer earfcn_index := i mod 3;
2735 if (index >= lengthof(si2quater)) {
2736 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2737 }
2738 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);
2739 }
2740
2741 return si2quater;
2742}
2743
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002744private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2745{
2746 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2747
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002748 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002749 for (var integer i := 0; i < count; i := i + 1) {
2750 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002751 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002752 }
2753
2754 return tr_CellSelIndValue_EUTRAN(cells);
2755}
2756
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002757private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2758{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002759 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002760 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002761 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2762 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002763}
2764
2765testcase TC_si2quater_2_earfcns() runs on test_CT {
2766 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002767 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002768}
2769
2770testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002771 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002772 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002773}
2774
2775testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002776 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002777 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002778}
2779
2780testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002781 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002782 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002783}
2784
2785testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002786 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002787 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002788}
2789
2790testcase TC_si2quater_12_earfcns() runs on test_CT {
2791 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002792 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002793}
2794
2795testcase TC_si2quater_23_earfcns() runs on test_CT {
2796 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002797 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002798}
2799
2800testcase TC_si2quater_32_earfcns() runs on test_CT {
2801 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002802 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002803}
2804
2805testcase TC_si2quater_33_earfcns() runs on test_CT {
2806 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002807 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002808}
2809
2810testcase TC_si2quater_42_earfcns() runs on test_CT {
2811 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002812 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002813}
2814
2815testcase TC_si2quater_48_earfcns() runs on test_CT {
2816 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002817 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002818}
2819
2820/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2821 * 48 EARFCNs. */
2822testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002823 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002824 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2825 f_init(0);
2826
2827 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002828 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2829 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002830 }
2831
2832 /* The 49th EARFCN no longer fits, expect VTY error */
2833 f_vty_enter_cfg_bts(BSCVTY, 0);
2834 var charstring vty_error;
2835 vty_error := f_vty_transceive_ret(BSCVTY,
2836 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2837 f_vty_transceive(BSCVTY, "end");
2838
2839 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2840 log("Got expected VTY error: ", vty_error);
2841 setverdict(pass);
2842 } else {
2843 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2844 }
2845
2846 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2847
2848 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002849 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 +02002850 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002851 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002852}
2853
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002854private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2855{
2856 var uint8_t count := 0;
2857 for (var integer i := 5; i < 16; i := i + 1) {
2858 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2859 count := count + 1;
2860 }
2861 }
2862 return count;
2863}
2864
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002865private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2866{
2867 var ASP_RSL_Unitdata rx_rsl_ud;
2868 var SystemInformationType1 last_si1;
2869
2870 timer T := 30.0;
2871 T.start;
2872 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002873 [] IPA_RSL[rsl_idx][0].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2874 tr_RSL_BCCH_INFO,
2875 tr_RSL_NO_SACCH_FILL,
2876 tr_RSL_SACCH_FILL))) -> value rx_rsl_ud {
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002877 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2878 if (g_system_information[rsl_idx].si1 == omit) {
2879 repeat;
2880 }
2881 last_si1 := g_system_information[rsl_idx].si1;
2882 g_system_information[rsl_idx].si1 := omit;
2883 T.stop;
2884 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06002885 [] IPA_RSL[rsl_idx][0].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002886 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2887 }
2888 return last_si1;
2889}
2890
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002891/* verify ACC rotate feature */
2892testcase TC_si_acc_rotate() runs on test_CT {
2893 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002894 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002895 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002896 var uint8_t count;
2897 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2898
2899 f_init(0, guard_timeout := 60.0);
2900
2901 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2902 "access-control-class-rotate 3",
2903 "access-control-class-rotate-quantum 1"});
2904
2905 /* Init and get first sysinfo */
2906 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2907
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002908 for (var integer i:= 0; i < 20; i := i + 1) {
2909 last_si1 := f_recv_next_si1(0);
2910 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002911 count := f_acc09_count_allowed(acc);
2912 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2913
2914 if (count != 3) {
2915 log("RSL: EXPECTED SI ACC len=3");
2916 setverdict(fail, "received SI does not match expectations");
2917 break;
2918 }
2919
2920 for (var integer j := 0; j < 10; j := j + 1) {
2921 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2922 times_allowed[j] := times_allowed[j] + 1;
2923 }
2924 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002925 }
2926
2927 for (var integer j := 0; j < 10; j := j + 1) {
2928 log("ACC", j, " allowed ", times_allowed[j], " times" );
2929 if (j != 5 and times_allowed[j] < 3) {
2930 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2931 } else if (j == 5 and times_allowed[j] > 0) {
2932 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2933 }
2934 }
2935
2936 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2937 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002938 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002939}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002940
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002941/* verify ACC startup ramp+rotate feature */
2942testcase TC_si_acc_ramp_rotate() runs on test_CT {
2943 var template SystemInformationConfig sic := SystemInformationConfig_default;
2944 var SystemInformationType1 last_si1;
2945 var AccessControlClass acc;
2946 var ASP_RSL_Unitdata rx_rsl_ud;
2947 var uint8_t count;
2948 var uint8_t prev_count;
2949 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2950
2951 f_init(0, guard_timeout := 80.0);
2952
2953 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2954 "access-control-class-rotate 0",
2955 "access-control-class-rotate-quantum 1",
2956 "access-control-class-ramping",
2957 "access-control-class-ramping-step-interval 5",
2958 "access-control-class-ramping-step-size 5"});
2959
2960 /* Init and get first sysinfo */
2961 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2962 last_si1 := g_system_information[0].si1;
2963 acc := last_si1.rach_control.acc;
2964 count := f_acc09_count_allowed(acc);
2965 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2966 while (count > 0) {
2967 last_si1 := f_recv_next_si1(0);
2968 acc := last_si1.rach_control.acc;
2969 count := f_acc09_count_allowed(acc);
2970 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2971 }
2972
2973 /* Increase adm subset size, we should see ramping start up */
2974 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2975 prev_count := 0;
2976 while (true) {
2977 last_si1 := f_recv_next_si1(0);
2978 acc := last_si1.rach_control.acc;
2979 count := f_acc09_count_allowed(acc);
2980 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2981
2982 if (prev_count > count) {
2983 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2984 break;
2985 }
2986
2987 if (count == 9) {
2988 break; /* Maximum reached (10 - 1 perm barred), done here */
2989 }
2990
2991 prev_count := count;
2992 }
2993
2994 setverdict(pass);
2995
2996 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2997 "rach access-control-class 4 allowed",
2998 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002999 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02003000}
3001
Harald Welte4003d112017-12-09 22:35:39 +01003002testcase TC_ctrl_msc_connection_status() runs on test_CT {
3003 var charstring ctrl_resp;
3004
Harald Welte89d42e82017-12-17 16:42:41 +01003005 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003006
3007 /* See https://osmocom.org/issues/2729 */
3008 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003009 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01003010}
3011
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003012testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3013 var charstring ctrl_resp;
3014
3015 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003016
3017 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003018 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003019}
3020
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003021/* Verify correct stats on the number of configured and connected MSCs */
3022private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3023 g_pars := f_gen_test_hdlr_pars();
3024 var StatsDExpects expect := {
3025 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3026 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3027 };
3028 f_statsd_expect(expect);
3029}
3030
3031private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3032{
3033 var MSC_ConnHdlr vc_conn;
3034
3035 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3036 f_sleep(1.0);
3037 vc_conn := f_start_handler(tc_fn);
3038 vc_conn.done;
3039
3040 /* Also verify stat exposed on CTRL interface */
3041 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3042 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3043
3044 f_shutdown_helper();
3045}
3046
3047/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3048private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3049 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3050}
3051testcase TC_stat_num_msc_connected_1() runs on test_CT {
3052 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3053}
3054
3055/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3056private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3057 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3058}
3059testcase TC_stat_num_msc_connected_2() runs on test_CT {
3060 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3061}
3062
3063/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3064private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3065 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3066}
3067testcase TC_stat_num_msc_connected_3() runs on test_CT {
3068 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3069}
3070
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003071/* Verify correct stats on the number of configured and connected MSCs */
3072private 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 +06003073 var integer num_trx_connected := 0;
3074 var integer num_trx_total := 0;
3075
3076 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3077 var integer trx_num := c_BtsParams[i].trx_num;
3078 num_trx_total := num_trx_total + trx_num;
3079 if (i < expect_num_bts_connected) {
3080 num_trx_connected := num_trx_connected + trx_num;
3081 }
3082 }
3083
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003084 var StatsDExpects expect := {
3085 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3086 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3087 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003088 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := num_trx_connected, max := num_trx_connected },
3089 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := num_trx_total, max := num_trx_total }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003090 };
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003091
3092 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003093 f_statsd_expect(expect);
3094}
3095
3096private 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 +06003097 var integer num_trx_connected := 0;
3098 var integer num_trx_total := 0;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003099 var MSC_ConnHdlr vc_conn;
3100
3101 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3102 f_sleep(1.0);
3103 vc_conn := f_start_handler(tc_fn);
3104 vc_conn.done;
3105
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003106 for (var integer i := 0; i < lengthof(c_BtsParams); i := i + 1) {
3107 var integer trx_num := c_BtsParams[i].trx_num;
3108 num_trx_total := num_trx_total + trx_num;
3109 if (i < nr_bts) {
3110 num_trx_connected := num_trx_connected + trx_num;
3111 }
3112 }
3113
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003114 /* Also verify stat exposed on CTRL interface */
3115 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3116 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 +06003117 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(num_trx_connected));
3118 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 +02003119
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003120 /* Verify rf_states exposed on CTRL interface */
3121 var charstring expect_net_rf_states := "";
3122 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003123 var charstring expect_bts_rf_states := "";
3124
3125 for (var integer j := 0; j < c_BtsParams[i].trx_num; j := j + 1) {
3126 expect_bts_rf_states := expect_bts_rf_states &
3127 int2str(i) & "," & int2str(j) & ",";
3128 if (i < NUM_BTS) {
3129 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3130 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3131 } else {
3132 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3133 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3134 }
3135 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3136 expect_bts_rf_states := expect_bts_rf_states & "on,";
3137 if (i < nr_bts) {
3138 /* For BTS where RSL is connected, the RSL state will be "up" */
3139 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3140 } else {
3141 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3142 }
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003143 }
3144
3145 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3146 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3147 }
3148 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3149
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003150 f_shutdown_helper();
3151}
3152
3153/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3154private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3155 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3156}
3157testcase TC_stat_num_bts_connected_1() runs on test_CT {
3158 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3159}
3160
3161/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3162private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3163 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3164}
3165testcase TC_stat_num_bts_connected_2() runs on test_CT {
3166 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3167}
3168
3169/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3170private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3171 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3172}
3173testcase TC_stat_num_bts_connected_3() runs on test_CT {
3174 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3175}
3176
Harald Welte4003d112017-12-09 22:35:39 +01003177testcase TC_ctrl() runs on test_CT {
3178 var charstring ctrl_resp;
3179
Harald Welte89d42e82017-12-17 16:42:41 +01003180 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003181
3182 /* all below values must match the osmo-bsc.cfg config file used */
3183
Harald Welte6a129692018-03-17 17:30:14 +01003184 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3185 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003186 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003187
3188 var integer bts_nr := 0;
3189 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3190 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3191 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3192 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3193 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3194 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3195 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3196
3197 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3198 f_sleep(2.0);
3199 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3200 setverdict(fail, "oml-uptime not incrementing as expected");
3201 }
3202 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3203
3204 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3205
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003206 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003207}
3208
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003209/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3210 "location-state" over the SCCPlite IPA conn */
3211testcase TC_ctrl_location() runs on test_CT {
3212 var MSC_ConnHdlr vc_conn;
3213 var integer bts_nr := 0;
3214
3215 f_init(1, true);
3216 f_sleep(1.0);
3217
3218 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3219 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3220 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3221
3222 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3223 f_sleep(2.0);
3224
3225 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3226 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3227 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3228
3229 /* should match the one from config */
3230 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3231
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003232 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003233}
3234
Harald Welte6f521d82017-12-11 19:52:02 +01003235
3236/***********************************************************************
3237 * Paging Testing
3238 ***********************************************************************/
3239
3240type record Cell_Identity {
3241 GsmMcc mcc,
3242 GsmMnc mnc,
3243 GsmLac lac,
3244 GsmCellId ci
3245};
Harald Welte24135bd2018-03-17 19:27:53 +01003246private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003247private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003248
Harald Welte5d1a2202017-12-13 19:51:29 +01003249type set of integer BtsIdList;
3250
3251private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3252 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3253 if (bts_id == bts_ids[j]) {
3254 return true;
3255 }
3256 }
3257 return false;
3258}
Harald Welte6f521d82017-12-11 19:52:02 +01003259
3260/* core paging test helper function; used by most paging test cases */
3261private function f_pageing_helper(hexstring imsi,
3262 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003263 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003264 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003265 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003266{
3267 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003268 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003269 var RSL_Message rx_rsl;
3270 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003271 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003272
3273 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003274
3275 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003276 for (i := 0; i < NUM_BTS; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003277 IPA_RSL[i][0].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003278 }
Harald Welte6f521d82017-12-11 19:52:02 +01003279
3280 if (isvalue(rsl_chneed)) {
3281 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3282 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3283 } else {
3284 bssmap_chneed := omit;
3285 }
3286
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003287 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3288 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003289
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003290 if (not istemplatekind(tmsi, "omit")) {
3291 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003292 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003293 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003294 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003295
Harald Welte5d1a2202017-12-13 19:51:29 +01003296 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003297 rx_rsl := f_exp_ipa_rx(tr_RSL_PAGING_CMD(mi), idx := {bts_ids[i], 0});
Harald Welte5d1a2202017-12-13 19:51:29 +01003298 /* check channel type, paging group */
3299 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3300 setverdict(fail, "Paging for wrong paging group");
3301 }
3302 if (ispresent(rsl_chneed) and
3303 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3304 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3305 }
Harald Welte6f521d82017-12-11 19:52:02 +01003306 }
Harald Welte2fccd982018-01-31 15:48:19 +01003307 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003308 /* do a quick check on all not-included BTSs if they received paging */
3309 for (i := 0; i < NUM_BTS; i := i + 1) {
3310 timer T := 0.1;
3311 if (f_bts_in_list(i, bts_ids)) {
3312 continue;
3313 }
3314 T.start;
3315 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003316 [] IPA_RSL[i][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003317 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3318 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003319 [] IPA_RSL[i][0].receive { repeat; }
Harald Welte5d1a2202017-12-13 19:51:29 +01003320 [] T.timeout { }
3321 }
Harald Welte6f521d82017-12-11 19:52:02 +01003322 }
3323
3324 setverdict(pass);
3325}
3326
Harald Welte5d1a2202017-12-13 19:51:29 +01003327const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003328const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003329const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3330const BtsIdList c_BtsId_LAC2 := { 2 };
3331
Harald Welte6f521d82017-12-11 19:52:02 +01003332/* PAGING by IMSI + TMSI */
3333testcase TC_paging_imsi_nochan() runs on test_CT {
3334 var BSSMAP_FIELD_CellIdentificationList cid_list;
3335 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003336 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003337 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003338}
3339
3340/* PAGING by IMSI + TMSI */
3341testcase TC_paging_tmsi_nochan() runs on test_CT {
3342 var BSSMAP_FIELD_CellIdentificationList cid_list;
3343 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003344 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003345 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003346}
3347
3348/* Paging with different "channel needed' values */
3349testcase TC_paging_tmsi_any() runs on test_CT {
3350 var BSSMAP_FIELD_CellIdentificationList cid_list;
3351 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003352 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003353 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003354}
3355testcase TC_paging_tmsi_sdcch() runs on test_CT {
3356 var BSSMAP_FIELD_CellIdentificationList cid_list;
3357 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003358 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003359 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003360}
3361testcase TC_paging_tmsi_tch_f() runs on test_CT {
3362 var BSSMAP_FIELD_CellIdentificationList cid_list;
3363 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003364 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003365 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003366}
3367testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3368 var BSSMAP_FIELD_CellIdentificationList cid_list;
3369 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003370 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003371 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003372}
3373
3374/* Paging by CGI */
3375testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3376 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3377 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003378 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003379 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003380}
3381
3382/* Paging by LAC+CI */
3383testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3384 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3385 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003386 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003387 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003388}
3389
3390/* Paging by CI */
3391testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3392 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3393 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003394 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003395 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003396}
3397
3398/* Paging by LAI */
3399testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3400 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3401 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003402 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003403 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003404}
3405
3406/* Paging by LAC */
3407testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3408 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3409 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003410 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003411 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003412}
3413
3414/* Paging by "all in BSS" */
3415testcase TC_paging_imsi_nochan_all() runs on test_CT {
3416 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3417 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003418 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003419 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003420}
3421
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003422/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003423testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3424 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3425 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 +01003426 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003427 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003428}
Harald Welte6f521d82017-12-11 19:52:02 +01003429
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003430/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003431testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3432 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3433 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003434 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003435 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003436}
3437
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003438/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003439testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3440 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3441 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003442 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003443 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003444}
3445
Harald Welte6f521d82017-12-11 19:52:02 +01003446/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003447testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3448 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3449 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3450 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003451 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003452}
3453
3454/* Paging on empty list: Verify none of them page */
3455testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3456 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3457 cid_list := { cIl_LAC := { } };
3458 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003459 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003460}
3461
Stefan Sperling049a86e2018-03-20 15:51:00 +01003462/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3463testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3464 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3465 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3466 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3467 f_shutdown_helper();
3468}
3469
Harald Welte6f521d82017-12-11 19:52:02 +01003470/* Verify paging retransmission interval + count */
3471/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003472/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003473
Harald Weltee65d40e2017-12-13 00:09:06 +01003474/* Verify PCH load */
3475testcase TC_paging_imsi_load() runs on test_CT {
3476 var BSSMAP_FIELD_CellIdentificationList cid_list;
3477 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003478 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003479 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003480 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003481
3482 /* tell BSC there is no paging space anymore */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003483 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003484 f_sleep(0.2);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003485 IPA_RSL[0][0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003486
3487 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3488 * there would be 8 retransmissions during 4 seconds */
3489 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003490 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003491 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003492 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003493 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003494 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003495 }
Harald Welte2caa1062018-03-17 18:19:05 +01003496 [] T_retrans.timeout {
3497 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003498 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(0));
Harald Welte2caa1062018-03-17 18:19:05 +01003499 T_retrans.start;
3500 repeat;
3501 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003502 [] T.timeout {
3503 setverdict(pass);
3504 }
3505 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003506
3507 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003508}
3509
Harald Welte235ebf12017-12-15 14:18:16 +01003510/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003511testcase TC_paging_counter() runs on test_CT {
3512 var BSSMAP_FIELD_CellIdentificationList cid_list;
3513 timer T := 4.0;
3514 var integer i;
3515 var integer paging_attempted_bsc;
3516 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003517 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003518 var integer paging_expired_bts[NUM_BTS];
3519 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3520
3521 f_init();
3522
3523 /* read counters before paging */
3524 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003525 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3526 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3527 }
Harald Welte1ff69992017-12-14 12:31:17 +01003528 for (i := 0; i < NUM_BTS; i := i+1) {
3529 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3530 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3531 }
3532
3533 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3534
3535 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3536 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3537 for (i := 0; i < NUM_BTS; i := i+1) {
3538 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3539 paging_attempted_bts[i]+1);
3540 }
3541
3542 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3543 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003544 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3545 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3546 }
Harald Welte1ff69992017-12-14 12:31:17 +01003547 for (i := 0; i < NUM_BTS; i := i+1) {
3548 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3549 paging_expired_bts[i]+1);
3550 }
Harald Welte1ff69992017-12-14 12:31:17 +01003551
Philipp Maier282ca4b2018-02-27 17:17:00 +01003552 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003553}
3554
3555
Harald Welte10985002017-12-12 09:29:15 +01003556/* Verify paging stops after A-RESET */
3557testcase TC_paging_imsi_a_reset() runs on test_CT {
3558 var BSSMAP_FIELD_CellIdentificationList cid_list;
3559 timer T := 3.0;
3560 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003561 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003562
3563 /* Perform a BSSMAP Reset and wait for ACK */
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003564 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 +01003565 alt {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02003566 [] 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 +01003567 [] BSSAP.receive { repeat; }
3568 }
3569
Daniel Willmanncbef3982018-07-30 09:22:40 +02003570 /* Wait to avoid a possible race condition if a paging message is
3571 * received right before the reset ACK. */
3572 f_sleep(0.2);
3573
Harald Welte10985002017-12-12 09:29:15 +01003574 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003575 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003576 IPA_RSL[i][0].clear;
Philipp Maier1e6b4422018-02-23 14:02:13 +01003577 }
Harald Welte10985002017-12-12 09:29:15 +01003578
3579 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3580 T.start;
3581 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003582 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003583 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003584 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003585 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003586 [] IPA_RSL[1][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003587 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003588 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003589 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003590 [] IPA_RSL[2][0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003591 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003592 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003593 }
Harald Welte10985002017-12-12 09:29:15 +01003594 [] T.timeout {
3595 setverdict(pass);
3596 }
3597 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003598
3599 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003600}
Harald Welteae026692017-12-09 01:03:01 +01003601
Philipp Maierf45824a2019-08-14 14:44:10 +02003602/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3603 * paging response we can not know which MSC is in charge, so we will blindly
3604 * pick the first configured MSC. This behavior is required in order to make
3605 * MT-CSFB calls working because in those cases the BSC can not know that the
3606 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3607 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003608 */
3609testcase TC_paging_resp_unsol() runs on test_CT {
3610
3611 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003612 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003613
3614 var BSSAP_N_CONNECT_ind rx_c_ind;
3615 var DchanTuple dt;
3616 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003617 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003618
3619 /* Send CHAN RQD and wait for allocation; acknowledge it */
3620 dt.rsl_chan_nr := f_chreq_act_ack();
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003621 dt.idx := {0, 0};
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003622
3623 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003624 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 +01003625
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003626
Philipp Maierf45824a2019-08-14 14:44:10 +02003627 /* Expevct a CR with a matching Paging response on the A-Interface */
3628 T.start;
3629 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003630 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003631 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003632 dt.sccp_conn_id := rx_c_ind.connectionId;
3633 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003634 }
3635 [] BSSAP.receive {
3636 setverdict(fail, "Received unexpected message on A-Interface!");
3637 }
3638 [] T.timeout {
3639 setverdict(fail, "Received nothing on A-Interface!");
3640 }
3641 }
3642
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003643 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003644 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003645}
3646
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003647/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3648function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003649 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003650 var Hexstrings imsis := {};
3651 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003652 var integer rx_paging_num := 0;
3653 var integer i;
3654 timer T_rx := 60.0;
3655 timer T_load_ind := 1.0;
3656
3657 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003658 imsis := imsis & {f_gen_imsi(i)};
3659 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003660 }
3661
3662 f_init(1, guard_timeout := 100.0);
3663
3664 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003665 IPA_RSL[0][0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003666 if (send_pag_load_ind) {
3667 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003668 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(65535));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003669 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003670
3671 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003672 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003673 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 +02003674 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3675 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003676 }
3677
3678 T_rx.start;
3679 T_load_ind.start;
3680 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003681 [] 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 +02003682 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3683 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3684 var charstring imsi_str := hex2str(imsi_suffix);
3685 var integer imsi_idx := str2int(imsi_str);
3686 if (rx_paging_done[imsi_idx] == false) {
3687 rx_paging_done[imsi_idx] := true;
3688 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003689 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003690 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 +02003691 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003692 }
3693 if (rx_paging_num < num_subscribers) {
3694 repeat;
3695 }
3696 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003697 [] IPA_RSL[0][0].receive { repeat; }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003698 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003699 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3700 if (send_pag_load_ind) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003701 f_ipa_tx(ts_RSL_PAGING_LOAD_IND(40));
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003702 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003703 T_load_ind.start;
3704 repeat;
3705 }
3706 [] T_rx.timeout {
3707 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3708 mtc.stop;
3709 }
3710 }
3711
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003712 /* Drop OML connection to have all paging requests flushed: */
3713 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3714
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003715 f_shutdown_helper();
3716}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003717/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3718testcase TC_paging_500req() runs on test_CT {
3719 f_TC_paging_Nreq(500, true);
3720}
3721/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3722 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3723 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3724 * for current config yields ~8req/sec, so 480req/min maximum. */
3725testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3726 f_TC_paging_Nreq(450, false);
3727}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003728
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003729/* Test RSL link drop causes counter increment */
3730testcase TC_rsl_drop_counter() runs on test_CT {
3731 var integer rsl_fail;
3732
Harald Welte89d42e82017-12-17 16:42:41 +01003733 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003734
3735 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3736
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003737 f_ipa_rsl_stop(bts[0][0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003738
3739 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3740
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003741 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003742}
3743
3744/* TODO: Test OML link drop causes counter increment */
3745
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003746/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3747function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003748 var IPA_Client client;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003749 timer T := 10.0;
3750
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003751 client.id := "IPA-BTS0-TRX0-RSL";
3752 client.vc_IPA := IPA_Emulation_CT.create(client.id & "-IPA") alive;
3753 client.ccm_pars := c_IPA_default_ccm_pars;
3754 client.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
3755 client.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003756
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003757 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003758
3759 f_init_mgcp("VirtMSC");
3760
3761 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003762 map(client.vc_IPA:IPA_PORT, system:IPA);
3763 connect(client.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0][0]);
3764 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 +01003765
3766 /* wait for IPA OML link to connect and then disconnect */
3767 T.start;
3768 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003769 [] IPA_RSL[0][0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003770 T.stop;
3771 return true;
3772 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003773 [] IPA_RSL[0][0].receive { repeat }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003774 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003775 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003776 }
3777 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003778 return false;
3779}
3780
3781/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3782testcase TC_rsl_unknown_unit_id() runs on test_CT {
3783 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3784 setverdict(pass);
3785 } else {
3786 setverdict(fail, "Timeout RSL waiting for connection to close");
3787 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003788 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003789}
3790
3791
3792/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3793testcase TC_oml_unknown_unit_id() runs on test_CT {
3794 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3795 setverdict(pass);
3796 } else {
3797 setverdict(fail, "Timeout OML waiting for connection to close");
3798 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003799 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003800}
3801
3802
Harald Weltec1a2fff2017-12-17 11:06:19 +01003803/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003804 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003805 ***********************************************************************/
3806
Harald Welte6811d102019-04-14 22:23:14 +02003807import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003808import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003809import from RSL_Emulation all;
3810import from MSC_ConnectionHandler all;
3811
3812type function void_fn(charstring id) runs on MSC_ConnHdlr;
3813
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003814/* helper function to create and connect a MSC_ConnHdlr component
3815 * TODO: allow connecting to TRX1..N, not only TRX0 */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003816private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3817 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003818 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003819 connect(vc_conn:RSL, bts[0][0].rsl.vc_RSL:CLIENT_PT);
3820 connect(vc_conn:RSL_PROC, bts[0][0].rsl.vc_RSL:RSL_PROC);
3821 if (isvalue(bts[1][0])) {
3822 connect(vc_conn:RSL1, bts[1][0].rsl.vc_RSL:CLIENT_PT);
3823 connect(vc_conn:RSL1_PROC, bts[1][0].rsl.vc_RSL:RSL_PROC);
Philipp Maier956a92f2018-02-16 10:58:07 +01003824 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06003825 if (isvalue(bts[2][0])) {
3826 connect(vc_conn:RSL2, bts[2][0].rsl.vc_RSL:CLIENT_PT);
3827 connect(vc_conn:RSL2_PROC, bts[2][0].rsl.vc_RSL:RSL_PROC);
Neels Hofmeyr91401012019-07-11 00:42:35 +02003828 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003829 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003830 if (mp_enable_lcs_tests) {
3831 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3832 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3833 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003834 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003835 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003836 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003837}
3838
Neels Hofmeyrda436782021-07-20 22:09:06 +02003839function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003840runs on test_CT return MSC_ConnHdlr {
3841 var charstring id := testcasename();
3842 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003843 var integer bssap_idx := 0;
3844 if (isvalue(pars)) {
3845 bssap_idx := valueof(pars).mscpool.bssap_idx;
3846 }
Harald Welte336820c2018-05-31 20:34:52 +02003847 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003848 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003849 return vc_conn;
3850}
3851
3852function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3853runs on test_CT return MSC_ConnHdlr {
3854 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003855 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003856 return vc_conn;
3857}
3858
Neels Hofmeyrda436782021-07-20 22:09:06 +02003859function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3860runs on test_CT return MSC_ConnHdlr {
3861 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3862}
3863
Harald Weltea0630032018-03-20 21:09:55 +01003864/* first function inside ConnHdlr component; sets g_pars + starts function */
3865private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3866runs on MSC_ConnHdlr {
3867 if (isvalue(pars)) {
3868 g_pars := valueof(pars);
3869 }
3870 fn.apply(id);
3871}
3872
Oliver Smith26a3db72021-07-09 13:51:29 +02003873private function f_vty_encryption_a5(charstring options) runs on test_CT {
3874 f_vty_transceive(BSCVTY, "configure terminal");
3875 f_vty_transceive(BSCVTY, "network");
3876 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3877 f_vty_transceive(BSCVTY, "exit");
3878 f_vty_transceive(BSCVTY, "exit");
3879}
3880
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003881const charstring VTY_A5_DEFAULT := "0 1 3";
3882
Oliver Smith26a3db72021-07-09 13:51:29 +02003883private function f_vty_encryption_a5_reset() runs on test_CT {
3884 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003885 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003886}
3887
Harald Welte3c86ea02018-05-10 22:28:05 +02003888/* Establish signalling channel (non-assignment case) followed by cipher mode */
3889private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003890 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3891 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003892 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003893 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3894 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3895 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3896 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003897
Philipp Maier23000732018-05-18 11:25:37 +02003898 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003899 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003900}
3901testcase TC_ciph_mode_a5_0() runs on test_CT {
3902 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003903 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003904 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3905
3906 f_init(1, true);
3907 f_sleep(1.0);
3908 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3909 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003910 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003911}
3912testcase TC_ciph_mode_a5_1() runs on test_CT {
3913 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003914 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003915 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3916
3917 f_init(1, true);
3918 f_sleep(1.0);
3919 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3920 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003921 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003922}
Oliver Smith50b98122021-07-09 15:00:28 +02003923/* OS#4975: verify that A5/2 is preferred over A5/0 */
3924testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3925 var MSC_ConnHdlr vc_conn;
3926 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3927
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003928 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003929
3930 f_init(1, true);
3931 f_vty_encryption_a5("0 1 2 3");
3932 f_sleep(1.0);
3933 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3934 vc_conn.done;
3935 f_vty_encryption_a5_reset();
3936 f_shutdown_helper();
3937}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003938/* OS#4975: verify that A5/1 is preferred over A5/2 */
3939testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3940 var MSC_ConnHdlr vc_conn;
3941 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3942
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003943 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003944
3945 f_init(1, true);
3946 f_vty_encryption_a5("1 2");
3947 f_sleep(1.0);
3948 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3949 vc_conn.done;
3950 f_vty_encryption_a5_reset();
3951 f_shutdown_helper();
3952}
Harald Welte3c86ea02018-05-10 22:28:05 +02003953testcase TC_ciph_mode_a5_3() runs on test_CT {
3954 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003955 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003956 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3957
3958 f_init(1, true);
3959 f_sleep(1.0);
3960 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3961 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003962 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003963}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003964/* Establish a Signalling channel with A5/4 encryption. */
3965testcase TC_ciph_mode_a5_4() runs on test_CT {
3966 var MSC_ConnHdlr vc_conn;
3967 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3968 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003969
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003970 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003971 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003972 f_sleep(1.0);
3973 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3974 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003975 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003976 f_shutdown_helper();
3977}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003978/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3979private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3980 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3981 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3982 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3983 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3984
3985 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003986 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003987}
3988testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3989 var MSC_ConnHdlr vc_conn;
3990 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3991
3992 f_init(1, true);
3993 f_sleep(1.0);
3994 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3995 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003996 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003997}
3998
Harald Welte3c86ea02018-05-10 22:28:05 +02003999
4000/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02004001private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004002 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4003 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004004
Harald Welte552620d2017-12-16 23:21:36 +01004005 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4006 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01004007
Harald Weltea0630032018-03-20 21:09:55 +01004008 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004009 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004010}
Harald Welte552620d2017-12-16 23:21:36 +01004011testcase TC_assignment_fr_a5_0() runs on test_CT {
4012 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004013 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004014 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01004015
Harald Welte89d42e82017-12-17 16:42:41 +01004016 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004017 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004018 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004019 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004020 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004021}
Harald Welte552620d2017-12-16 23:21:36 +01004022testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01004023 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004024 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004025 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004026
Harald Welte89d42e82017-12-17 16:42:41 +01004027 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004028 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02004029 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4030 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004031 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02004032}
4033testcase TC_assignment_fr_a5_3() runs on test_CT {
4034 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02004035 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02004036 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01004037
Harald Welte651fcdc2018-05-10 20:23:16 +02004038 f_init(1, true);
4039 f_sleep(1.0);
4040 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01004041 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004042 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01004043}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004044/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
4045testcase TC_assignment_fr_a5_4() runs on test_CT {
4046 var MSC_ConnHdlr vc_conn;
4047 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4048 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
4049
4050 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004051 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004052 f_sleep(1.0);
4053 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
4054 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02004055 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02004056 f_shutdown_helper();
4057}
Harald Weltec1a2fff2017-12-17 11:06:19 +01004058
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02004059/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
4060testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
4061 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4062 var MSC_ConnHdlr vc_conn;
4063
4064 f_init(1, true);
4065 f_sleep(1.0);
4066
4067 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4068 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4069 vc_conn.done;
4070 f_shutdown_helper();
4071}
4072
Harald Welte552620d2017-12-16 23:21:36 +01004073/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4074private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004075 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004076 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004077 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004078
4079 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004080 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4081
Harald Weltea0630032018-03-20 21:09:55 +01004082 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004083 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004084}
Harald Welte552620d2017-12-16 23:21:36 +01004085testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4086 var MSC_ConnHdlr vc_conn;
4087
Harald Welte89d42e82017-12-17 16:42:41 +01004088 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004089 f_sleep(1.0);
4090
Harald Welte8863fa12018-05-10 20:15:27 +02004091 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004092 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004093 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004094}
4095
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004096private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4097 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4098 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004099
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004100 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4101 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4102
4103 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4104
4105 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004106
4107 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4108 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4109
4110 f_create_chan_and_exp();
4111 /* we should now have a COMPL_L3 at the MSC */
4112
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004113 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004114 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004115 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004116}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004117testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4118 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004119 var MSC_ConnHdlr vc_conn;
4120
Harald Welte89d42e82017-12-17 16:42:41 +01004121 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004122 f_sleep(1.0);
4123
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004124 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004125 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004126 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004127 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004128}
4129
4130
Harald Welte4532e0a2017-12-23 02:05:44 +01004131private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004132 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004133 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004134 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004135 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004136
4137 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004138 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004139
4140 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004141 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4142 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004143 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4144 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4145 };
4146 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004147 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004148}
4149
4150testcase TC_assignment_sign() runs on test_CT {
4151 var MSC_ConnHdlr vc_conn;
4152
4153 f_init(1, true);
4154 f_sleep(1.0);
4155
Harald Welte8863fa12018-05-10 20:15:27 +02004156 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004157 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004158 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004159}
4160
Harald Welte60aa5762018-03-21 19:33:13 +01004161/***********************************************************************
4162 * Codec (list) testing
4163 ***********************************************************************/
4164
4165/* check if the given rsl_mode is compatible with the a_elem */
4166private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4167return boolean {
4168 select (a_elem.codecType) {
4169 case (GSM_FR) {
4170 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4171 return true;
4172 }
4173 }
4174 case (GSM_HR) {
4175 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4176 return true;
4177 }
4178 }
4179 case (GSM_EFR) {
4180 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4181 return true;
4182 }
4183 }
4184 case (FR_AMR) {
4185 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4186 return true;
4187 }
4188 }
4189 case (HR_AMR) {
4190 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4191 return true;
4192 }
4193 }
4194 case else { }
4195 }
4196 return false;
4197}
4198
4199/* check if the given rsl_mode is compatible with the a_list */
4200private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4201return boolean {
4202 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4203 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4204 return true;
4205 }
4206 }
4207 return false;
4208}
4209
4210/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004211function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004212return BSSMAP_IE_ChannelType {
4213 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4214 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4215 select (a_elem.codecType) {
4216 case (GSM_FR) {
4217 ret.channelRateAndType := ChRate_TCHF;
4218 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4219 }
4220 case (GSM_HR) {
4221 ret.channelRateAndType := ChRate_TCHH;
4222 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4223 }
4224 case (GSM_EFR) {
4225 ret.channelRateAndType := ChRate_TCHF;
4226 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4227 }
4228 case (FR_AMR) {
4229 ret.channelRateAndType := ChRate_TCHF;
4230 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4231 }
4232 case (HR_AMR) {
4233 ret.channelRateAndType := ChRate_TCHH;
4234 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4235 }
4236 case else {
4237 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004238 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004239 }
4240 }
4241 return ret;
4242}
4243
Harald Weltea63b9102018-03-22 20:36:16 +01004244private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4245return template RSL_IE_Body {
4246 var template RSL_IE_Body mode_ie := {
4247 chan_mode := {
4248 len := ?,
4249 reserved := ?,
4250 dtx_d := ?,
4251 dtx_u := ?,
4252 spd_ind := RSL_SPDI_SPEECH,
4253 ch_rate_type := -,
4254 coding_alg_rate := -
4255 }
4256 }
4257
4258 select (a_elem.codecType) {
4259 case (GSM_FR) {
4260 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4261 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4262 }
4263 case (GSM_HR) {
4264 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4265 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4266 }
4267 case (GSM_EFR) {
4268 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4269 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4270 }
4271 case (FR_AMR) {
4272 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4273 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4274 }
4275 case (HR_AMR) {
4276 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4277 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4278 }
4279 }
4280 return mode_ie;
4281}
4282
Harald Welte60aa5762018-03-21 19:33:13 +01004283type record CodecListTest {
4284 BSSMAP_IE_SpeechCodecList codec_list,
4285 charstring id
4286}
4287type record of CodecListTest CodecListTests
4288
4289private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004290 f_assignment_codec(id);
4291}
4292
4293private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02004294 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
4295 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux_cn);
Harald Welte60aa5762018-03-21 19:33:13 +01004296
4297 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004298 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004299 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4300 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4301 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004302 if (isvalue(g_pars.expect_mr_s0_s7)) {
4303 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4304 g_pars.expect_mr_s0_s7;
4305 }
Harald Welte79f3f542018-05-25 20:02:37 +02004306 }
Harald Welte60aa5762018-03-21 19:33:13 +01004307 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4308 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004309 log("expecting ASS COMPL like this: ", exp_compl);
4310
4311 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004312
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004313 if (not g_pars.expect_channel_mode_modify) {
4314 /* Verify that the RSL-side activation actually matches our expectations */
4315 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004316
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004317 var RSL_IE_Body mode_ie;
4318 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4319 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004320 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004321 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004322 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4323 if (not match(mode_ie, t_mode_ie)) {
4324 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4325 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004326 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004327
4328 var RSL_IE_Body mr_conf;
4329 if (g_pars.expect_mr_conf_ie != omit) {
4330 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4331 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4332 mtc.stop;
4333 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004334 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004335
4336 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4337 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4338 g_pars.expect_mr_conf_ie);
4339 }
4340 } else {
4341 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4342 log("found RSL MR CONFIG IE: ", mr_conf);
4343 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4344 mtc.stop;
4345 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004346 }
4347 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004348
4349 if (do_perform_clear) {
4350 f_perform_clear();
4351 }
Harald Welte60aa5762018-03-21 19:33:13 +01004352}
4353
Philipp Maierd0e64b02019-03-13 14:15:23 +01004354private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4355
4356 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4357 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4358
4359 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004360 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004361 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4362 }
4363 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4364 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4365 log("expecting ASS FAIL like this: ", exp_fail);
4366
4367 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004368 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004369}
4370
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004371const CounterNameVals counternames_bsc_bts_assignment := {
4372 { "assignment:attempted", 0 },
4373 { "assignment:completed", 0 },
4374 { "assignment:stopped", 0 },
4375 { "assignment:no_channel", 0 },
4376 { "assignment:timeout", 0 },
4377 { "assignment:failed", 0 },
4378 { "assignment:error", 0 }
4379};
4380
4381const CounterNameVals counternames_bts_assignment := {
4382 { "assignment:attempted_sign", 0 },
4383 { "assignment:attempted_speech", 0 },
4384 { "assignment:completed_sign", 0 },
4385 { "assignment:completed_speech", 0 },
4386 { "assignment:stopped_sign", 0 },
4387 { "assignment:stopped_speech", 0 },
4388 { "assignment:no_channel_sign", 0 },
4389 { "assignment:no_channel_speech", 0 },
4390 { "assignment:timeout_sign", 0 },
4391 { "assignment:timeout_speech", 0 },
4392 { "assignment:failed_sign", 0 },
4393 { "assignment:failed_speech", 0 },
4394 { "assignment:error_sign", 0 },
4395 { "assignment:error_speech", 0 }
4396};
4397
4398function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4399 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4400 f_ctrs_bts_init(bts_count, bts_names);
4401 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4402}
4403
Harald Welte60aa5762018-03-21 19:33:13 +01004404testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004405 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004406 var MSC_ConnHdlr vc_conn;
4407
4408 f_init(1, true);
4409 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004410 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004411
4412 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004413 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004414 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004415
4416 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4417 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4418 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4419 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4420 f_ctrs_bts_verify();
4421
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004422 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004423}
4424
4425testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004426 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004427 var MSC_ConnHdlr vc_conn;
4428
4429 f_init(1, true);
4430 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004431 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004432
4433 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004434 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004435 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004436
4437 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4438 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4439 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4440 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4441 f_ctrs_bts_verify();
4442
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004443 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004444}
4445
4446testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004447 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004448 var MSC_ConnHdlr vc_conn;
4449
4450 f_init(1, true);
4451 f_sleep(1.0);
4452
4453 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004454 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004455 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004456 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004457}
4458
Philipp Maierd0e64b02019-03-13 14:15:23 +01004459/* Allow 5,90k only (current default config) */
4460private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004461 f_vty_cfg_msc(BSCVTY, 0, {
4462 "amr-config 12_2k forbidden",
4463 "amr-config 10_2k forbidden",
4464 "amr-config 7_95k forbidden",
4465 "amr-config 7_40k forbidden",
4466 "amr-config 6_70k forbidden",
4467 "amr-config 5_90k allowed",
4468 "amr-config 5_15k forbidden",
4469 "amr-config 4_75k forbidden"
4470 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004471}
4472
4473/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4474 * ("Config-NB-Code = 1") */
4475private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004476 f_vty_cfg_msc(BSCVTY, 0, {
4477 "amr-config 12_2k allowed",
4478 "amr-config 10_2k forbidden",
4479 "amr-config 7_95k forbidden",
4480 "amr-config 7_40k allowed",
4481 "amr-config 6_70k forbidden",
4482 "amr-config 5_90k allowed",
4483 "amr-config 5_15k forbidden",
4484 "amr-config 4_75k allowed"
4485 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004486}
4487
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004488private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4489 var charstring tch;
4490 if (fr) {
4491 tch := "tch-f";
4492 } else {
4493 tch := "tch-h";
4494 }
4495 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4496}
4497
4498/* Set the AMR start-mode for this TCH back to the default configuration. */
4499private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4500 f_vty_amr_start_mode_set(fr, "auto");
4501}
4502
Harald Welte60aa5762018-03-21 19:33:13 +01004503testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004504 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004505 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004506
4507 /* Note: This setups the codec configuration. The parameter payload in
4508 * mr_conf must be consistant with the parameter codecElements in pars
4509 * and also must match the amr-config in osmo-bsc.cfg! */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004510 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004511 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004512 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +02004513 pars.expect_mr_conf_ie := mr_conf_amr_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004514
Harald Welte60aa5762018-03-21 19:33:13 +01004515 f_init(1, true);
4516 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004517 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004518 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004519
Harald Welte8863fa12018-05-10 20:15:27 +02004520 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004521 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004522
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004523 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4524 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4525 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4526 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4527 f_ctrs_bts_verify();
4528
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004529 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004530 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004531}
4532
4533testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004534 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004535 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004536
4537 /* See note above */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004538 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004539 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004540 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +02004541 pars.expect_mr_conf_ie := mr_conf_amr_5_90;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004542
Harald Welte60aa5762018-03-21 19:33:13 +01004543 f_init(1, true);
4544 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004545 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004546 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004547
Harald Welte8863fa12018-05-10 20:15:27 +02004548 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004549 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004550
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004551 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4552 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4553 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4554 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4555 f_ctrs_bts_verify();
4556
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004557 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004558 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004559}
4560
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004561/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4562testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4563 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4564 var MSC_ConnHdlr vc_conn;
4565
4566 f_init(1, true);
4567 f_sleep(1.0);
4568
4569 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4570 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4571 * expecting a Channel Mode Modify if the channel type is compatible. */
4572 f_disable_all_sdcch();
4573 f_disable_all_tch_h();
4574
4575 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4576 pars.expect_channel_mode_modify := true;
4577 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4578 vc_conn.done;
4579
4580 f_enable_all_sdcch();
4581 f_enable_all_tch();
4582 f_shutdown_helper();
4583}
4584
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004585/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4586testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4587 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4588 var MSC_ConnHdlr vc_conn;
4589
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004590 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4591 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4592 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
Pau Espin Pedrolf7634dc2022-09-02 17:56:00 +02004593 /* expect ICMI=0, smod=00: */
4594 pars.expect_mr_conf_ie := valueof(RSL_IE_Body:{multirate_cfg := ts_RSL_MultirateCfg(false, 0, '00000100'B /* 5,90k */)});
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004595
4596 f_init(1, true);
4597 f_sleep(1.0);
4598
4599 /* First set nonzero start mode bits */
4600 f_vty_amr_start_mode_set(true, "4");
4601 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4602 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4603 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4604 f_vty_amr_start_mode_set(true, "auto");
4605
4606 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4607 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004608
4609 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4610 f_vty_amr_start_mode_set(true, "1");
4611 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004612 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004613}
4614
Neels Hofmeyr21863562020-11-26 00:34:33 +00004615function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4616 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004617runs on test_CT {
4618
4619 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4620 var MSC_ConnHdlr vc_conn;
4621
4622 /* See note above */
4623 var RSL_IE_Body mr_conf := {
4624 other := {
4625 len := lengthof(mrconf),
4626 payload := mrconf
4627 }
4628 };
4629
4630 if (fr) {
4631 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4632 } else {
4633 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4634 }
4635 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4636 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4637 pars.expect_mr_conf_ie := mr_conf;
4638 pars.expect_mr_s0_s7 := exp_s8_s0;
4639
4640 f_init(1, true);
4641 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004642 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004643 f_sleep(1.0);
4644
4645 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4646 vc_conn.done;
4647 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004648 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004649}
4650
4651function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4652runs on test_CT {
4653
4654 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4655 var MSC_ConnHdlr vc_conn;
4656
4657 if (fr) {
4658 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4659 } else {
4660 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4661 }
4662 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4663 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4664
4665 f_init(1, true);
4666 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004667 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004668 f_sleep(1.0);
4669
4670 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4671 vc_conn.done;
4672 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004673 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004674}
4675
4676
4677/* Set S1, we expect an AMR multirate configuration IE with all four rates
4678 * set. */
4679testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004680 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004681 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004682}
4683
4684/* Set S1, we expect an AMR multirate configuration IE with the lower three
4685 * rates set. */
4686testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004687 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004688 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004689}
4690
4691/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4692 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4693testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004694 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004695 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004696}
4697
4698/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4699 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4700testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004701 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004702 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004703}
4704
4705/* The following block of tests selects more and more rates until all four
4706 * possible rates are in the active set (full rate) */
4707testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004708 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004709 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004710}
4711
4712testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004713 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004714 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004715}
4716
4717testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004718 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004719 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004720}
4721
4722testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004723 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004724 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004725}
4726
4727/* The following block of tests selects more and more rates until all three
4728 * possible rates are in the active set (half rate) */
4729testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004730 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004731 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004732}
4733
4734testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004735 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004736 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004737}
4738
4739testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004740 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004741 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004742}
4743
4744/* The following block tests what happens when the MSC does offer rate
4745 * configurations that are not supported by the BSC. Normally such situations
4746 * should not happen because the MSC gets informed by the BSC in advance via
4747 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4748 * to offer rates that are not applicable anyway. */
4749
4750testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004751 /* Try to include 12,2k in into the active set even though the channel
4752 * is half rate only. The BSC is expected to remove the 12,0k */
4753 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'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_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004758 /* See what happens when all rates are selected at once. Since then
4759 * Also S1 is selected, this setting will be prefered and we should
4760 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4761 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004762 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004763}
4764
4765testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004766 /* Same as above, but with S1 missing, the MSC is then expected to
4767 * select the currently supported rates, which are also 12.2k, 7,40k,
4768 * 5,90k, and 4,75k, into the active set. */
4769 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004770 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004771}
4772
4773testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004774 /* Try to select no rates at all */
4775 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004776 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004777}
4778
4779testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004780 /* Try to select only unsupported rates */
4781 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004782 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004783}
4784
4785testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004786 /* Try to select 12,2k for half rate */
4787 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004788 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004789}
4790
Neels Hofmeyr21863562020-11-26 00:34:33 +00004791testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4792 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4793 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004794 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004795}
4796
4797testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4798 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4799 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004800 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004801}
4802
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004803testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004804 /* "amr tch-f modes 0 2 4 7" => total 4 modes and start mode 4 => '11'B on the wire */
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004805 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4806 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004807 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004808}
4809
4810testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004811 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4812 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004813 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004814 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004815}
4816
Philipp Maierac09bfc2019-01-08 13:41:39 +01004817private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004818 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4819 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4820 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4821 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004822}
4823
4824private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004825 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4826 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004827}
4828
4829private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004830 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4831 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4832 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4833 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4834 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4835 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004836}
4837
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004838private function f_disable_all_sdcch() runs on test_CT {
4839 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4840 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4841 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4842 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4843}
4844
4845private function f_enable_all_sdcch() runs on test_CT {
4846 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4847 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4848 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4849 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4850}
4851
Philipp Maierac09bfc2019-01-08 13:41:39 +01004852/* Allow HR only */
4853private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4854 g_pars := f_gen_test_hdlr_pars();
4855 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4856 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4857 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4858 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4859 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4860 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4861 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004862 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004863}
4864
4865/* Allow FR only */
4866private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4867 g_pars := f_gen_test_hdlr_pars();
4868 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4869 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4870 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4871 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4872 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4873 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4874 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004875 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004876}
4877
4878/* Allow HR only (expect assignment failure) */
4879private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4880 g_pars := f_gen_test_hdlr_pars();
4881 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4882 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4883 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4884 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4885 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4886 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4887 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004888 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004889}
4890
4891/* Allow FR only (expect assignment failure) */
4892private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4893 g_pars := f_gen_test_hdlr_pars();
4894 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4895 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4896 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4897 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4898 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4899 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4900 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004901 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004902}
4903
4904/* Allow FR and HR, but prefer FR */
4905private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4906 g_pars := f_gen_test_hdlr_pars();
4907 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4908 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4909 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4910 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4911 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4912 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4913 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4914 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004915 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004916}
4917
4918/* Allow FR and HR, but prefer HR */
4919private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4920 g_pars := f_gen_test_hdlr_pars();
4921 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4922 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4923 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4924 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4925 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4926 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4927 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4928 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004929 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004930}
4931
4932/* Allow FR and HR, but prefer FR */
4933private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4934 g_pars := f_gen_test_hdlr_pars();
4935 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4936 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4937 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4938 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4939 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4940 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4941 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4942 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004943 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004944}
4945
4946/* Allow FR and HR, but prefer HR */
4947private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4948 g_pars := f_gen_test_hdlr_pars();
4949 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4950 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4951 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4952 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4953 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4954 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4955 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4956 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004957 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004958}
4959
4960/* Request a HR channel while all FR channels are exhausted, this is expected
4961 * to work without conflicts */
4962testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4963 var MSC_ConnHdlr vc_conn;
4964 f_init(1, true);
4965 f_sleep(1.0);
4966 f_enable_all_tch();
4967 f_disable_all_tch_f();
4968 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4969 vc_conn.done;
4970 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004971 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004972}
4973
4974/* Request a FR channel while all FR channels are exhausted, this is expected
4975 * to fail. */
4976testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4977 var MSC_ConnHdlr vc_conn;
4978 f_init(1, true);
4979 f_sleep(1.0);
4980 f_enable_all_tch();
4981 f_disable_all_tch_f();
4982 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4983 vc_conn.done;
4984 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004985 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004986}
4987
4988/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4989 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4990testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4991 var MSC_ConnHdlr vc_conn;
4992 f_init(1, true);
4993 f_sleep(1.0);
4994 f_enable_all_tch();
4995 f_disable_all_tch_f();
4996 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4997 vc_conn.done;
4998 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004999 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005000}
5001
5002/* Request a HR (prefered) or alternatively a FR channel while all FR channels
5003 * are exhausted, this is expected to work without conflicts. */
5004testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
5005 var MSC_ConnHdlr vc_conn;
5006 f_init(1, true);
5007 f_sleep(1.0);
5008 f_enable_all_tch();
5009 f_disable_all_tch_f();
5010 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
5011 vc_conn.done;
5012 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005013 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005014}
5015
5016/* Request a FR channel while all HR channels are exhausted, this is expected
5017 * to work without conflicts */
5018testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
5019 var MSC_ConnHdlr vc_conn;
5020 f_init(1, true);
5021 f_sleep(1.0);
5022 f_enable_all_tch();
5023 f_disable_all_tch_h();
5024 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
5025 vc_conn.done;
5026 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005027 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005028}
5029
5030/* Request a HR channel while all HR channels are exhausted, this is expected
5031 * to fail. */
5032testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
5033 var MSC_ConnHdlr vc_conn;
5034 f_init(1, true);
5035 f_sleep(1.0);
5036 f_enable_all_tch();
5037 f_disable_all_tch_h();
5038 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
5039 vc_conn.done;
5040 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005041 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005042}
5043
5044/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5045 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5046testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5047 var MSC_ConnHdlr vc_conn;
5048 f_init(1, true);
5049 f_sleep(1.0);
5050 f_enable_all_tch();
5051 f_disable_all_tch_h();
5052 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5053 vc_conn.done;
5054 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005055 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005056}
5057
5058/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5059 * are exhausted, this is expected to work without conflicts. */
5060testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5061 var MSC_ConnHdlr vc_conn;
5062 f_init(1, true);
5063 f_sleep(1.0);
5064 f_enable_all_tch();
5065 f_disable_all_tch_h();
5066 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5067 vc_conn.done;
5068 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005069 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005070}
5071
5072/* Allow FR and HR, but prefer HR */
5073private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5074 g_pars := f_gen_test_hdlr_pars();
5075 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5076 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5077 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5078 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5079 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5080 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5081 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5082 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005083 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005084}
5085
5086/* Allow FR and HR, but prefer FR */
5087private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5088 g_pars := f_gen_test_hdlr_pars();
5089 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5090 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5091 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5092 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5093 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5094 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5095 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5096 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005097 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005098}
5099
5100/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5101 * HR, which is the prefered type, is selected. */
5102testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5103 var MSC_ConnHdlr vc_conn;
5104 f_init(1, true);
5105 f_sleep(1.0);
5106 f_enable_all_tch();
5107 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5108 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005109 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005110}
5111
5112/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5113 * FR, which is the prefered type, is selected. */
5114testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5115 var MSC_ConnHdlr vc_conn;
5116 f_init(1, true);
5117 f_sleep(1.0);
5118 f_enable_all_tch();
5119 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5120 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005121 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005122}
5123
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005124/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5125private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5126 g_pars := f_gen_test_hdlr_pars();
5127 g_pars.ra := '02'O; /* RA containing reason=LU */
5128
5129 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5130 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5131 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5132 var template uint3_t tsc := ?;
5133
5134 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5135 f_create_bssmap_exp(l3_enc);
5136 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5137 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5138
5139 /* we should now have a COMPL_L3 at the MSC */
5140 timer T := 10.0;
5141 T.start;
5142 alt {
5143 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5144 [] T.timeout {
5145 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5146 }
5147 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005148
5149 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005150}
5151testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5152 var MSC_ConnHdlr vc_conn;
5153 f_init(1, true);
5154 f_sleep(1.0);
5155 f_disable_all_sdcch();
5156 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5157 vc_conn.done;
5158 f_enable_all_sdcch();
5159 f_shutdown_helper();
5160}
5161
5162/* Request a signalling channel with all SDCCH exhausted, it is
5163 expected that no TCH will be selected for signalling and assigment will fail
5164 because it's dictated by VTY config */
5165testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5166 var RSL_Message rsl_unused, rsl_msg;
5167 var GsmRrMessage rr;
5168 f_init(1, false);
5169 f_sleep(1.0);
5170 f_vty_allow_tch_for_signalling(false, 0);
5171 f_disable_all_sdcch();
5172
5173 /* RA containing reason=LU */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005174 f_ipa_tx(ts_RSL_CHAN_RQD('02'O, 2342));
5175 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005176 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5177 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5178 setverdict(fail, "Expected reject");
5179 }
5180
5181 f_vty_allow_tch_for_signalling(true, 0);
5182 f_enable_all_sdcch();
5183 f_shutdown_helper();
5184}
5185
5186/* Request a voice channel with all SDCCH exhausted, it is
5187 * expected that TCH channel will be allocated since the VTY option is only
5188 * aimed at signalling requests */
5189private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5190 g_pars := f_gen_test_hdlr_pars();
5191 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5192
5193 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5194 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5195 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5196 var template uint3_t tsc := ?;
5197
5198 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5199 f_create_bssmap_exp(l3_enc);
5200 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5201 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5202
5203 /* we should now have a COMPL_L3 at the MSC */
5204 timer T := 10.0;
5205 T.start;
5206 alt {
5207 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5208 [] T.timeout {
5209 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5210 }
5211 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005212 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005213}
5214testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5215 var MSC_ConnHdlr vc_conn;
5216 f_init(1, true);
5217 f_sleep(1.0);
5218 f_vty_allow_tch_for_signalling(false, 0);
5219 f_disable_all_sdcch();
5220
5221 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5222 vc_conn.done;
5223
5224 f_vty_allow_tch_for_signalling(true, 0);
5225 f_enable_all_sdcch();
5226 f_shutdown_helper();
5227}
5228
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005229testcase TC_assignment_osmux() runs on test_CT {
5230 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5231 var MSC_ConnHdlr vc_conn;
5232
5233 /* See note above */
5234 var RSL_IE_Body mr_conf := {
5235 other := {
5236 len := 2,
5237 payload := '2804'O
5238 }
5239 };
5240
5241 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5242 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5243 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
5244 pars.expect_mr_conf_ie := mr_conf;
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +02005245 pars.use_osmux_cn := true;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005246
Pau Espin Pedrol9b941492022-08-08 18:26:17 +02005247 g_osmux_enabled_cn := true;
5248 f_init(1, true);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005249 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005250 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005251
5252 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5253 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005254
5255 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005256 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005257}
5258
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005259/* test the procedure of the MSC requesting a Classmark Update:
5260 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5261 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005262private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005263 g_pars := f_gen_test_hdlr_pars();
5264
Harald Weltea0630032018-03-20 21:09:55 +01005265 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005266 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005267
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005268 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5269 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5270
Harald Welte898113b2018-01-31 18:32:21 +01005271 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5272 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5273 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005274
5275 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005276}
5277testcase TC_classmark() runs on test_CT {
5278 var MSC_ConnHdlr vc_conn;
5279 f_init(1, true);
5280 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005281 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005282 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005283 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005284}
5285
Harald Welteeddf0e92020-06-21 19:42:15 +02005286/* Send a CommonID from the simulated MSC and verify that the information is used to
5287 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5288private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5289 g_pars := f_gen_test_hdlr_pars();
5290 f_MscConnHdlr_init_vty();
5291
5292 f_create_chan_and_exp();
5293 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005294
5295 /* Send CommonID */
5296 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5297
5298 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5299 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5300 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5301
5302 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005303
5304 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005305}
5306testcase TC_common_id() runs on test_CT {
5307 var MSC_ConnHdlr vc_conn;
5308 f_init(1, true);
5309 f_sleep(1.0);
5310 vc_conn := f_start_handler(refers(f_tc_common_id));
5311 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005312 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005313}
5314
Harald Weltee3bd6582018-01-31 22:51:25 +01005315private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005316 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005317 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005318 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005319
Harald Weltee3bd6582018-01-31 22:51:25 +01005320 /* send the single message we want to send */
5321 f_rsl_send_l3(l3);
5322}
5323
5324private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5325 timer T := sec;
5326 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005327 T.start;
5328 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005329 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5330 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005331 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005332 }
5333 [] T.timeout {
5334 setverdict(pass);
5335 }
5336 }
5337}
5338
Harald Weltee3bd6582018-01-31 22:51:25 +01005339/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5340private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5341 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5342 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005343 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005344}
Harald Welte898113b2018-01-31 18:32:21 +01005345testcase TC_unsol_ass_fail() runs on test_CT {
5346 var MSC_ConnHdlr vc_conn;
5347 f_init(1, true);
5348 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005349 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005350 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005351 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005352}
Harald Welte552620d2017-12-16 23:21:36 +01005353
Harald Welteea99a002018-01-31 20:46:43 +01005354
5355/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5356private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005357 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5358 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005359 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005360}
5361testcase TC_unsol_ass_compl() runs on test_CT {
5362 var MSC_ConnHdlr vc_conn;
5363 f_init(1, true);
5364 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005365 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005366 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005367 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005368}
5369
5370
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005371/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5372private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005373 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5374 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005375 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005376}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005377testcase TC_unsol_ho_fail() runs on test_CT {
5378 var MSC_ConnHdlr vc_conn;
5379 f_init(1, true);
5380 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005381 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005382 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005383 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005384}
5385
5386
Harald Weltee3bd6582018-01-31 22:51:25 +01005387/* short message from MS should be ignored */
5388private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005389 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005390 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005391 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005392
5393 /* send short message */
5394 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5395 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005396 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005397}
5398testcase TC_err_82_short_msg() runs on test_CT {
5399 var MSC_ConnHdlr vc_conn;
5400 f_init(1, true);
5401 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005402 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005403 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005404 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005405}
5406
5407
Harald Weltee9e02e42018-01-31 23:36:25 +01005408/* 24.008 8.4 Unknown message must trigger RR STATUS */
5409private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5410 f_est_single_l3(ts_RRM_UL_REL('00'O));
5411 timer T := 3.0
5412 alt {
5413 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5414 setverdict(pass);
5415 }
5416 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005417 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005418 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005419 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005420}
5421testcase TC_err_84_unknown_msg() runs on test_CT {
5422 var MSC_ConnHdlr vc_conn;
5423 f_init(1, true);
5424 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005425 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005426 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005427 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005428}
5429
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005430/***********************************************************************
5431 * Handover
5432 ***********************************************************************/
5433
Harald Welte94e0c342018-04-07 11:33:23 +02005434/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5435private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5436runs on test_CT {
5437 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5438 " timeslot "&int2str(ts_nr)&" ";
5439 f_vty_transceive(BSCVTY, cmd & suffix);
5440}
5441
Harald Welte261af4b2018-02-12 21:20:39 +01005442/* 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 +07005443private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5444 uint8_t bts_nr, uint8_t trx_nr,
5445 in RslChannelNr chan_nr)
5446{
Harald Welte261af4b2018-02-12 21:20:39 +01005447 /* FIXME: resolve those from component-global state */
5448 var integer ts_nr := chan_nr.tn;
5449 var integer ss_nr;
5450 if (ischosen(chan_nr.u.ch0)) {
5451 ss_nr := 0;
5452 } else if (ischosen(chan_nr.u.lm)) {
5453 ss_nr := chan_nr.u.lm.sub_chan;
5454 } else if (ischosen(chan_nr.u.sdcch4)) {
5455 ss_nr := chan_nr.u.sdcch4.sub_chan;
5456 } else if (ischosen(chan_nr.u.sdcch8)) {
5457 ss_nr := chan_nr.u.sdcch8.sub_chan;
5458 } else {
5459 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005460 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005461 }
5462
5463 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5464 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005465 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005466}
5467
Neels Hofmeyr91401012019-07-11 00:42:35 +02005468/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5469 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5470 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5471 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5472 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005473private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5474 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5475{
5476 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005477}
5478
5479/* intra-BSC hand-over between BTS0 and BTS1 */
5480private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005481 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5482 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005483
5484 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5485 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5486
Harald Weltea0630032018-03-20 21:09:55 +01005487 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005488 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005489
5490 var HandoverState hs := {
5491 rr_ho_cmpl_seen := false,
5492 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005493 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005494 expect_target_tsc := c_BtsParams[1].tsc
Harald Welte261af4b2018-02-12 21:20:39 +01005495 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005496 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005497 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005498 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5499 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005500
5501 /* From the MGW perspective, a handover is is characterized by
5502 * performing one MDCX operation with the MGW. So we expect to see
5503 * one more MDCX during handover. */
5504 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5505
Harald Welte261af4b2018-02-12 21:20:39 +01005506 alt {
5507 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005508 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005509
Philipp Maier4dae0652018-11-12 12:03:26 +01005510 /* Since this is an internal handover we expect the BSC to inform the
5511 * MSC about the event */
5512 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5513
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005514 /* Check the amount of MGCP transactions is still consistant with the
5515 * test expectation */
5516 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005517
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005518 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5519
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005520 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5521 * 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 +02005522 f_verify_encr_info(chan_act);
5523
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005524 f_chan_act_verify_tsc(chan_act, c_BtsParams[1].tsc);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005525
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005526 f_perform_clear(RSL1, RSL1_PROC);
5527
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005528 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005529}
5530
5531testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005532 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005533 var MSC_ConnHdlr vc_conn;
5534 f_init(2, true);
5535 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005536
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005537 pars.expect_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005538
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005539 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005540
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005541 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005542 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005543
5544 /* from f_establish_fully() */
5545 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5546 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5547 /* from handover */
5548 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5549 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5550 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5551 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005552 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5553 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005554 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005555 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005556}
Harald Weltee9e02e42018-01-31 23:36:25 +01005557
Oliver Smith7eabd312021-07-12 14:18:56 +02005558function 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 +02005559 var MSC_ConnHdlr vc_conn;
5560 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5561 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5562
5563 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005564 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005565 f_sleep(1.0);
5566
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005567 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005568
5569 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5570 vc_conn.done;
5571
5572 /* from f_establish_fully() */
5573 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5574 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5575 /* from handover */
5576 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5577 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5578 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5579 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005580 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5581 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005582 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005583 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005584 f_shutdown_helper();
5585}
5586
5587testcase TC_ho_int_a5_0() runs on test_CT {
5588 f_tc_ho_int_a5('01'O);
5589}
5590
5591testcase TC_ho_int_a5_1() runs on test_CT {
5592 f_tc_ho_int_a5('02'O);
5593}
5594
5595testcase TC_ho_int_a5_3() runs on test_CT {
5596 f_tc_ho_int_a5('08'O);
5597}
5598
5599testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005600 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005601}
5602
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005603/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5604private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5605 g_pars := f_gen_test_hdlr_pars();
5606 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5607 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005608
5609 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5610 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5611
5612 f_establish_fully(ass_cmd, exp_compl);
5613 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5614
5615 var HandoverState hs := {
5616 rr_ho_cmpl_seen := false,
5617 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005618 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06005619 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005620 };
5621 /* issue hand-over command on VTY */
5622 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5623 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5624 f_rslem_suspend(RSL1_PROC);
5625
5626 /* From the MGW perspective, a handover is is characterized by
5627 * performing one MDCX operation with the MGW. So we expect to see
5628 * one more MDCX during handover. */
5629 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5630
5631 var RSL_Message rsl;
5632 var PDU_ML3_NW_MS l3;
5633 var RslChannelNr new_chan_nr;
5634 var GsmArfcn arfcn;
5635 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5636 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5637 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5638 setverdict(fail, "Expected handoverCommand");
5639 mtc.stop;
5640 }
5641 }
5642 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5643 new_chan_nr, arfcn);
5644
5645 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5646
5647 /* resume processing of RSL DChan messages, which was temporarily suspended
5648 * before performing a hand-over */
5649 f_rslem_resume(RSL1_PROC);
5650 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5651
5652 f_sleep(1.0);
5653
5654 /* Handover fails because no HANDO DET appears on the new lchan,
5655 * and the old lchan reports a Radio Link Failure. */
5656 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5657
5658 var PDU_BSSAP rx_clear_request;
5659 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5660 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5661 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5662
5663 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5664
5665 var MgcpCommand mgcp;
5666 interleave {
5667 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5668 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005669 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005670 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005671 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005672 }
5673 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005674 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005675 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005676 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005677 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005678 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5679 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5680 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005681 }
5682
5683 f_sleep(0.5);
5684 setverdict(pass);
5685}
5686testcase TC_ho_int_radio_link_failure() runs on test_CT {
5687 var MSC_ConnHdlr vc_conn;
5688 f_init(2, true);
5689 f_sleep(1.0);
5690
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005691 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005692
5693 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5694 vc_conn.done;
5695
5696 /* from f_establish_fully() */
5697 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5698 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5699 /* from handover */
5700 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5701 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5702 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5703 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005704 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5705 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005706 f_ctrs_bsc_and_bts_verify();
5707 f_shutdown_helper();
5708}
5709
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005710/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005711private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005712 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005713 var template MgcpResponse mgcp_resp;
5714 var MGCP_RecvFrom mrf;
5715 var template MgcpMessage msg_resp;
5716 var template MgcpMessage msg_dlcx := {
5717 command := tr_DLCX()
5718 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005719
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005720 if (g_pars.aoip) {
5721 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005722 log("Got first DLCX: ", mgcp);
5723 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005724 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005725
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005726 MGCP.receive(tr_DLCX()) -> value mgcp {
5727 log("Got second DLCX: ", mgcp);
5728 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5729 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005730 } else {
5731 /* For SCCPLite, BSC doesn't handle the MSC-side */
5732 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5733 log("Got first DLCX: ", mrf.msg.command);
5734 msg_resp := {
5735 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5736 }
5737 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5738 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005739 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005740}
5741
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005742private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005743
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005744 var NcellReports neighbor_rep := {
5745 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5746 };
5747 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5748 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5749 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005750
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005751 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005752
5753 f_sleep(0.5);
5754 /* The MSC negotiates Handover Request and Handover Request Ack with
5755 * the other BSS and comes back with a BSSMAP Handover Command
5756 * containing an RR Handover Command coming from the target BSS... */
5757
5758 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5759 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5760 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5761 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5762 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5763
5764 /* expect the Handover Command to go out on RR */
5765 var RSL_Message rsl_ho_cmd
5766 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5767 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5768 var RSL_IE_Body rsl_ho_cmd_l3;
5769 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5770 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5771 setverdict(fail);
5772 } else {
5773 log("Found L3 Info: ", rsl_ho_cmd_l3);
5774 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5775 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5776 setverdict(fail);
5777 } else {
5778 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5779 setverdict(pass);
5780 }
5781 }
5782
5783 /* When the other BSS has reported a completed handover, this side is
5784 * torn down. */
5785
5786 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5787 var BssmapCause cause := enum2int(cause_val);
5788 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5789
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005790 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005791
5792 interleave {
5793 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5794 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5795 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005796 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5797 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5798 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005799 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005800 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005801}
5802
5803private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5804 g_pars := f_gen_test_hdlr_pars();
5805 var PDU_BSSAP ass_req := f_gen_ass_req();
5806 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5807 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5808 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5809 f_establish_fully(ass_req, exp_compl);
5810
5811 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005812}
5813testcase TC_ho_out_of_this_bsc() runs on test_CT {
5814 var MSC_ConnHdlr vc_conn;
5815
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005816 f_init_vty();
5817 f_bts_0_cfg(BSCVTY,
5818 {"neighbor-list mode automatic",
5819 "handover 1",
5820 "handover algorithm 2",
5821 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005822 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005823 "neighbor lac 99 arfcn 123 bsic any"});
5824 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5825
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005826 f_init(1, true);
5827 f_sleep(1.0);
5828
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005829 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005830
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005831 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5832 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005833
5834 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5835 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5836 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5837 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5838 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5839 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5840 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005841 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005842}
5843
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005844private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5845 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005846 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005847 octetstring l3 := '0123456789'O)
5848runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005849 /* The old lchan and conn should still be active. See that arbitrary L3
5850 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005851 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005852 var template PDU_BSSAP exp_data := {
5853 discriminator := '1'B,
5854 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005855 dlci := dlci,
5856 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005857 pdu := {
5858 dtap := l3
5859 }
5860 };
5861 BSSAP.receive(exp_data);
5862 setverdict(pass);
5863}
5864
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005865private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5866 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005867 template (value) OCT1 dlci := '00'O,
5868 octetstring l3 := '0123456789'O)
5869runs on MSC_ConnHdlr {
5870 BSSAP.send(PDU_BSSAP:{
5871 discriminator := '1'B,
5872 spare := '0000000'B,
5873 dlci := dlci,
5874 lengthIndicator := lengthof(l3),
5875 pdu := {
5876 dtap := l3
5877 }
5878 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005879 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005880 setverdict(pass);
5881}
5882
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005883/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5884 * simply never sends a BSSMAP Handover Command. */
5885private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005886 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005887
5888 var PDU_BSSAP ass_req := f_gen_ass_req();
5889 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5890 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5891 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5892 f_establish_fully(ass_req, exp_compl);
5893
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005894 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005895 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5896
5897 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5898
5899 /* osmo-bsc should time out 10 seconds after the handover started.
5900 * Let's give it a bit extra. */
5901 f_sleep(15.0);
5902
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005903 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005904 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005905 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005906}
5907testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5908 var MSC_ConnHdlr vc_conn;
5909
5910 f_init(1, true);
5911 f_sleep(1.0);
5912
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005913 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005914
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005915 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5916 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005917
5918 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5919 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5920 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5921 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5922 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5923 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5924 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005925 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005926}
5927
5928/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5929 * RR Handover Failure. */
5930private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005931 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005932
5933 var PDU_BSSAP ass_req := f_gen_ass_req();
5934 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5935 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5936 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5937 f_establish_fully(ass_req, exp_compl);
5938
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005939 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005940 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5941
5942 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5943
5944 f_sleep(0.5);
5945 /* The MSC negotiates Handover Request and Handover Request Ack with
5946 * the other BSS and comes back with a BSSMAP Handover Command
5947 * containing an RR Handover Command coming from the target BSS... */
5948
5949 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5950 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5951 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5952 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5953 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5954
5955 /* expect the Handover Command to go out on RR */
5956 var RSL_Message rsl_ho_cmd
5957 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5958 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5959 var RSL_IE_Body rsl_ho_cmd_l3;
5960 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5961 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5962 setverdict(fail);
5963 } else {
5964 log("Found L3 Info: ", rsl_ho_cmd_l3);
5965 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5966 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5967 setverdict(fail);
5968 } else {
5969 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5970 setverdict(pass);
5971 }
5972 }
5973
5974 f_sleep(0.2);
5975 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5976
5977 /* Should tell the MSC about the failure */
5978 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5979
5980 f_sleep(1.0);
5981
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005982 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005983 f_sleep(1.0);
5984
5985 setverdict(pass);
5986 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005987 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005988}
5989testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5990 var MSC_ConnHdlr vc_conn;
5991
5992 f_init(1, true);
5993 f_sleep(1.0);
5994
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005995 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005996
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005997 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5998 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005999
6000 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6001 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6002 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6003 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6004 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6005 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
6006 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006007 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006008}
6009
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006010/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
6011 * (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 +02006012 * and the lchan is released. */
6013private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01006014 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006015
6016 var PDU_BSSAP ass_req := f_gen_ass_req();
6017 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6018 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6019 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6020 f_establish_fully(ass_req, exp_compl);
6021
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006022 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006023 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
6024
6025 BSSAP.receive(tr_BSSMAP_HandoverRequired);
6026
6027 f_sleep(0.5);
6028 /* The MSC negotiates Handover Request and Handover Request Ack with
6029 * the other BSS and comes back with a BSSMAP Handover Command
6030 * containing an RR Handover Command coming from the target BSS... */
6031
6032 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6033 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
6034 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6035 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
6036 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
6037
6038 /* expect the Handover Command to go out on RR */
6039 var RSL_Message rsl_ho_cmd
6040 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
6041 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
6042 var RSL_IE_Body rsl_ho_cmd_l3;
6043 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
6044 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6045 setverdict(fail);
6046 } else {
6047 log("Found L3 Info: ", rsl_ho_cmd_l3);
6048 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6049 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6050 setverdict(fail);
6051 } else {
6052 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6053 setverdict(pass);
6054 }
6055 }
6056
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006057 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6058 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6059 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006060
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006061 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006062 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6063 log("Got BSSMAP Clear Request");
6064 /* Instruct BSC to clear channel */
6065 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6066 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6067
6068 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006069 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006070 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6071 log("Got Deact SACCH");
6072 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006073 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006074 log("Got RR Release");
6075 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006076 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006077 log("Got RF Chan Rel");
6078 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006079 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006080 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006081 }
6082
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006083 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006084 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006085 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006086
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006087 setverdict(pass);
6088 f_sleep(1.0);
6089}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006090testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006091 var MSC_ConnHdlr vc_conn;
6092
6093 f_init(1, true);
6094 f_sleep(1.0);
6095
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006096 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006097
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006098 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006099 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006100
6101 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6102 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6103 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6104 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6105 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6106 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6107 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006108 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006109}
6110
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006111private 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 +01006112 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006113 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6114 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6115 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6116 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6117 * before we get started. */
6118 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6119 f_rslem_register(0, new_chan_nr);
6120 g_chan_nr := new_chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06006121 var uint3_t expect_target_tsc := c_BtsParams[0].tsc;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006122 f_sleep(1.0);
6123
6124 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6125 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006126 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006127
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006128 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6129 cell_id_source := g_pars.cell_id_source,
6130 oldToNewBSSIEs := oldToNewBSSIEs,
6131 enc := g_pars.encr);
6132 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6133 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6134 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6135 } else {
6136 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6137 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6138 BSSAP.send(ho_req);
6139 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006140
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006141 alt {
6142 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6143 if (g_pars.expect_ho_fail) {
6144 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6145 "Expected Handover Request to fail, but got Handover Request Ack")
6146 }
6147 }
6148 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6149 if (not g_pars.expect_ho_fail) {
6150 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6151 "Expected Handover Request to succeed, but got Handover Failure")
6152 }
6153 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6154 // For now just accept any cause.
6155 BSSAP.receive(tr_BSSMAP_ClearRequest);
6156 setverdict(pass);
6157 return;
6158 }
6159 }
6160
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006161 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6162
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006163 /* we're sure that the channel activation is done now, verify the parameters in it */
6164 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6165 f_verify_encr_info(chan_act);
6166 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006167
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006168 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6169 if (not g_pars.aoip) {
6170 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6171 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6172 }
6173 /* TODO: check actual codecs? */
6174 } else {
6175 if (g_pars.aoip) {
6176 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6177 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6178 }
6179 }
6180
6181 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6182 if (not g_pars.aoip) {
6183 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6184 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6185 }
6186 /* TODO: check actual codec? */
6187 } else {
6188 if (g_pars.aoip) {
6189 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6190 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6191 }
6192 }
6193
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006194 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006195 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6196 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6197 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6198 log("L3 Info in HO Request Ack is ", ho_command);
6199
6200 var GsmArfcn arfcn;
6201 var RslChannelNr actual_new_chan_nr;
6202 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6203 actual_new_chan_nr, arfcn);
6204
6205 if (actual_new_chan_nr != new_chan_nr) {
6206 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6207 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6208 setverdict(fail);
6209 return;
6210 }
6211 log("Handover Command chan_nr is", actual_new_chan_nr);
6212
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006213 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6214 if (not match(got_tsc, expect_target_tsc)) {
6215 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6216 expect_target_tsc, " got ", got_tsc);
6217 mtc.stop;
6218 } else {
6219 log("handoverCommand: verified TSC = ", got_tsc);
6220 }
6221
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006222 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6223 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6224 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6225 var template (present) CipherModeSetting_TV tr_cms := {
6226 sC := '0'B, /* no ciphering by default */
6227 algorithmIdentifier := '000'B,
6228 elementIdentifier := ?
6229 };
6230 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6231 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6232 tr_cms.sC := '1'B;
6233 }
6234 if (not match(cms, tr_cms)) {
6235 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6236 cms, ", expected: ", tr_cms);
6237 }
6238 } else {
6239 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6240 }
6241
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006242 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6243 * tells the MS to handover to the new lchan. Here comes the new MS on
6244 * the new lchan with a Handover RACH: */
6245
6246 /* send handover detect */
6247
6248 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6249
6250 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6251
6252 /* send handover complete over the new channel */
6253
6254 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6255 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6256 enc_PDU_ML3_MS_NW(l3_tx)));
6257
6258 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006259 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006260 setverdict(pass);
6261}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006262
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006263private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006264 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006265 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6266 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6267 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006268 }
6269 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006270 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006271 } else {
6272 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006273 }
6274 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006275 if (g_pars.expect_ho_fail) {
6276 f_perform_clear_no_lchan();
6277 } else {
6278 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6279 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006280 setverdict(pass);
6281}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006282function 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 +01006283 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006284
6285 f_init(1, true);
6286 f_sleep(1.0);
6287
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006288 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006289 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006290
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006291 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6292 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006293
6294 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6295 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006296
6297 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006298 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006299 if (pars.expect_ho_fail) {
6300 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6301 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6302 } else {
6303 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6304 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6305 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006306 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006307
6308 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006309}
6310
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006311testcase TC_ho_into_this_bsc() runs on test_CT {
6312 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6313 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006314 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006315}
6316
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006317function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6318 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006319 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006320 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006321 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006322 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006323 f_shutdown_helper();
6324}
6325
6326testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006327 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006328}
6329
6330testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006331 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006332}
6333
6334testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006335 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006336}
6337
6338testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006339 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006340}
6341
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006342/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6343 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6344 *
6345 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6346 * omitted.
6347 *
6348 * Related: SYS#5839
6349 */
6350testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6351 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6352}
6353
6354testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6355 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6356}
6357
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006358/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6359testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6360 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6361 expect_fail := true); // 0x18 = A5/3 and A5/4
6362}
6363
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006364testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6365 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6366 pars.host_aoip_tla := "::6";
6367 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006368 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006369}
6370
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006371/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006372 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006373 channel is later released (RR CHannel Release), should trigger inclusion of
6374 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6375 neighbors. */
6376testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6377 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6378 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006379 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006380 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006381
6382 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6383 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6384 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006385 f_shutdown_helper();
6386}
6387
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006388/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6389testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6390 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6391 pars.encr := f_encr_params('08'O); /* only A5/3 */
6392 pars.last_used_eutran_plmn := '323454'O;
6393 pars.exp_fast_return := true;
6394 f_tc_ho_into_this_bsc_main(pars);
6395
6396 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6397 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6398 f_ctrs_bsc_and_bts_verify();
6399 f_shutdown_helper();
6400}
6401
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006402/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6403 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6404 list when the channel is released. */
6405testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6406 f_init_vty();
6407 f_vty_allow_srvcc_fast_return(true, 0)
6408
6409 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6410 pars.last_used_eutran_plmn := '323454'O;
6411 pars.exp_fast_return := false;
6412 f_tc_ho_into_this_bsc_main(pars);
6413 f_vty_allow_srvcc_fast_return(false, 0);
6414 f_shutdown_helper();
6415}
6416
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006417/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6418testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6419 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6420 pars.last_used_eutran_plmn := '323454'O;
6421 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6422 f_tc_ho_into_this_bsc_main(pars);
6423
6424 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6425 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6426 f_ctrs_bsc_and_bts_verify();
6427 f_shutdown_helper();
6428}
6429
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006430private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6431 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6432 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6433 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6434 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6435 setverdict(pass);
6436}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006437
6438private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6439 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006440 var MSC_ConnHdlr vc_conn;
6441 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6442
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006443 f_init_vty();
6444 f_bts_0_cfg(BSCVTY,
6445 {"neighbor-list mode automatic",
6446 "handover 1",
6447 "handover algorithm 2",
6448 "handover2 window rxlev averaging 1",
6449 "no neighbors",
6450 "neighbor lac 99 arfcn 123 bsic any"});
6451 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6452
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006453 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006454 if (disable_fast_return) {
6455 f_vty_allow_srvcc_fast_return(true, 0);
6456 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006457 f_sleep(1.0);
6458
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006459 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006460
6461 pars.last_used_eutran_plmn := '323454'O;
6462 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6463 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6464
6465 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6466 vc_conn.done;
6467
6468 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6469 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6470 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6471 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6472 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6473 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006474
6475 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6476 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006477 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006478
6479 if (disable_fast_return) {
6480 f_vty_allow_srvcc_fast_return(false, 0);
6481 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006482 f_shutdown_helper();
6483}
6484
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006485/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6486 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6487 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6488 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6489testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6490 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6491}
6492/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6493 * independently of fast-reture allowed/forbidden in local BTS */
6494testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6495 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6496}
6497
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006498private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6499 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6500 f_rslem_register(0, new_chan_nr);
6501 g_chan_nr := new_chan_nr;
6502 f_sleep(1.0);
6503
6504 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6505 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6506 activate(as_Media());
6507
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006508 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006509 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006510 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006511
6512 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6513
6514 var PDU_BSSAP rx_bssap;
6515 var octetstring ho_command_str;
6516
6517 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6518
6519 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6520 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6521 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6522 log("L3 Info in HO Request Ack is ", ho_command);
6523
6524 var GsmArfcn arfcn;
6525 var RslChannelNr actual_new_chan_nr;
6526 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6527 actual_new_chan_nr, arfcn);
6528
6529 if (actual_new_chan_nr != new_chan_nr) {
6530 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6531 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6532 setverdict(fail);
6533 return;
6534 }
6535 log("Handover Command chan_nr is", actual_new_chan_nr);
6536
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006537 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6538 f_sleep(1.0);
6539
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006540 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6541 * tells the MS to handover to the new lchan. In this case, the MS
6542 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6543 * Handover Failure to the MSC. The procedure according to 3GPP TS
6544 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6545 * BSSMAP Clear Command: */
6546
6547 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6548 var BssmapCause cause := enum2int(cause_val);
6549 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6550
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006551 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006552 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006553 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006554
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006555 setverdict(pass);
6556 f_sleep(1.0);
6557
6558 setverdict(pass);
6559}
6560testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6561 var MSC_ConnHdlr vc_conn;
6562 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6563
6564 f_init(1, true);
6565 f_sleep(1.0);
6566
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006567 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006568
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006569 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6570 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006571
6572 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6573 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006574
6575 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6576 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6577 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6578 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6579 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006580 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006581}
6582
6583private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6584 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6585 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6586 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6587 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6588 * before we get started. */
6589 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6590 f_rslem_register(0, new_chan_nr);
6591 g_chan_nr := new_chan_nr;
6592 f_sleep(1.0);
6593
6594 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6595 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6596 activate(as_Media());
6597
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006598 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006599 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006600 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006601
6602 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6603
6604 var PDU_BSSAP rx_bssap;
6605 var octetstring ho_command_str;
6606
6607 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6608
6609 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6610 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6611 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6612 log("L3 Info in HO Request Ack is ", ho_command);
6613
6614 var GsmArfcn arfcn;
6615 var RslChannelNr actual_new_chan_nr;
6616 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6617 actual_new_chan_nr, arfcn);
6618
6619 if (actual_new_chan_nr != new_chan_nr) {
6620 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6621 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6622 setverdict(fail);
6623 return;
6624 }
6625 log("Handover Command chan_nr is", actual_new_chan_nr);
6626
6627 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6628 * tells the MS to handover to the new lchan. Here comes the new MS on
6629 * the new lchan with a Handover RACH: */
6630
6631 /* send handover detect */
6632
6633 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6634
6635 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6636
6637 /* The MSC chooses to clear the connection now, maybe we got the
6638 * Handover RACH on the new cell but the MS still signaled Handover
6639 * Failure to the old BSS? */
6640
6641 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6642 var BssmapCause cause := enum2int(cause_val);
6643 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6644
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006645 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006646 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006647 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006648
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006649 f_sleep(1.0);
6650}
6651testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6652 var MSC_ConnHdlr vc_conn;
6653 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6654
6655 f_init(1, true);
6656 f_sleep(1.0);
6657
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006658 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006659
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006660 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6661 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006662
6663 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6664 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006665
6666 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6667 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6668 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6669 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6670 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006671 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006672}
6673
6674/* The new BSS's lchan times out before the MSC decides that handover failed. */
6675private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6676 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6677 f_rslem_register(0, new_chan_nr);
6678 g_chan_nr := new_chan_nr;
6679 f_sleep(1.0);
6680
6681 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6682 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006683 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006684
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006685 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006686 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006687 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006688
6689 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6690
6691 var PDU_BSSAP rx_bssap;
6692 var octetstring ho_command_str;
6693
6694 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6695
6696 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6697 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6698 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6699 log("L3 Info in HO Request Ack is ", ho_command);
6700
6701 var GsmArfcn arfcn;
6702 var RslChannelNr actual_new_chan_nr;
6703 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6704 actual_new_chan_nr, arfcn);
6705
6706 if (actual_new_chan_nr != new_chan_nr) {
6707 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6708 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6709 setverdict(fail);
6710 return;
6711 }
6712 log("Handover Command chan_nr is", actual_new_chan_nr);
6713
6714 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6715 * tells the MS to handover to the new lchan. But the MS never shows up
6716 * on the new lchan. */
6717
6718 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6719
6720 /* Did osmo-bsc also send a Clear Request? */
6721 timer T := 0.5;
6722 T.start;
6723 alt {
6724 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6725 [] T.timeout { }
6726 }
6727
6728 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6729 * asked for it, this is a Handover Failure after all). */
6730
6731 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6732 var BssmapCause cause := enum2int(cause_val);
6733 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6734
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006735 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006736 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006737 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006738
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006739 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006740}
6741testcase TC_ho_in_fail_no_detect() runs on test_CT {
6742 var MSC_ConnHdlr vc_conn;
6743 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6744
6745 f_init(1, true);
6746 f_sleep(1.0);
6747
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006748 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006749
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006750 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6751 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006752
6753 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6754 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006755
6756 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6757 f_ctrs_bsc_and_bts_add(0, "handover:error");
6758 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6759 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6760 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006761 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006762}
6763
6764/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6765private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6766 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6767 f_rslem_register(0, new_chan_nr);
6768 g_chan_nr := new_chan_nr;
6769 f_sleep(1.0);
6770
6771 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6772 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006773 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006774
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006775 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006776 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006777 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006778
6779 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6780
6781 var PDU_BSSAP rx_bssap;
6782 var octetstring ho_command_str;
6783
6784 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6785
6786 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6787 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6788 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6789 log("L3 Info in HO Request Ack is ", ho_command);
6790
6791 var GsmArfcn arfcn;
6792 var RslChannelNr actual_new_chan_nr;
6793 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6794 actual_new_chan_nr, arfcn);
6795
6796 if (actual_new_chan_nr != new_chan_nr) {
6797 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6798 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6799 setverdict(fail);
6800 return;
6801 }
6802 log("Handover Command chan_nr is", actual_new_chan_nr);
6803
6804 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6805 * tells the MS to handover to the new lchan. But the MS never shows up
6806 * on the new lchan. */
6807
6808 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6809
6810 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006811 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006812
6813 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006814 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6815 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6816 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006817 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006818 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006819 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006820
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006821 f_sleep(1.0);
6822}
6823testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6824 var MSC_ConnHdlr vc_conn;
6825 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6826
6827 f_init(1, true);
6828 f_sleep(1.0);
6829
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006830 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006831
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006832 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6833 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006834
6835 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6836 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006837
6838 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6839 f_ctrs_bsc_and_bts_add(0, "handover:error");
6840 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6841 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6842 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006843 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006844}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006845
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006846/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6847 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6848 * empty N-Connect case. */
6849testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6850 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6851 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6852 f_tc_ho_into_this_bsc_main(pars);
6853 f_shutdown_helper();
6854}
6855
Neels Hofmeyr91401012019-07-11 00:42:35 +02006856type record of charstring Commands;
6857
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006858private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006859{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006860 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006861 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006862 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006863 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006864 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006865}
6866
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006867private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6868{
6869 f_vty_enter_cfg_cs7_inst(pt, 0);
6870 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6871 f_vty_transceive(pt, cmds[i]);
6872 }
6873 f_vty_transceive(pt, "end");
6874}
6875
Neels Hofmeyr91401012019-07-11 00:42:35 +02006876private function f_probe_for_handover(charstring log_label,
6877 charstring log_descr,
6878 charstring handover_vty_cmd,
6879 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006880 boolean is_inter_bsc_handover := false,
6881 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006882runs on MSC_ConnHdlr
6883{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006884 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6885 * lchans to be established on bts 1 or bts 2. */
6886 f_rslem_suspend(RSL1_PROC);
6887 f_rslem_suspend(RSL2_PROC);
6888
Neels Hofmeyr91401012019-07-11 00:42:35 +02006889 var RSL_Message rsl;
6890
6891 var charstring log_msg := " (expecting handover)"
6892 if (not expect_handover) {
6893 log_msg := " (expecting NO handover)";
6894 }
6895 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6896 f_vty_transceive(BSCVTY, handover_vty_cmd);
6897
Neels Hofmeyr91401012019-07-11 00:42:35 +02006898 timer T := 2.0;
6899 T.start;
6900
6901 alt {
6902 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6903 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6904 log("Rx L3 from net: ", l3);
6905 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6906 var RslChannelNr new_chan_nr;
6907 var GsmArfcn arfcn;
6908 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6909 new_chan_nr, arfcn);
6910 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6911 log(l3.msgs.rrm.handoverCommand);
6912
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006913 /* Verify correct TSC in handoverCommand */
6914 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6915 if (not match(got_tsc, expect_target_tsc)) {
6916 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6917 expect_target_tsc, " got ", got_tsc);
6918 mtc.stop;
6919 } else {
6920 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6921 expect_target_tsc, ")");
6922 }
6923
Neels Hofmeyr91401012019-07-11 00:42:35 +02006924 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6925 * matter on which BTS it really is, we're not going to follow through an entire handover
6926 * anyway. */
6927 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6928 f_rslem_resume(RSL1_PROC);
6929 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6930 f_rslem_resume(RSL2_PROC);
6931
6932 if (expect_handover and not is_inter_bsc_handover) {
6933 setverdict(pass);
6934 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6935 } else {
6936 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6937 & log_label & ": " & log_descr);
6938 }
6939
6940 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6941 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6942 * Handover Failure. */
6943 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6944
6945 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6946 f_sleep(0.5);
6947 RSL1.clear;
6948 RSL2.clear;
6949 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6950 break;
6951 } else {
6952 repeat;
6953 }
6954 }
6955 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6956 if (expect_handover and is_inter_bsc_handover) {
6957 setverdict(pass);
6958 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6959 } else {
6960 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6961 & log_label & ": " & log_descr);
6962 }
6963
6964 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6965
6966 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6967 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6968 * setting a short timeout and waiting is the only way. */
6969 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6970 f_sleep(1.5);
6971 log("f_probe_for_handover(" & log_label & "): ...done");
6972
6973 break;
6974 }
6975 [] T.timeout {
6976 if (expect_handover) {
6977 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6978 & log_label & ": " & log_descr);
6979 } else {
6980 setverdict(pass);
6981 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6982 }
6983 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6984 break;
6985 }
6986 }
6987
6988 f_rslem_resume(RSL1_PROC);
6989 f_rslem_resume(RSL2_PROC);
6990 f_sleep(3.0);
6991 RSL.clear;
6992
6993 log("f_probe_for_handover(" & log_label & "): done clearing");
6994}
6995
6996/* Test the effect of various neighbor configuration scenarios:
6997 *
6998 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6999 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
7000 */
7001private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
7002 g_pars := f_gen_test_hdlr_pars();
7003 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
7004 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007005
7006 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
7007 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
7008
7009 /* Establish lchan at bts 0 */
7010 f_establish_fully(ass_cmd, exp_compl);
7011
7012 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
7013 f_vty_enter_cfg_network(BSCVTY);
7014 f_vty_transceive(BSCVTY, "timer T7 1");
7015 f_vty_transceive(BSCVTY, "end");
7016}
7017
7018private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
7019 f_tc_ho_neighbor_config_start();
7020
7021 /*
7022 * bts 0 ARFCN 871 BSIC 10
7023 * bts 1 ARFCN 871 BSIC 11
7024 * bts 2 ARFCN 871 BSIC 12
7025 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7026 */
7027
7028 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007029 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007030 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
7031 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007032 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007033
7034 f_probe_for_handover("1.b", "HO to unknown cell does not start",
7035 "handover any to arfcn 13 bsic 39",
7036 false);
7037
7038 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
7039 "handover any to arfcn 871 bsic 12",
7040 false);
7041
7042 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
7043 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007044 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007045
7046 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007047}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007048testcase TC_ho_neighbor_config_1() runs on test_CT {
7049 var MSC_ConnHdlr vc_conn;
7050 f_init(3, true, guard_timeout := 60.0);
7051 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007052 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007053 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7054 vc_conn.done;
7055
7056 /* f_tc_ho_neighbor_config_start() */
7057 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7058 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7059
7060 /* 1.a */
7061 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7062 * handover quickly by sending a Handover Failure message. */
7063 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7064 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7065 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7066 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007067 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7068 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007069
7070 /* 1.b */
7071 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7072 f_ctrs_bsc_and_bts_add(0, "handover:error");
7073
7074 /* 1.c */
7075 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7076 f_ctrs_bsc_and_bts_add(0, "handover:error");
7077
7078 /* 1.d */
7079 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7080 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7081 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7082 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007083 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7084 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007085
7086 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007087 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007088}
7089
Neels Hofmeyr91401012019-07-11 00:42:35 +02007090private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7091 f_tc_ho_neighbor_config_start();
7092
7093 /*
7094 * bts 0 ARFCN 871 BSIC 10
7095 * bts 1 ARFCN 871 BSIC 11
7096 * bts 2 ARFCN 871 BSIC 12
7097 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7098 */
7099
7100 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007101 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007102 f_sleep(0.5);
7103
7104 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7105 "handover any to arfcn 871 bsic 11",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007106 true, expect_target_tsc := c_BtsParams[1].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007107
7108 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7109 "handover any to arfcn 871 bsic 12",
7110 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007111 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007112}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007113testcase TC_ho_neighbor_config_2() runs on test_CT {
7114 var MSC_ConnHdlr vc_conn;
7115 f_init(3, true, guard_timeout := 50.0);
7116 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007117 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007118 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7119 vc_conn.done;
7120
7121 /* f_tc_ho_neighbor_config_start() */
7122 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7123 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7124
7125 /* 2.a */
7126 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7127 * handover quickly by sending a Handover Failure message. */
7128 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7129 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7130 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7131 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007132 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7133 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007134
7135 /* 2.b */
7136 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7137 f_ctrs_bsc_and_bts_add(0, "handover:error");
7138
7139 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007140 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007141}
7142
Neels Hofmeyr91401012019-07-11 00:42:35 +02007143private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7144 f_tc_ho_neighbor_config_start();
7145
7146 /*
7147 * bts 0 ARFCN 871 BSIC 10
7148 * bts 1 ARFCN 871 BSIC 11
7149 * bts 2 ARFCN 871 BSIC 12
7150 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7151 */
7152
7153 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007154 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007155 f_sleep(0.5);
7156
7157 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7158 "handover any to arfcn 871 bsic 11",
7159 false);
7160 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",
7161 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007162 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007163 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007164}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007165testcase TC_ho_neighbor_config_3() runs on test_CT {
7166 var MSC_ConnHdlr vc_conn;
7167 f_init(3, true, guard_timeout := 50.0);
7168 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007169 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007170 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7171 vc_conn.done;
7172
7173 /* f_tc_ho_neighbor_config_start() */
7174 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7175 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7176
7177 /* 3.a */
7178 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7179 f_ctrs_bsc_and_bts_add(0, "handover:error");
7180
7181 /* 3.b */
7182 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7183 * handover quickly by sending a Handover Failure message. */
7184 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7185 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7186 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7187 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007188 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7189 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007190
7191 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007192 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007193}
7194
Neels Hofmeyr91401012019-07-11 00:42:35 +02007195private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7196 f_tc_ho_neighbor_config_start();
7197
7198 /*
7199 * bts 0 ARFCN 871 BSIC 10
7200 * bts 1 ARFCN 871 BSIC 11
7201 * bts 2 ARFCN 871 BSIC 12
7202 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7203 */
7204
7205 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007206 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007207 f_sleep(0.5);
7208
7209 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7210 "handover any to arfcn 871 bsic 11",
7211 false);
7212 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7213 "handover any to arfcn 871 bsic 12",
7214 false);
7215 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7216 "handover any to arfcn 123 bsic 45",
7217 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007218 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007219}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007220testcase TC_ho_neighbor_config_4() runs on test_CT {
7221 var MSC_ConnHdlr vc_conn;
7222 f_init(3, true, guard_timeout := 50.0);
7223 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007224 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007225 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7226 vc_conn.done;
7227
7228 /* f_tc_ho_neighbor_config_start() */
7229 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7230 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7231
7232 /* 4.a */
7233 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7234 f_ctrs_bsc_and_bts_add(0, "handover:error");
7235
7236 /* 4.b */
7237 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7238 f_ctrs_bsc_and_bts_add(0, "handover:error");
7239
7240 /* 4.c */
7241 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7242 * handover quickly by timing out after the Handover Required message */
7243 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7244 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7245 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7246 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7247
7248 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007249 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007250}
7251
Neels Hofmeyr91401012019-07-11 00:42:35 +02007252private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7253 f_tc_ho_neighbor_config_start();
7254
7255 /*
7256 * bts 0 ARFCN 871 BSIC 10
7257 * bts 1 ARFCN 871 BSIC 11
7258 * bts 2 ARFCN 871 BSIC 12
7259 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7260 */
7261
7262 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 +02007263 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007264 f_sleep(0.5);
7265
7266 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7267 "handover any to arfcn 871 bsic 12",
7268 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007269 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007270}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007271testcase TC_ho_neighbor_config_5() runs on test_CT {
7272 var MSC_ConnHdlr vc_conn;
7273 f_init(3, true);
7274 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007275 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007276 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7277 vc_conn.done;
7278
7279 /* f_tc_ho_neighbor_config_start() */
7280 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7281 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7282
7283 /* 5 */
7284 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7285 * handover quickly by timing out after the Handover Required message */
7286 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7287 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7288 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7289 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7290
7291 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007292 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007293}
7294
Neels Hofmeyr91401012019-07-11 00:42:35 +02007295private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7296 f_tc_ho_neighbor_config_start();
7297
7298 /*
7299 * bts 0 ARFCN 871 BSIC 10
7300 * bts 1 ARFCN 871 BSIC 11
7301 * bts 2 ARFCN 871 BSIC 12
7302 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7303 */
7304
7305 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7306 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007307 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007308 f_sleep(0.5);
7309
7310 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7311 "handover any to arfcn 871 bsic 12",
7312 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007313 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007314}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007315testcase TC_ho_neighbor_config_6() runs on test_CT {
7316 var MSC_ConnHdlr vc_conn;
7317 f_init(3, true);
7318 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007319 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007320 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7321 vc_conn.done;
7322
7323 /* f_tc_ho_neighbor_config_start() */
7324 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7325 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7326
7327 /* 6.a */
7328 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7329 * handover quickly by timing out after the Handover Required message */
7330 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7331 f_ctrs_bsc_and_bts_add(0, "handover:error");
7332
7333 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007334 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007335}
7336
Neels Hofmeyr91401012019-07-11 00:42:35 +02007337private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7338 f_tc_ho_neighbor_config_start();
7339
7340 /*
7341 * bts 0 ARFCN 871 BSIC 10
7342 * bts 1 ARFCN 871 BSIC 11
7343 * bts 2 ARFCN 871 BSIC 12
7344 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7345 */
7346
7347 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7348 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007349 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007350 f_sleep(0.5);
7351
7352 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7353 "handover any to arfcn 871 bsic 12",
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007354 true, expect_target_tsc := c_BtsParams[2].tsc);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007355 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7356 "handover any to arfcn 123 bsic 45",
7357 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007358 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007359}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007360testcase TC_ho_neighbor_config_7() runs on test_CT {
7361 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007362 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007363 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007364 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007365 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7366 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007367
7368 /* f_tc_ho_neighbor_config_start() */
7369 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7370 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7371
7372 /* 7.a */
7373 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7374 * handover quickly by sending a Handover Failure message. */
7375 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7376 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7377 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7378 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007379 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7380 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007381
7382 /* 7.b */
7383 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7384 * handover quickly by timing out after the Handover Required message */
7385 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7386 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7387 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7388 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7389
7390 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007391 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007392}
7393
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007394/* OS#3041: Open and close N connections in a normal fashion, and expect no
7395 * BSSMAP Reset just because of that. */
7396testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7397 var default d;
7398 var integer i;
7399 var DchanTuple dt;
7400
7401 f_init();
7402
7403 /* Wait for initial BSSMAP Reset to pass */
7404 f_sleep(4.0);
7405
7406 d := activate(no_bssmap_reset());
7407
7408 /* Setup up a number of connections and RLSD them again from the MSC
7409 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7410 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007411 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007412 /* Since we're doing a lot of runs, give each one a fresh
7413 * T_guard from the top. */
7414 T_guard.start;
7415
7416 /* Setup a BSSAP connection and clear it right away. This is
7417 * the MSC telling the BSC about a planned release, it's not an
7418 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007419 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007420
7421 /* MSC disconnects (RLSD). */
7422 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7423 }
7424
7425 /* In the buggy behavior, a timeout of 2 seconds happens between above
7426 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7427 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7428 f_sleep(4.0);
7429
7430 deactivate(d);
7431 f_shutdown_helper();
7432}
Harald Welte552620d2017-12-16 23:21:36 +01007433
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007434/* OS#3041: Open and close N connections in a normal fashion, and expect no
7435 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7436 * the MSC. */
7437testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7438 var default d;
7439 var integer i;
7440 var DchanTuple dt;
7441 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007442 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7443 var BssmapCause cause := enum2int(cause_val);
7444
7445 f_init();
7446
7447 /* Wait for initial BSSMAP Reset to pass */
7448 f_sleep(4.0);
7449
7450 d := activate(no_bssmap_reset());
7451
7452 /* Setup up a number of connections and RLSD them again from the MSC
7453 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7454 * Let's do it some more times for good measure. */
7455 for (i := 0; i < 8; i := i+1) {
7456 /* Since we're doing a lot of runs, give each one a fresh
7457 * T_guard from the top. */
7458 T_guard.start;
7459
7460 /* Setup a BSSAP connection and clear it right away. This is
7461 * the MSC telling the BSC about a planned release, it's not an
7462 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007463 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007464
7465 /* Instruct BSC to clear channel */
7466 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7467
7468 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007469 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007470 }
7471
7472 /* In the buggy behavior, a timeout of 2 seconds happens between above
7473 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7474 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7475 f_sleep(4.0);
7476
7477 deactivate(d);
7478 f_shutdown_helper();
7479}
7480
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007481/* OS#3041: Open and close N connections in a normal fashion, and expect no
7482 * BSSMAP Reset just because of that. Close connections from the MS side with a
7483 * Release Ind on RSL. */
7484testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7485 var default d;
7486 var integer i;
7487 var DchanTuple dt;
7488 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007489 var integer j;
7490
7491 f_init();
7492
7493 /* Wait for initial BSSMAP Reset to pass */
7494 f_sleep(4.0);
7495
7496 d := activate(no_bssmap_reset());
7497
7498 /* Setup up a number of connections and RLSD them again from the MSC
7499 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7500 * Let's do it some more times for good measure. */
7501 for (i := 0; i < 8; i := i+1) {
7502 /* Since we're doing a lot of runs, give each one a fresh
7503 * T_guard from the top. */
7504 T_guard.start;
7505
7506 /* Setup a BSSAP connection and clear it right away. This is
7507 * the MSC telling the BSC about a planned release, it's not an
7508 * erratic loss of a connection. */
7509 dt := f_est_dchan('23'O, 23, '00010203040506'O);
7510
7511 /* simulate RLL REL IND */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007512 f_ipa_tx(ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007513
7514 /* expect Clear Request on MSC side */
7515 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7516
7517 /* Instruct BSC to clear channel */
7518 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7519 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7520
7521 /* expect BSC to disable the channel */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007522 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007523 }
7524
7525 /* In the buggy behavior, a timeout of 2 seconds happens between above
7526 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7527 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7528 f_sleep(4.0);
7529
7530 deactivate(d);
7531 f_shutdown_helper();
7532}
7533
Harald Welte94e0c342018-04-07 11:33:23 +02007534/***********************************************************************
7535 * IPA style dynamic PDCH
7536 ***********************************************************************/
7537
7538private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7539 template (omit) RSL_Cause nack := omit)
7540runs on test_CT {
7541 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7542 var RSL_Message rsl_unused;
7543 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7544 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7545 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007546 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007547 if (istemplatekind(nack, "omit")) {
7548 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007549 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007550 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007551 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007552 }
7553}
7554
7555private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7556 template (omit) RSL_Cause nack := omit)
7557runs on test_CT {
7558 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7559 var RSL_Message rsl_unused;
7560 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7561 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7562 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007563 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_DEACT(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007564 if (istemplatekind(nack, "omit")) {
7565 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007566 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007567 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007568 f_ipa_tx(ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007569 }
7570}
7571
7572private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7573runs on test_CT return charstring {
7574 var charstring cmd, resp;
7575 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007576 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007577}
7578
7579private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7580 template charstring exp)
7581runs on test_CT {
7582 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7583 if (not match(mode, exp)) {
7584 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007585 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007586 }
7587}
7588
7589private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7590runs on test_CT {
7591 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7592 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7593 f_vty_transceive(BSCVTY, "end");
7594}
7595
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007596
7597private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7598 var integer i;
7599 for (i := 0; i < 8; i := i + 1) {
7600 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7601 }
7602}
7603
Harald Welte94e0c342018-04-07 11:33:23 +02007604private const charstring TCHF_MODE := "TCH/F mode";
7605private const charstring TCHH_MODE := "TCH/H mode";
7606private const charstring PDCH_MODE := "PDCH mode";
7607private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007608private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007609
7610/* Test IPA PDCH activation / deactivation triggered by VTY */
7611testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7612 var RSL_Message rsl_unused;
7613
7614 /* change Timeslot 6 before f_init() starts RSL */
7615 f_init_vty();
7616 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7617 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7618
7619 f_init(1, false);
7620 f_sleep(1.0);
7621
7622 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7623
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007624 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007625 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7626 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007627 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7628 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007629 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007630 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007631 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7632
7633 /* De-activate it via VTY */
7634 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7635 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007636 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007637 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7638
7639 /* re-activate it via VTY */
7640 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7641 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007642 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007643 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7644
7645 /* and finally de-activate it again */
7646 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7647 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007648 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007649 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7650
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007651 /* clean up config */
7652 f_ts_set_chcomb(0, 0, 6, "PDCH");
7653
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007654 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007655}
7656
7657/* Test IPA PDCH activation NACK */
7658testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7659 var RSL_Message rsl_unused;
7660
7661 /* change Timeslot 6 before f_init() starts RSL */
7662 f_init_vty();
7663 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7664 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7665
7666 f_init(1, false);
7667 f_sleep(1.0);
7668
7669 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7670
7671 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7672 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007673 rsl_unused := f_exp_ipa_rx(tr_RSL_IPA_PDCH_ACT(chan_nr));
7674 f_ipa_tx(ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
Harald Welte94e0c342018-04-07 11:33:23 +02007675 f_sleep(1.0);
7676 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7677
7678 /* De-activate it via VTY */
7679 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7680 f_sleep(1.0);
7681 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7682
7683 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7684 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7685 f_sleep(1.0);
7686 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7687
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007688 /* clean up config */
7689 f_ts_set_chcomb(0, 0, 6, "PDCH");
7690
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007691 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007692}
7693
7694
7695/***********************************************************************
7696 * Osmocom style dynamic PDCH
7697 ***********************************************************************/
7698
7699private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7700 template (omit) RSL_Cause nack := omit)
7701runs on test_CT {
7702 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7703 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007704 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007705 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7706 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007707 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT(chan_nr, ?));
Harald Welte94e0c342018-04-07 11:33:23 +02007708 if (istemplatekind(nack, "omit")) {
7709 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007710 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007711 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007712 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007713 }
7714}
7715
7716private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7717 template (omit) RSL_Cause nack := omit)
7718runs on test_CT {
7719 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7720 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007721 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007722 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7723 /* expect the BSC to issue the related RSL command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007724 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007725 if (istemplatekind(nack, "omit")) {
7726 /* respond with a related acknowledgement */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007727 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007728 } else {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007729 //f_ipa_tx(ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
Harald Welte94e0c342018-04-07 11:33:23 +02007730 }
7731}
7732
7733/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7734testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7735 var RSL_Message rsl_unused;
7736
7737 /* change Timeslot 6 before f_init() starts RSL */
7738 f_init_vty();
7739 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7740 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7741
7742 f_init(1, false);
7743 f_sleep(1.0);
7744
7745 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7746
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007747 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007748 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7749 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007750 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007751
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007752 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Harald Welte94e0c342018-04-07 11:33:23 +02007753 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007754 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 +02007755 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7756
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007757 /* clean up config */
7758 f_ts_set_chcomb(0, 0, 6, "PDCH");
7759
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007760 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007761}
7762
7763/* Test Osmocom dyn PDCH activation NACK behavior */
7764testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7765 var RSL_Message rsl_unused;
7766
7767 /* change Timeslot 6 before f_init() starts RSL */
7768 f_init_vty();
7769 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7770 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7771
7772 f_init(1, false);
7773 f_sleep(1.0);
7774
7775 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7776
7777 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7778 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007779 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007780
7781 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007782 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
Harald Welte94e0c342018-04-07 11:33:23 +02007783 f_sleep(1.0);
7784 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7785
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007786 /* clean up config */
7787 f_ts_set_chcomb(0, 0, 6, "PDCH");
7788
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007789 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007790}
7791
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007792/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7793testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7794 var RSL_Message rsl_unused, rsl_msg;
7795 var DchanTuple dt;
7796 var BSSAP_N_CONNECT_ind rx_c_ind;
7797
7798 /* change Timeslot 6 before f_init() starts RSL */
7799 f_init_vty();
7800 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7801 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7802
7803 f_init(1, false);
7804 f_sleep(1.0);
7805
7806 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7807
7808 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7809 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7810 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007811 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007812
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007813 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007814 f_sleep(1.0);
7815 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7816 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7817
7818 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7819 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007820 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007821 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007822 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007823 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007824 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007825 }
7826
7827 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007828 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7829 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7830 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007831
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007832 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007833 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007834 dt.idx := {0, 0};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007835
7836 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007837 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7838 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007839 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7840
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007841 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 +02007842 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7843 dt.sccp_conn_id := rx_c_ind.connectionId;
7844 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7845
7846 /* Instruct BSC to clear channel */
7847 var BssmapCause cause := 0;
7848 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007849 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007850
7851 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007852 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
7853 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007854 f_sleep(1.0);
7855 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7856
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007857 /* Clean up SDCCH lchans */
7858 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
7859 f_perform_clear_test_ct(sdcch_cleanup[i]);
7860 }
7861
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007862 /* clean up config */
7863 f_ts_set_chcomb(0, 0, 6, "PDCH");
7864
7865 f_shutdown_helper();
7866}
7867
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007868/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7869testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7870 var ASP_RSL_Unitdata rsl_ud;
7871 var integer i;
7872 var integer chreq_total, chreq_nochan;
7873
7874 f_init_vty();
7875 for (i := 1; i < 8; i := i + 1) {
7876 if (i == 2) {
7877 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7878 } else {
7879 f_ts_set_chcomb(0, 0, i, "PDCH");
7880 }
7881 }
7882 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7883
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007884 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007885
7886 /* The dyn TS want to activate PDCH mode, ACK that. */
7887 var RslChannelNr chan_nr;
7888 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007889 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
7890 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007891
7892 f_sleep(1.0);
7893
7894 /* Exhaust all dedicated SDCCH lchans.
7895 /* GSM 44.018 Table 9.1.8.2:
7896 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7897 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007898 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007899 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007900 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007901 }
7902
7903 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007904 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007905 /* Also occupy the seven other SDCCH of the dyn TS */
7906 for (i := 0; i < 7; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007907 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
7908 }
7909
7910 /* Clean up SDCCH lchans */
7911 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7912 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007913 }
7914
7915 /* clean up config */
7916 f_ts_reset_chcomb(0);
7917
7918 f_shutdown_helper();
7919}
7920
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007921/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7922 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7923 it as TCH directly instead. SYS#5309. */
7924testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7925 var RSL_Message rsl_unused, rsl_msg;
7926 var DchanTuple dt;
7927 var BSSAP_N_CONNECT_ind rx_c_ind;
7928 var integer i;
7929
7930 /* change Timeslot 6 before f_init() starts RSL */
7931 f_init_vty();
7932 for (i := 1; i < 8; i := i + 1) {
7933 if (i == 6) {
7934 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7935 } else {
7936 f_ts_set_chcomb(0, 0, i, "PDCH");
7937 }
7938 }
7939 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7940
7941 f_init(1, false);
7942 f_sleep(1.0);
7943
7944 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7945
7946 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7947 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7948 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007949 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007950
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007951 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007952 f_sleep(1.0);
7953 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7954 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7955
7956 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7957 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007958 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007959 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007960 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007961 dt := f_est_dchan(ra, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007962 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007963 }
7964
7965 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007966 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
7967 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7968 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007969
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007970 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007971 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007972 dt.idx := {0, 0};
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007973
7974 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007975 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7976 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007977 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7978
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007979 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 +02007980 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7981 dt.sccp_conn_id := rx_c_ind.connectionId;
7982 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7983
7984 /* Instruct BSC to clear channel */
7985 var BssmapCause cause := 0;
7986 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007987 f_exp_chan_rel_and_clear(dt);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007988
7989 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06007990 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
7991 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007992 f_sleep(1.0);
7993 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7994
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007995 /* Clean up SDCCH lchans */
7996 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7997 f_perform_clear_test_ct(chan_cleanup[i]);
7998 }
7999
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02008000 /* clean up config */
8001 f_ts_reset_chcomb(0);
8002 /* TODO: clean up other channels? */
8003
8004 f_shutdown_helper();
8005}
8006
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008007/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
8008testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
8009 var RSL_Message rsl_unused, rsl_msg;
8010 var DchanTuple dt;
8011 var BSSAP_N_CONNECT_ind rx_c_ind;
8012 var GsmRrMessage rr;
8013
8014 /* change Timeslot 6 before f_init() starts RSL */
8015 f_init_vty();
8016 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
8017 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8018
8019 f_init(1, false);
8020 f_sleep(1.0);
8021
8022 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
8023
8024 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
8025 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
8026 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008027 rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008028
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008029 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008030 f_sleep(1.0);
8031 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
8032 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
8033
8034 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
8035 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008036 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008037 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02008038 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008039 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008040 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008041 }
8042
8043 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008044 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
8045 rsl_unused := f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(pdch_chan_nr));
8046 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008047
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008048 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008049 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008050 dt.idx := {0, 0};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008051
8052 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008053 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8054 rsl_msg := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008055 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8056 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8057 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8058 }
8059
8060 /* FIXME? Currently the TS stays in state BORKEN: */
8061
8062 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008063 /* rsl_unused := f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
8064 * f_ipa_tx(ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008065 * f_sleep(1.0);
8066 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8067 */
8068
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008069 /* Clean up SDCCH lchans */
8070 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8071 f_perform_clear_test_ct(chan_cleanup[i]);
8072 }
8073
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008074 /* clean up config */
8075 f_ts_set_chcomb(0, 0, 6, "PDCH");
8076
8077 f_shutdown_helper();
8078}
8079
Stefan Sperling0796a822018-10-05 13:01:39 +02008080testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008081 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008082 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8083 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8084 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008085 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008086}
8087
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008088testcase TC_chopped_ipa_payload() runs on test_CT {
8089 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8090 /* TODO: mp_bsc_ctrl_port does not work yet */};
8091 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8092 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8093 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008094 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008095}
8096
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008097/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8098 the BTS does autonomous MS power control loop */
8099testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8100 var MSC_ConnHdlr vc_conn;
8101 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8102 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8103 pars.exp_ms_power_params := true;
8104
8105 f_init(1, true);
8106 f_sleep(1.0);
8107 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8108 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008109 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008110}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008111
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008112/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8113testcase TC_c0_power_red_mode() runs on test_CT {
8114 f_init(1);
8115
8116 for (var integer red := 6; red >= 0; red := red - 2) {
8117 /* Configure BCCH carrier power reduction mode via the VTY */
8118 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8119
8120 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008121 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008122 chan_nr := t_RslChanNr_BCCH(0),
8123 bs_power := tr_RSL_IE_BS_Power(red / 2));
8124 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008125 var RSL_Message unused := f_exp_ipa_rx(tr_rsl_pdu);
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008126
8127 /* Additionally verify the applied value over the CTRL interface */
8128 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8129 if (cred != int2str(red)) {
8130 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8131 cred, " (expected ", red, ")");
8132 }
8133 }
8134
8135 f_shutdown_helper();
8136}
8137
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008138/***********************************************************************
8139 * MSC Pooling
8140 ***********************************************************************/
8141
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008142template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008143 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 +02008144
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008145private 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 +02008146runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008147 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008148 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008149 f_logp(BSCVTY, "Got RSL RR Release");
8150 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008151 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008152 f_logp(BSCVTY, "Got RSL Deact SACCH");
8153 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008154 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008155 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008156 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8157 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008158 break;
8159 }
8160 }
8161}
8162
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008163private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8164 var MgcpCommand mgcp_cmd;
8165 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8166 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8167 repeat;
8168 }
8169}
8170
8171private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8172 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8173 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8174 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8175 repeat;
8176 }
8177}
8178
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008179friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8180 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008181runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008182 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8183 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008184 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008185 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8186 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008187 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008188 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008189 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008190 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008191 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008192 }
8193 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008194 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008195 /* Also drop the SCCP connection */
8196 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8197 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008198 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008199 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008200 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8201 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008202 }
8203 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008204 deactivate(ack_dlcx);
8205 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008206}
8207
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008208friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8209runs on MSC_ConnHdlr {
8210 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8211 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8212 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8213 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8214 interleave {
8215 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8216 f_logp(BSCVTY, "Got RSL Deact SACCH");
8217 }
8218 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8219 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8220 /* Also drop the SCCP connection */
8221 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8222 }
8223 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8224 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8225 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8226 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8227 }
8228 }
8229 deactivate(ack_dlcx);
8230 deactivate(ack_rel_req);
8231}
8232
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008233friend function f_perform_clear_no_lchan()
8234runs on MSC_ConnHdlr {
8235 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8236 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8237 BSSAP.receive(tr_BSSMAP_ClearComplete);
8238 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8239 /* Also drop the SCCP connection */
8240 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8241}
8242
Vadim Yanitskiy65d879d2022-06-23 18:15:39 +07008243friend function f_perform_clear_test_ct(DchanTuple dt)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008244 runs on test_CT
8245{
8246 /* Instruct BSC to clear channel */
8247 var BssmapCause cause := 0;
8248 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06008249 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008250}
8251
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008252private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8253 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008254runs on MSC_ConnHdlr {
8255 timer T := 10.0;
8256 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8257
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008258 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008259 f_create_bssmap_exp(l3_enc);
8260
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008261 /* RSL_Emulation.f_chan_est() on rsl_pt:
8262 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008263 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8264 */
8265 var RSL_Message rx_rsl;
8266 var GsmRrMessage rr;
8267
8268 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008269 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008270 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008271 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008272 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8273 */
8274 timer Tt := 10.0;
8275
8276 /* request a channel to be established */
8277 Tt.start;
8278 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008279 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008280 Tt.stop;
8281 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008282 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008283 setverdict(fail, "Unexpected RSL message on DCHAN");
8284 mtc.stop;
8285 }
8286 [] Tt.timeout {
8287 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8288 mtc.stop;
8289 }
8290 }
8291 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8292 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008293 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008294
8295
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008296 if (expect_bssmap_l3) {
8297 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8298 var template PDU_BSSAP exp_l3_compl;
8299 exp_l3_compl := tr_BSSMAP_ComplL3()
8300 if (g_pars.aoip == false) {
8301 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8302 } else {
8303 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8304 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008305
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008306 var PDU_BSSAP bssap;
8307 T.start;
8308 alt {
8309 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8310 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8311 log("rx exp_l3_compl = ", bssap);
8312 }
8313 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8314 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8315 }
8316 [] T.timeout {
8317 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8318 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008319 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008320
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008321 /* start ciphering, if requested */
8322 if (ispresent(g_pars.encr)) {
8323 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008324 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008325 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008326 }
8327
8328 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008329 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008330 }
8331 setverdict(pass);
8332 f_sleep(1.0);
8333}
8334
8335private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8336 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8337 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008338 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008339 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008340 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008341 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008342 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008343 }
8344}
8345
8346/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8347private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8348 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008349 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8350 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8351 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8352 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 +02008353}
8354testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8355
8356 f_init(1, true);
8357 f_sleep(1.0);
8358 var MSC_ConnHdlr vc_conn;
8359 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008360
8361 f_ctrs_msc_init();
8362
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008363 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8364 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008365
8366 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008367 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008368}
8369
8370/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8371/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8372 * just as well using only RSL. */
8373testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8374
8375 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8376 f_sleep(1.0);
8377
8378 /* Control which MSC gets chosen next by the round-robin, otherwise
8379 * would be randomly affected by which other tests ran before this. */
8380 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8381
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008382 f_ctrs_msc_init();
8383
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008384 var MSC_ConnHdlr vc_conn1;
8385 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8386 pars1.mscpool.rsl_idx := 0;
8387 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8388 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8389 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008390 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008391
8392 var MSC_ConnHdlr vc_conn2;
8393 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8394 pars2.mscpool.rsl_idx := 1;
8395 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8396 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8397 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008398 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008399
8400 /* Test round-robin wrap to the first MSC */
8401 var MSC_ConnHdlr vc_conn3;
8402 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8403 pars3.mscpool.rsl_idx := 2;
8404 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8405 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8406 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008407 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008408 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008409}
8410
8411/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8412 * (configured in osmo-bsc.cfg). */
8413/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8414 * just as well using only RSL. */
8415testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8416
8417 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8418 f_sleep(1.0);
8419
8420 /* Control which MSC gets chosen next by the round-robin, otherwise
8421 * would be randomly affected by which other tests ran before this. */
8422 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8423
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008424 f_ctrs_msc_init();
8425
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008426 var MSC_ConnHdlr vc_conn1;
8427 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8428 pars1.mscpool.rsl_idx := 0;
8429 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8430 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8431 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008432 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008433
8434 var MSC_ConnHdlr vc_conn2;
8435 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8436 pars2.mscpool.rsl_idx := 1;
8437 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8438 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8439 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008440 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008441
8442 /* Test round-robin wrap to the first MSC */
8443 var MSC_ConnHdlr vc_conn3;
8444 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8445 pars3.mscpool.rsl_idx := 2;
8446 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8447 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8448 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008449 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008450 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008451}
8452
8453/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8454 * (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
8455 * NULL-NRI setting is stronger than that. */
8456/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8457 * just as well using only RSL. */
8458testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8459
8460 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8461 f_sleep(1.0);
8462
8463 /* Control which MSC gets chosen next by the round-robin, otherwise
8464 * would be randomly affected by which other tests ran before this. */
8465 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8466
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008467 f_ctrs_msc_init();
8468
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008469 var MSC_ConnHdlr vc_conn1;
8470 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8471 pars1.mscpool.rsl_idx := 0;
8472 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8473 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8474 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008475 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008476
8477 var MSC_ConnHdlr vc_conn2;
8478 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8479 pars2.mscpool.rsl_idx := 1;
8480 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8481 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8482 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008483 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008484
8485 /* Test round-robin wrap to the first MSC */
8486 var MSC_ConnHdlr vc_conn3;
8487 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8488 pars3.mscpool.rsl_idx := 2;
8489 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8490 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8491 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008492 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008493 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008494}
8495
8496/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8497 * assigned to any MSC (configured in osmo-bsc.cfg). */
8498/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8499 * just as well using only RSL. */
8500testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8501
8502 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8503 f_sleep(1.0);
8504
8505 /* Control which MSC gets chosen next by the round-robin, otherwise
8506 * would be randomly affected by which other tests ran before this. */
8507 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8508
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008509 f_ctrs_msc_init();
8510
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008511 var MSC_ConnHdlr vc_conn1;
8512 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8513 pars1.mscpool.rsl_idx := 0;
8514 /* An NRI that is not assigned to any MSC */
8515 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8516 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8517 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008518 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008519
8520 var MSC_ConnHdlr vc_conn2;
8521 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8522 pars2.mscpool.rsl_idx := 1;
8523 /* An NRI that is not assigned to any MSC */
8524 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8525 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8526 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008527 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008528
8529 /* Test round-robin wrap to the first MSC */
8530 var MSC_ConnHdlr vc_conn3;
8531 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8532 pars3.mscpool.rsl_idx := 2;
8533 /* An NRI that is not assigned to any MSC */
8534 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8535 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8536 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008537 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008538 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008539}
8540
8541/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8542 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8543/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8544 * just as well using only RSL. */
8545testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8546
8547 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8548 f_sleep(1.0);
8549
8550 /* Control which MSC gets chosen next by the round-robin, otherwise
8551 * would be randomly affected by which other tests ran before this. */
8552 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8553
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008554 f_ctrs_msc_init();
8555
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008556 var MSC_ConnHdlr vc_conn1;
8557 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8558 pars1.mscpool.rsl_idx := 0;
8559 /* An NRI that is assigned to an unconnected MSC */
8560 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8561 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8562 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008563 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8564 f_ctrs_msc_add(0, "mscpool:subscr:new");
8565 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008566
8567 var MSC_ConnHdlr vc_conn2;
8568 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8569 pars2.mscpool.rsl_idx := 1;
8570 /* An NRI that is assigned to an unconnected MSC */
8571 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8572 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8573 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008574 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8575 f_ctrs_msc_add(1, "mscpool:subscr:new");
8576 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008577
8578 /* Test round-robin wrap to the first MSC */
8579 var MSC_ConnHdlr vc_conn3;
8580 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8581 pars3.mscpool.rsl_idx := 2;
8582 /* An NRI that is assigned to an unconnected MSC */
8583 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8584 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8585 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008586 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8587 f_ctrs_msc_add(0, "mscpool:subscr:new");
8588 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008589 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008590}
8591
8592/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8593 * osmo-bsc.cfg). */
8594/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8595 * just as well using only RSL. */
8596testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8597
8598 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8599 f_sleep(1.0);
8600
8601 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8602 * this is not using round-robin. */
8603 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8604
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008605 f_ctrs_msc_init();
8606
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008607 var MSC_ConnHdlr vc_conn1;
8608 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8609 pars1.mscpool.rsl_idx := 0;
8610 /* An NRI of the second MSC's range (256-511) */
8611 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
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(1, "mscpool:subscr:known");
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 /* An NRI of the second MSC's range (256-511) */
8620 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8621 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8622 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008623 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008624
8625 var MSC_ConnHdlr vc_conn3;
8626 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8627 pars3.mscpool.rsl_idx := 2;
8628 /* An NRI of the second MSC's range (256-511) */
8629 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8630 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8631 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008632 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008633 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008634}
8635
8636/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8637 * while a round-robin remains unaffected by that. */
8638/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8639 * just as well using only RSL. */
8640testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8641
8642 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8643 f_sleep(1.0);
8644
8645 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8646 * this is not using round-robin. */
8647 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8648
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008649 f_ctrs_msc_init();
8650
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008651 var MSC_ConnHdlr vc_conn1;
8652 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8653 pars1.mscpool.rsl_idx := 0;
8654 /* An NRI of the third MSC's range (512-767) */
8655 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8656 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8657 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008658 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008659
8660 var MSC_ConnHdlr vc_conn2;
8661 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8662 pars2.mscpool.rsl_idx := 1;
8663 /* An NRI of the third MSC's range (512-767) */
8664 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8665 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8666 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008667 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008668
8669 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8670 var MSC_ConnHdlr vc_conn3;
8671 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8672 pars3.mscpool.rsl_idx := 2;
8673 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
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(1, "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/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8681/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8682 * just as well using only RSL. */
8683testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8684
8685 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8686 f_sleep(1.0);
8687
8688 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8689 * instead, and hits msc 0. */
8690 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8691
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008692 f_ctrs_msc_init();
8693
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008694 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8695 var MSC_ConnHdlr vc_conn1;
8696 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8697 pars1.mscpool.rsl_idx := 0;
8698 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8699 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8700 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008701 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008702
8703 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8704 var MSC_ConnHdlr vc_conn2;
8705 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8706 pars2.mscpool.rsl_idx := 1;
8707 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8708 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8709 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008710 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008711 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008712}
8713
8714/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8715 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8716private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8717 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8718 //cid_list := { cIl_allInBSS := ''O };
8719 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8720 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8721 var BSSAP_N_UNITDATA_req paging;
8722 var hexstring imsi := '001010000000123'H;
8723
8724 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8725
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008726 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008727 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8728 BSSAP.send(paging);
8729
8730 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8731 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8732 * channel number is picked here. */
8733 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8734 f_rslem_register(0, new_chan_nr);
8735 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8736 f_rslem_unregister(0, new_chan_nr);
8737
8738 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8739 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008740 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008741 f_sleep(1.0);
8742}
8743testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8744 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8745 f_sleep(1.0);
8746
8747 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8748 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8749 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8750
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008751 f_ctrs_msc_init();
8752
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008753 var MSC_ConnHdlr vc_conn1;
8754 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8755 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008756 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8757 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008758 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8759 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008760 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008761 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008762}
8763
8764/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8765 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8766private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8767 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8768 //cid_list := { cIl_allInBSS := ''O };
8769 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8770 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8771 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008772 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008773 var BSSAP_N_UNITDATA_req paging;
8774
8775 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8776
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008777 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008778 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8779 BSSAP.send(paging);
8780
8781 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8782 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8783 * channel number is picked here. */
8784 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8785 f_rslem_register(0, new_chan_nr);
8786 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8787 f_rslem_unregister(0, new_chan_nr);
8788
8789 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8790 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8791 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008792 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 +02008793 f_sleep(1.0);
8794}
8795testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8796 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8797 f_sleep(1.0);
8798
8799 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8800 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8801 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8802
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008803 f_ctrs_msc_init();
8804
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008805 var MSC_ConnHdlr vc_conn1;
8806 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8807 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008808 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8809 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008810 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8811 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008812 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008813 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008814}
8815
8816/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8817/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8818 * just as well using only RSL. */
8819testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8820
8821 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8822 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008823 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8824 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008825
8826 /* Control which MSC gets chosen next by the round-robin, otherwise
8827 * would be randomly affected by which other tests ran before this. */
8828 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8829
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008830 f_ctrs_msc_init();
8831
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008832 var MSC_ConnHdlr vc_conn1;
8833 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8834 pars1.mscpool.rsl_idx := 0;
8835 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8836 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8837 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008838 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008839
8840 var MSC_ConnHdlr vc_conn2;
8841 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8842 pars2.mscpool.rsl_idx := 1;
8843 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8844 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8845 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008846 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008847
8848 var MSC_ConnHdlr vc_conn3;
8849 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8850 pars3.mscpool.rsl_idx := 2;
8851 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8852 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8853 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008854 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008855 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008856}
8857
8858/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8859 * TMSI NRI. */
8860testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8861
8862 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8863 f_sleep(1.0);
8864
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008865 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8866 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8867
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008868 /* Control which MSC gets chosen next by the round-robin, otherwise
8869 * would be randomly affected by which other tests ran before this. */
8870 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8871
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008872 f_ctrs_msc_init();
8873
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008874 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8875 var MSC_ConnHdlr vc_conn1;
8876 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8877 pars1.mscpool.rsl_idx := 0;
8878 /* An NRI of the second MSC's range (256-511) */
8879 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8880 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8881 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008882 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008883
8884 var MSC_ConnHdlr vc_conn2;
8885 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8886 pars2.mscpool.rsl_idx := 1;
8887 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8888 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8889 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008890 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008891
8892 var MSC_ConnHdlr vc_conn3;
8893 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8894 pars3.mscpool.rsl_idx := 2;
8895 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8896 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8897 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008898 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008899 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008900}
8901
Philipp Maier783681c2020-07-16 16:47:06 +02008902/* Allow/Deny emergency calls globally via VTY */
8903private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8904 f_vty_enter_cfg_msc(BSCVTY, 0);
8905 if (allow) {
8906 f_vty_transceive(BSCVTY, "allow-emergency allow");
8907 } else {
8908 f_vty_transceive(BSCVTY, "allow-emergency deny");
8909 }
8910 f_vty_transceive(BSCVTY, "exit");
8911 f_vty_transceive(BSCVTY, "exit");
8912}
8913
8914/* Allow/Deny emergency calls per BTS via VTY */
8915private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8916 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8917 if (allow) {
8918 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8919 } else {
8920 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8921 }
8922 f_vty_transceive(BSCVTY, "exit");
8923 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008924 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008925}
8926
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008927/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8928private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8929 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8930 if (allow) {
8931 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8932 } else {
8933 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8934 }
8935 f_vty_transceive(BSCVTY, "exit");
8936 f_vty_transceive(BSCVTY, "exit");
8937 f_vty_transceive(BSCVTY, "exit");
8938}
8939
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008940/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8941private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8942 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8943 if (allow) {
8944 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8945 } else {
8946 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8947 }
8948 f_vty_transceive(BSCVTY, "exit");
8949 f_vty_transceive(BSCVTY, "exit");
8950 f_vty_transceive(BSCVTY, "exit");
8951}
8952
Philipp Maier783681c2020-07-16 16:47:06 +02008953/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8954private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8955 var PDU_ML3_MS_NW emerg_setup;
8956 var octetstring emerg_setup_enc;
8957 var RSL_Message emerg_setup_data_ind;
8958
8959 f_establish_fully(omit, omit);
8960
8961 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8962 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8963 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8964
8965 RSL.send(emerg_setup_data_ind);
8966}
8967
8968/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8969 * CALLS are permitted by the BSC config. */
8970private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8971 var PDU_BSSAP emerg_setup_data_ind_bssap;
8972 var PDU_ML3_MS_NW emerg_setup;
8973 timer T := 3.0;
8974
8975 f_assignment_emerg_setup()
8976
8977 T.start;
8978 alt {
8979 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8980 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8981 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8982 setverdict(fail, "no emergency setup");
8983 }
8984 }
8985 [] BSSAP.receive {
8986 setverdict(fail, "unexpected BSSAP message!");
8987 }
8988 [] T.timeout {
8989 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8990 }
8991 }
8992
8993 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008994 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02008995}
8996
8997/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8998 * forbidden by the BSC config. */
8999private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
9000 var PDU_BSSAP emerg_setup_data_ind_bssap;
9001 timer T := 3.0;
9002
9003 f_assignment_emerg_setup()
9004
9005 T.start;
9006 alt {
9007 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9008 setverdict(pass);
9009 }
9010 [] RSL.receive {
9011 setverdict(fail, "unexpected RSL message!");
9012 }
9013 [] T.timeout {
9014 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
9015 }
9016 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009017 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01009018 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02009019}
9020
9021/* EMERGENCY CALL situation #1, allowed globally and by BTS */
9022testcase TC_assignment_emerg_setup_allow() runs on test_CT {
9023 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9024 var MSC_ConnHdlr vc_conn;
9025
9026 f_init(1, true);
9027 f_sleep(1.0);
9028
9029 f_vty_allow_emerg_msc(true);
9030 f_vty_allow_emerg_bts(true, 0);
9031 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
9032 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009033 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009034}
9035
9036/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
9037testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
9038 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9039 var MSC_ConnHdlr vc_conn;
9040
9041 f_init(1, true);
9042 f_sleep(1.0);
9043
9044 f_vty_allow_emerg_msc(false);
9045 f_vty_allow_emerg_bts(true, 0);
9046 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9047 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009048 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009049}
9050
9051/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
9052testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9053 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9054 var MSC_ConnHdlr vc_conn;
9055
9056 /* Note: This simulates a spec violation by the MS, correct MS
9057 * implementations would not try to establish an emergency call because
9058 * the system information tells in advance that emergency calls are
9059 * not forbidden */
9060
9061 f_init(1, true);
9062 f_sleep(1.0);
9063
9064 f_vty_allow_emerg_msc(true);
9065 f_vty_allow_emerg_bts(false, 0);
9066 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9067 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009068 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009069}
9070
Philipp Maier82812002020-08-13 18:48:27 +02009071/* Test what happens when an emergency call arrives while all TCH channels are
9072 * busy, the BSC is expected to terminate one call in favor of the incoming
9073 * emergency call */
9074testcase TC_emerg_premption() runs on test_CT {
9075 var ASP_RSL_Unitdata rsl_ud;
9076 var integer i;
9077 var integer chreq_total, chreq_nochan;
9078 var RSL_Message rx_rsl;
Philipp Maier82812002020-08-13 18:48:27 +02009079
9080 f_init(1);
9081 f_sleep(1.0);
9082
9083 f_vty_allow_emerg_msc(true);
9084 f_vty_allow_emerg_bts(true, 0);
9085
9086 /* Fill up all channels on the BTS */
9087 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9088 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9089 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 +02009090 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009091 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009092 IPA_RSL[0][0].clear;
Philipp Maier82812002020-08-13 18:48:27 +02009093 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9094 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9095
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009096 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9097 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
9098 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009099 f_ipa_tx(ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009100
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009101 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9102 var BSSAP_N_CONNECT_ind rx_c_ind;
9103 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9104 var integer sccp_conn_id := rx_c_ind.connectionId;
9105 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9106
Philipp Maier82812002020-08-13 18:48:27 +02009107 /* Send Channel request for emegergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009108 f_ipa_tx(ts_RSL_CHAN_RQD('A5'O, 23));
Philipp Maier82812002020-08-13 18:48:27 +02009109
9110 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009111 f_expect_chan_rel(first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009112 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009113
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009114 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9115 var BSSAP_N_DATA_ind rx_clear_req;
9116 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9117 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9118 log("XXX ", rx_clear_req);
9119 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9120 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9121 }
9122
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009123 /* Expect the BSC to send activate/assign the channel for the emergency call */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009124 rx_rsl := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009125 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9126 setverdict(fail, "different TCH lchan activated than expected");
9127 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009128 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(first_tch, 33));
9129 rx_rsl := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009130
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009131 /* complete the BSSMAP Clear to satisfy the conn leak check */
9132 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9133 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9134 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9135 }
9136
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009137 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009138}
9139
9140/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009141private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009142private type record FHParamsTs {
9143 boolean enabled,
9144 uint6_t hsn,
9145 uint6_t maio,
9146 ArfcnList ma
9147};
9148
9149/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009150private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009151 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009152 FHParamsTs ts[8]
9153};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009154
9155/* Randomly generate the hopping parameters for the given timeslot numbers */
9156private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9157runs on test_CT return FHParamsTrx {
9158 var FHParamsTrx fhp;
9159
Philipp Maier798d8952021-10-19 14:43:19 +02009160 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9161 * fall in the GSM900 band. */
9162 fhp.arfcn.arfcn := f_rnd_int(3);
9163 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009164
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009165 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9166 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009167 fhp.ts[tn].enabled := false;
9168 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009169 continue;
9170 }
9171
9172 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009173 fhp.ts[tn].hsn := f_rnd_int(64);
9174 fhp.ts[tn].maio := f_rnd_int(64);
9175 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009176
9177 /* Random Mobile Allocation (hopping channels) */
9178 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9179 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9180 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009181 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009182 }
9183
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009184 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009185 }
9186
9187 log("f_TC_fh_params_gen(): ", fhp);
9188 return fhp;
9189}
9190
9191/* Make sure that the given Channel Description IE matches the hopping configuration */
9192private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9193{
9194 var template (present) ChannelDescription tr_cd;
9195 var template (present) MaioHsn tr_maio_hsn;
9196 var uint3_t tn := cd.chan_nr.tn;
9197
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009198 if (fhp.ts[tn].enabled) {
9199 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009200 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9201 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009202 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009203 }
9204
9205 if (not match(cd, tr_cd)) {
9206 setverdict(fail, "Channel Description IE does not match: ",
9207 cd, " vs expected ", tr_cd);
9208 }
9209}
9210
9211/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9212private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9213 in MobileAllocationLV ma)
9214{
9215 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9216
9217 if (not match(ma, tr_ma)) {
9218 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9219 tn, "): ", ma, " vs expected: ", tr_ma);
9220 } else {
9221 setverdict(pass);
9222 }
9223}
9224
9225private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9226 in MobileAllocationLV ma)
9227return template MobileAllocationLV {
9228 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009229 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009230 return { len := 0, ma := ''B };
9231 }
9232
9233 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9234 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9235 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009236
9237 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009238 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9239 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9240 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009241 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009242 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009243 }
9244 }
9245
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009246 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009247 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009248
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009249 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009250 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9251 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009252 }
9253
9254 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009255 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009256 if (full_mask[i] != '1'B)
9257 { continue; }
9258
9259 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9260 if (slot_mask[i] == '1'B) {
9261 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009262 } else {
9263 ma_mask := ma_mask & '0'B;
9264 }
9265 }
9266
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009267 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9268 if (full_mask[0] == '1'B) {
9269 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9270 if (slot_mask[0] == '1'B) {
9271 ma_mask := ma_mask & '1'B;
9272 } else {
9273 ma_mask := ma_mask & '0'B;
9274 }
9275 }
9276
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009277 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009278 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009279 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9280
9281 return { len := ma_mask_len, ma := ma_mask };
9282}
9283
Philipp Maier798d8952021-10-19 14:43:19 +02009284/* Configure the appropriate band for a given arfcn, exc */
9285private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9286{
9287 var charstring band;
9288 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9289
9290 select (arfcn_) {
9291 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9292 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9293 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9294 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9295 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9296 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9297 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9298 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9299 case else { return; }
9300 }
9301
9302 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9303 f_vty_transceive(BSCVTY, "band " & band);
9304 f_vty_transceive(BSCVTY, "end");
9305}
9306
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009307/* Configure the hopping parameters in accordance with the given record */
9308private function f_TC_fh_params_set(in FHParamsTrx fhp,
9309 uint8_t bts_nr := 0,
9310 uint8_t trx_nr := 0)
9311runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009312
9313 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9314
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009315 /* Enter the configuration node for the given BTS/TRX numbers */
9316 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9317
Philipp Maier798d8952021-10-19 14:43:19 +02009318 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009319
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009320 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009321 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9322
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009323 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009324 f_vty_transceive(BSCVTY, "hopping enabled 0");
9325 f_vty_transceive(BSCVTY, "exit"); /* go back */
9326 continue;
9327 }
9328
9329 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009330 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9331 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009332
9333 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009334 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9335 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009336 }
9337
9338 f_vty_transceive(BSCVTY, "hopping enabled 1");
9339 f_vty_transceive(BSCVTY, "exit"); /* go back */
9340 }
9341
9342 f_vty_transceive(BSCVTY, "end");
9343}
9344
9345/* Disable frequency hopping on all timeslots */
9346private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9347 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009348 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009349 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009350runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009351
9352 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9353
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009354 /* Enter the configuration node for the given BTS/TRX numbers */
9355 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9356
Philipp Maier798d8952021-10-19 14:43:19 +02009357 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009358
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009359 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009360 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9361
9362 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009363 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9364 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009365 }
9366
9367 f_vty_transceive(BSCVTY, "hopping enabled 0");
9368 f_vty_transceive(BSCVTY, "exit"); /* go back */
9369 }
9370
9371 f_vty_transceive(BSCVTY, "end");
9372 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9373}
9374
9375/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9376 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9377testcase TC_fh_params_chan_activ() runs on test_CT {
9378 var FHParamsTrx fhp := f_TC_fh_params_gen();
9379 var RSL_Message rsl_msg;
9380 var RSL_IE_Body ie;
9381
9382 f_init_vty();
9383
9384 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9385 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9386
9387 f_init(1);
9388
9389 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9390 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009391 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9392 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009393
9394 /* Make sure that Channel Identification IE is present */
9395 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9396 setverdict(fail, "RSL Channel Identification IE is absent");
9397 continue;
9398 }
9399
9400 /* Make sure that hopping parameters (HSN/MAIO) match */
9401 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9402
9403 /* "Mobile Allocation shall be included but empty" - let's check this */
9404 if (ie.chan_ident.ma.v.len != 0) {
9405 setverdict(fail, "Mobile Allocation IE is not empty: ",
9406 ie.chan_ident.ma, ", despite it shall be");
9407 continue;
9408 }
9409 }
9410
9411 /* Disable frequency hopping */
9412 f_TC_fh_params_unset(fhp);
9413
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009414 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009415}
9416
9417/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9418testcase TC_fh_params_imm_ass() runs on test_CT {
9419 var FHParamsTrx fhp := f_TC_fh_params_gen();
9420 var RSL_Message rsl_msg;
9421 var RSL_IE_Body ie;
9422
9423 f_init_vty();
9424
9425 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9426 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9427
9428 f_init(1);
9429
9430 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9431 for (var integer i := 0; i < 9; i := i + 1) {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009432 f_ipa_tx(ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9433 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009434
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009435 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9436 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009437
9438 /* Make sure that Full Immediate Assign Info IE is present */
9439 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9440 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9441 continue;
9442 }
9443
9444 /* Decode the actual Immediate Assignment message */
9445 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9446 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9447 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9448 continue;
9449 }
9450
9451 /* Make sure that hopping parameters (HSN/MAIO) match */
9452 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9453
9454 /* Make sure that the Mobile Allocation IE matches */
9455 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9456 rr_msg.payload.imm_ass.mobile_allocation);
9457 }
9458
9459 /* Disable frequency hopping */
9460 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009461
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009462 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009463}
9464
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009465/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9466testcase TC_fh_params_assignment_cmd() runs on test_CT {
9467 var FHParamsTrx fhp := f_TC_fh_params_gen();
9468 var RSL_Message rsl_msg;
9469 var RSL_IE_Body ie;
9470
9471 f_init_vty();
9472
9473 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9474 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9475
9476 f_init(1);
9477
9478 /* HACK: work around "Couldn't find Expect for CRCX" */
9479 vc_MGCP.stop;
9480
9481 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9482 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9483
9484 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9485 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9486 for (var integer i := 0; i < 3; i := i + 1) {
9487 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
9488 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
9489
9490 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9491 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009492 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009493
9494 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009495 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9496 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009497
9498 /* Make sure that L3 Information IE is present */
9499 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9500 setverdict(fail, "RSL L3 Information IE is absent");
9501 continue;
9502 }
9503
9504 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9505 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9506 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9507 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9508 continue;
9509 }
9510
9511 /* Make sure that hopping parameters (HSN/MAIO) match */
9512 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9513 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9514
9515 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9516 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009517 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009518 continue;
9519 }
9520
9521 /* Make sure that the Mobile Allocation IE matches (if present) */
9522 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9523 if (chan_desc.h and ma_present) {
9524 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9525 l3_msg.payload.ass_cmd.mobile_allocation.v);
9526 } else if (chan_desc.h and not ma_present) {
9527 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9528 continue;
9529 } else if (not chan_desc.h and ma_present) {
9530 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9531 continue;
9532 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009533
9534 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009535 }
9536
9537 /* Give the IUT some time to release all channels */
9538 f_sleep(3.0);
9539
9540 /* Disable frequency hopping */
9541 f_TC_fh_params_unset(fhp);
9542
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009543 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009544}
9545
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009546/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9547private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9548runs on test_CT {
9549 var RSL_Message rsl_msg;
9550 var RSL_IE_Body ie;
9551 var DchanTuple dt;
9552
9553 /* Establish a dedicated channel, so we can trigger handover */
9554 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009555 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009556
9557 /* Trigger handover from BTS0 to BTS1 */
9558 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9559 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9560
9561 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009562 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx := {1, 0});
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009563
9564 /* ACKnowledge channel activation and expect (RR) Handover Command */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009565 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33), idx := {1, 0});
9566 rsl_msg := f_exp_ipa_rx(tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009567
9568 /* Make sure that L3 Information IE is present */
9569 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9570 setverdict(fail, "RSL L3 Information IE is absent");
9571 return;
9572 }
9573
9574 /* Decode the L3 message and make sure it is (RR) Handover Command */
9575 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9576 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9577 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9578 return;
9579 }
9580
9581 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9582 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9583 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9584 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9585 return;
9586 }
9587
9588 /* Make sure that hopping parameters (HSN/MAIO) match */
9589 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9590
9591 /* Make sure that Cell Channel Description IE is present */
9592 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9593 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9594 return;
9595 }
9596
9597 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9598 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9599 if (ma_present) {
9600 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9601 l3_msg.payload.ho_cmd.mobile_allocation.v);
9602 } else {
9603 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9604 return;
9605 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009606
9607 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009608}
9609testcase TC_fh_params_handover_cmd() runs on test_CT {
9610 var FHParamsTrx fhp := f_TC_fh_params_gen();
9611
9612 f_init_vty();
9613
9614 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9615 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9616
9617 f_vty_transceive(BSCVTY, "timeslot 0");
9618 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9619 f_vty_transceive(BSCVTY, "exit"); /* go back */
9620
9621 f_vty_transceive(BSCVTY, "timeslot 1");
9622 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9623 f_vty_transceive(BSCVTY, "end"); /* we're done */
9624
9625 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9626 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9627
9628 f_init(2);
9629
9630 f_TC_fh_params_handover_cmd(fhp);
9631
9632 /* Disable frequency hopping on BTS1 */
9633 f_TC_fh_params_unset(fhp, 1);
9634
9635 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9636 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9637
9638 f_vty_transceive(BSCVTY, "timeslot 0");
9639 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9640 f_vty_transceive(BSCVTY, "exit"); /* go back */
9641
9642 f_vty_transceive(BSCVTY, "timeslot 1");
9643 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9644 f_vty_transceive(BSCVTY, "end"); /* we're done */
9645
9646 f_shutdown_helper();
9647}
9648
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009649/* Verify the hopping parameters in System Information Type 4 */
9650testcase TC_fh_params_si4_cbch() runs on test_CT {
9651 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9652 var ASP_RSL_Unitdata rx_rsl_ud;
9653 timer T := 5.0;
9654
9655 f_init_vty();
9656
9657 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9658 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9659
9660 f_vty_transceive(BSCVTY, "timeslot 0");
9661 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9662 f_vty_transceive(BSCVTY, "exit"); /* go back */
9663
9664 f_vty_transceive(BSCVTY, "timeslot 1");
9665 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9666 f_vty_transceive(BSCVTY, "end"); /* we're done */
9667
9668 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9669 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9670
9671 f_init(1);
9672
9673 T.start;
9674 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009675 [] 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 +07009676 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9677 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9678
9679 /* Make sure that what we decoded is System Information Type 4 */
9680 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9681 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9682 repeat;
9683 }
9684
9685 /* Make sure that CBCH Channel Description IE is present */
9686 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9687 setverdict(fail, "CBCH Channel Description IE is absent");
9688 break;
9689 }
9690
9691 /* Finally, check the hopping parameters (HSN, MAIO) */
9692 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9693 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9694
9695 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9696 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9697 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9698 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9699 break;
9700 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9701 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9702 si.payload.si4.cbch_mobile_alloc.v);
9703 }
9704 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +06009705 [] IPA_RSL[0][0].receive { repeat; }
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009706 [] T.timeout {
9707 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9708 }
9709 }
9710
9711 /* Disable frequency hopping */
9712 f_TC_fh_params_unset(fhp);
9713
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009714 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009715 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9716
9717 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009718 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009719 f_vty_transceive(BSCVTY, "exit"); /* go back */
9720
9721 f_vty_transceive(BSCVTY, "timeslot 1");
9722 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9723 f_vty_transceive(BSCVTY, "end"); /* we're done */
9724
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009725 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009726}
9727
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009728template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9729 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9730
9731private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9732 template (present) BSSLAP_PDU expect_bsslap)
9733{
9734 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9735 if (not match(bsslap, expect_bsslap)) {
9736 log("EXPECTING BSSLAP: ", expect_bsslap);
9737 log("GOT BSSLAP: ", bsslap);
9738 setverdict(fail, "BSSLAP is not as expected");
9739 mtc.stop;
9740 }
9741 setverdict(pass);
9742}
9743
9744/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9745const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9746
9747private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9748 var PDU_BSSAP_LE rx_bsslap;
9749 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9750 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9751}
9752
9753/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9754 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9755private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9756 f_sleep(1.0);
9757
9758 f_establish_fully(omit, omit);
9759 f_bssap_le_register_imsi(g_pars.imsi, omit);
9760
9761 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9762 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9763
9764 var PDU_BSSAP_LE plr;
9765 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9766
9767 if (not do_ta_request) {
9768 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9769 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9770 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9771 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9772 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9773 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9774 mtc.stop;
9775 }
9776 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9777 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9778 if (not match(bsslap, expect_ta_layer3)) {
9779 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9780 log("GOT BSSLAP: ", bsslap);
9781 setverdict(fail, "BSSLAP is not as expected");
9782 mtc.stop;
9783 }
9784 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9785 * has no need to request the TA from the BSC and directly responds. */
9786 } else {
9787 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9788 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9789 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9790 }
9791
9792 /* SMLC got the TA from the BSC, now responds with geo information data. */
9793 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9794 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9795 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9796
9797 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9798 f_mo_l3_transceive();
9799
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009800 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009801
9802 f_sleep(2.0);
9803 setverdict(pass);
9804}
9805
9806/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9807 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9808private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9809 f_lcs_loc_req_for_active_ms(false);
9810}
9811testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9812 var MSC_ConnHdlr vc_conn;
9813 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9814
9815 f_init(1, true);
9816 f_sleep(1.0);
9817 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9818 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009819 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009820}
9821
9822/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9823 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9824private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9825 f_lcs_loc_req_for_active_ms(true);
9826}
9827testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9828 var MSC_ConnHdlr vc_conn;
9829 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9830
9831 f_init(1, true);
9832 f_sleep(1.0);
9833 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9834 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009835 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009836}
9837
9838/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9839 * conn without an active lchan. */
9840private function f_clear_A_conn() runs on MSC_ConnHdlr
9841{
9842 var BssmapCause cause := 0;
9843 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9844 BSSAP.receive(tr_BSSMAP_ClearComplete);
9845 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9846
9847 timer no_more_bssap := 5.0;
9848 no_more_bssap.start;
9849 alt {
9850 [] no_more_bssap.timeout { break; }
9851 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9852 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9853 mtc.stop;
9854 }
9855 }
9856 setverdict(pass);
9857}
9858
9859/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9860 * for LCS, for cases where there is only an A conn without an active lchan. */
9861private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9862{
9863 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9864
9865 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9866 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9867 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9868 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9869 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9870 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9871
9872 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9873 f_clear_A_conn();
9874 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9875 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9876}
9877
9878/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9879 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9880 */
9881private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9882 f_sleep(1.0);
9883
9884 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9885 f_bssap_le_register_imsi(g_pars.imsi, omit);
9886
9887 /* Register to receive the Paging Command */
9888 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9889 g_chan_nr := new_chan_nr;
9890 f_rslem_register(0, g_chan_nr);
9891
9892 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9893 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9894 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9895 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9896
9897 var PDU_BSSAP_LE plr;
9898 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9899
9900 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9901 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9902
9903 /* OsmoBSC needs to Page */
9904 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9905 f_logp(BSCVTY, "got Paging Command");
9906
9907 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9908 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009909 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);
9910 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009911
9912 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9913
9914 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9915
9916 /* SMLC got the TA from the BSC, now responds with geo information data. */
9917 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9918 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9919
9920 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9921
9922 /* The lchan is gone, the A-interface conn was created for the LCS only.
9923 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9924 f_verify_active_A_conn_and_clear();
9925
9926 f_sleep(2.0);
9927 setverdict(pass);
9928}
9929testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9930 var MSC_ConnHdlr vc_conn;
9931 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9932
9933 f_init(1, true);
9934 f_sleep(1.0);
9935
9936 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9937 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9938
9939 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9940 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009941 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009942}
9943
9944/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9945 */
9946private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9947 f_sleep(1.0);
9948
9949 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9950 f_bssap_le_register_imsi(g_pars.imsi, omit);
9951
9952 /* provoke an abort by omitting both IMSI and IMEI */
9953 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9954 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9955 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9956 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9957
9958 /* BSC tells MSC about failure */
9959 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9960 locationEstimate := omit, positioningData := omit,
9961 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9962
9963 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9964 f_verify_active_A_conn_and_clear();
9965
9966 f_sleep(2.0);
9967 setverdict(pass);
9968}
9969testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9970 var MSC_ConnHdlr vc_conn;
9971 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9972
9973 f_init(1, true);
9974 f_sleep(1.0);
9975
9976 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9977 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9978
9979 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9980 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009981 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009982}
9983
9984/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9985 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9986private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9987 f_sleep(1.0);
9988
9989 f_establish_fully(omit, omit);
9990 f_bssap_le_register_imsi(g_pars.imsi, omit);
9991
9992 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9993 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9994
9995 var PDU_BSSAP_LE plr;
9996 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9997
9998 if (do_ta) {
9999 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10000 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10001 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10002 }
10003
10004 /* SMLC fails to respond, BSC runs into timeout */
10005 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
10006 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10007
10008 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10009 locationEstimate := omit, positioningData := omit,
10010 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
10011
10012 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10013 f_verify_active_A_conn_and_clear();
10014
10015 f_sleep(2.0);
10016 setverdict(pass);
10017}
10018
10019/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10020 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
10021private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
10022 f_lcs_loc_req_for_active_ms_le_timeout(false);
10023}
10024
10025testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
10026 var MSC_ConnHdlr vc_conn;
10027 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10028
10029 f_init(1, true);
10030 f_sleep(1.0);
10031 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
10032 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010033 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010034}
10035
10036/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
10037 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
10038private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
10039 f_lcs_loc_req_for_active_ms_le_timeout(true);
10040}
10041
10042testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
10043 var MSC_ConnHdlr vc_conn;
10044 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10045
10046 f_init(1, true);
10047 f_sleep(1.0);
10048 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10049 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010050 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010051}
10052
10053/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10054private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10055 f_sleep(1.0);
10056
10057 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10058 f_bssap_le_register_imsi(g_pars.imsi, omit);
10059
10060 /* Register to receive the Paging Command */
10061 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10062 g_chan_nr := new_chan_nr;
10063 f_rslem_register(0, g_chan_nr);
10064
10065 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10066 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10067 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10068 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10069
10070 var PDU_BSSAP_LE plr;
10071 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10072
10073 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10074 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10075
10076 /* OsmoBSC needs to Page */
10077 var PDU_BSSAP_LE rx_bsslap;
10078 alt {
10079 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10080 f_logp(BSCVTY, "got Paging Command");
10081 repeat;
10082 }
10083 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10084 /* MS does not respond to Paging, TA Req runs into timeout. */
10085 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10086 }
10087 }
10088
10089 /* SMLC responds with failure */
10090 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10091 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10092
10093 /* BSC tells MSC about failure */
10094 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10095 locationEstimate := omit, positioningData := omit,
10096 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10097
10098 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10099 f_verify_active_A_conn_and_clear();
10100
10101 f_sleep(2.0);
10102 setverdict(pass);
10103}
10104testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10105 var MSC_ConnHdlr vc_conn;
10106 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10107
10108 f_init(1, true);
10109 f_sleep(1.0);
10110
10111 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10112 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10113
10114 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10115 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010116 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010117}
10118
10119/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10120 * over. */
10121private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10122 f_sleep(1.0);
10123
10124 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10125 f_bssap_le_register_imsi(g_pars.imsi, omit);
10126
10127 /* Register to receive the Paging Command */
10128 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10129 g_chan_nr := new_chan_nr;
10130 f_rslem_register(0, g_chan_nr);
10131
10132 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10133 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10134 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10135 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10136
10137 var PDU_BSSAP_LE plr;
10138 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10139
10140 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10141 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010142 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 +020010143 do_clear := false, expect_bssmap_l3 := true);
10144
10145 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10146 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10147
10148 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10149 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10150
10151 /* SMLC got the TA from the BSC, now responds with geo information data. */
10152 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10153 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10154 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10155
10156 /* The lchan should still exist, it was from a CM Service Request. */
10157 f_mo_l3_transceive();
10158
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010159 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010160
10161 f_sleep(2.0);
10162 setverdict(pass);
10163}
10164testcase TC_cm_service_during_lcs_loc_req() 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
10171 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10172 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10173
10174 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10175 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010176 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010177}
10178
10179/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10180 * the new lchan after handover. */
10181private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10182 f_sleep(1.0);
10183
10184 f_establish_fully(omit, omit);
10185 f_bssap_le_register_imsi(g_pars.imsi, omit);
10186
10187 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10188 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10189
10190 var PDU_BSSAP_LE plr;
10191 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10192
10193 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10194 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10195
10196 var HandoverState hs := {
10197 rr_ho_cmpl_seen := false,
10198 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010199 old_chan_nr := -,
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010200 expect_target_tsc := c_BtsParams[1].tsc
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010201 };
10202 /* issue hand-over command on VTY */
10203 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10204 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10205 f_rslem_suspend(RSL1_PROC);
10206
10207 /* From the MGW perspective, a handover is is characterized by
10208 * performing one MDCX operation with the MGW. So we expect to see
10209 * one more MDCX during handover. */
10210 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10211
10212 alt {
10213 [] as_handover(hs);
10214 }
10215
10216 var PDU_BSSAP_LE rx_bsslap;
10217
10218 interleave {
10219 /* Expect the BSC to inform the MSC about the handover */
10220 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10221
10222 /* Expect the BSC to inform the SMLC about the handover */
10223 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10224 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10225 }
10226 }
10227
10228 /* SMLC now responds with geo information data. */
10229 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10230 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10231 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10232
10233 /* lchan still active */
10234 f_mo_l3_transceive(RSL1);
10235
10236 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010237 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010238
10239 f_sleep(2.0);
10240 setverdict(pass);
10241}
10242testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10243 var MSC_ConnHdlr vc_conn;
10244 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10245
10246 f_init(2, true);
10247 f_sleep(1.0);
10248 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10249 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010250 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010251}
10252
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010253private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10254{
10255 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10256 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10257 * another lchan. */
10258 g_pars.ra := 'b7'O;
10259 f_assignment_emerg_setup();
10260
10261 var PDU_BSSAP emerg_setup_data_ind_bssap;
10262 timer T := 3.0;
10263 T.start;
10264 alt {
10265 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10266 var PDU_ML3_MS_NW verify_emerg_setup;
10267 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10268 if (not isbound(verify_emerg_setup.msgs.cc.emergencySetup)) {
10269 setverdict(fail, "no emergency setup");
10270 }
10271 }
10272 [] BSSAP.receive {
10273 setverdict(fail, "unexpected BSSAP message!");
10274 }
10275 [] T.timeout {
10276 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10277 }
10278 }
10279
10280 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10281
10282 /* Do a Location Request in-between the CC call setup */
10283 f_bssap_le_register_imsi(g_pars.imsi, omit);
10284 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10285 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10286 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10287 /* SMLC got the TA from the BSC, now responds with geo information data. */
10288 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10289 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10290 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10291
10292 /* Go on with voice call assignment */
10293 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10294 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10295
10296 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
10297 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
10298 * seems a good idea to see how osmo-bsc reacts to this. */
10299 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
10300 elementIdentifier := '0B'O, /* overwritten */
10301 lengthIndicator := 0, /* overwritten */
10302 speechOrDataIndicator := '0001'B, /* speech */
10303 spare1_4 := '0000'B,
10304 channelRateAndType := ChRate_TCHForH_Fpref,
10305 speechId_DataIndicator := 'c2918105'O
10306 };
10307 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
10308 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
10309
10310 f_rslem_dchan_queue_enable();
10311
10312 var ExpectCriteria mgcpcrit := {
10313 connid := omit,
10314 endpoint := omit,
10315 transid := omit
10316 };
10317 f_create_mgcp_expect(mgcpcrit);
10318
10319 BSSAP.send(ass_cmd);
10320
10321 var AssignmentState st := valueof(ts_AssignmentStateInit);
10322 st.voice_call := true;
10323 st.is_assignment := false;
10324 alt {
10325 [] as_modify(st);
10326 [] as_Media();
10327 [st.modify_done] BSSAP.receive(exp_compl) {
10328 setverdict(pass);
10329 }
10330 }
10331
10332 /* Voice call carries on ... */
10333 f_sleep(2.0);
10334
10335 setverdict(pass);
10336 f_perform_clear();
10337}
10338
10339testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10340 var MSC_ConnHdlr vc_conn;
10341 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10342
10343 f_init(1, true);
10344 f_sleep(1.0);
10345 f_vty_allow_emerg_msc(true);
10346 f_vty_allow_emerg_bts(true, 0);
10347 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10348 vc_conn.done;
10349 f_shutdown_helper();
10350}
10351
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020010352private altstep no_bssmap_clear_req() runs on MSC_ConnHdlr {
10353 [] BSSAP.receive(tr_BSSMAP_ClearRequest) {
10354 setverdict(fail, "unexpected BSSMAP Clear Request");
10355 mtc.stop;
10356 }
10357}
10358
10359private type enumerated RslRel {
10360 RSLREL_REL_IND,
10361 RSLREL_CONN_FAIL
10362};
10363
10364private function f_emerg_call_and_lcs_loc_req_early_lchan_release(RslRel rsl_rel) runs on MSC_ConnHdlr
10365{
10366 g_pars.ra := f_rnd_ra_emerg();
10367 f_assignment_emerg_setup();
10368
10369 var PDU_BSSAP emerg_setup_data_ind_bssap;
10370 timer T := 3.0;
10371 T.start;
10372 alt {
10373 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10374 var PDU_ML3_MS_NW verify_emerg_setup;
10375 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10376 if (not ischosen(verify_emerg_setup.msgs.cc.emergencySetup)) {
10377 setverdict(fail, "no emergency setup");
10378 }
10379 }
10380 [] BSSAP.receive {
10381 setverdict(fail, "unexpected BSSAP message!");
10382 }
10383 [] T.timeout {
10384 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10385 }
10386 }
10387
10388 /* Start a Location Request to locate the emergency */
10389 f_bssap_le_register_imsi(g_pars.imsi, omit);
10390 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10391 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10392 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10393
10394 /* 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
10395 * do a Clear Command when the Location Response arrives. */
10396 activate(no_bssmap_clear_req());
10397
10398 /* the lchan gets interrupted while the Location Request has no response */
10399 select (rsl_rel) {
10400 case (RSLREL_REL_IND) {
10401 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10402 f_expect_lchan_rel(RSL, RSL_PROC);
10403 }
10404 case (RSLREL_CONN_FAIL) {
10405 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
10406 }
10407 case else {
10408 setverdict(fail, "Unknown RslRel type");
10409 mtc.stop;
10410 }
10411 }
10412
10413 /* Still expect the Location Response to find its way to the MSC. */
10414 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10415 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10416 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10417
10418 setverdict(pass);
10419
10420 select (rsl_rel) {
10421 case (RSLREL_REL_IND) {
10422 f_perform_clear_no_lchan();
10423 }
10424 case (RSLREL_CONN_FAIL) {
10425 f_perform_clear();
10426 }
10427 }
10428}
10429
10430private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind(charstring id) runs on MSC_ConnHdlr
10431{
10432 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_REL_IND);
10433}
10434
10435testcase TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() runs on test_CT {
10436 var MSC_ConnHdlr vc_conn;
10437 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10438
10439 f_init(1, true);
10440 f_sleep(1.0);
10441 f_vty_allow_emerg_msc(true);
10442 f_vty_allow_emerg_bts(true, 0);
10443 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_rel_ind), pars);
10444 vc_conn.done;
10445 f_shutdown_helper();
10446}
10447
10448private function f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail(charstring id) runs on MSC_ConnHdlr
10449{
10450 f_emerg_call_and_lcs_loc_req_early_lchan_release(RSLREL_CONN_FAIL);
10451}
10452
10453testcase TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() runs on test_CT {
10454 var MSC_ConnHdlr vc_conn;
10455 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10456
10457 f_init(1, true);
10458 f_sleep(1.0);
10459 f_vty_allow_emerg_msc(true);
10460 f_vty_allow_emerg_bts(true, 0);
10461 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req_early_lchan_conn_fail), pars);
10462 vc_conn.done;
10463 f_shutdown_helper();
10464}
10465
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010466/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10467private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10468 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10469
10470 /* Also disable attach for the single connected MSC */
10471 f_vty_msc_allow_attach(BSCVTY, { false });
10472
10473 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) ));
10474 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10475
10476 /* No MSC is found, expecting a proper release on RSL */
10477 interleave {
10478 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10479 f_logp(BSCVTY, "Got RSL RR Release");
10480 }
10481 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10482 f_logp(BSCVTY, "Got RSL Deact SACCH");
10483 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010484 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010485 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10486 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010487 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010488 }
10489 }
10490 setverdict(pass);
10491}
10492testcase TC_no_msc() runs on test_CT {
10493
10494 f_init(1, true);
10495 f_sleep(1.0);
10496 var MSC_ConnHdlr vc_conn;
10497 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10498
10499 f_ctrs_bsc_init(counternames_bsc_mscpool);
10500
10501 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10502 vc_conn.done;
10503
10504 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10505 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010506 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010507}
10508
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010509/* Dyn PDCH todo:
10510 * activate OSMO as TCH/F
10511 * activate OSMO as TCH/H
10512 * does the BSC-located PCU socket get the updated INFO?
10513 * what if no PCU is connected at the time?
10514 * is the info correct on delayed PCU (re)connect?
10515 */
Harald Welte94e0c342018-04-07 11:33:23 +020010516
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010517private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolf967afc2022-08-08 18:17:20 +020010518 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux_cn);
10519 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux_cn);
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010520
10521 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10522 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10523 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10524 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10525 g_pars.ass_codec_list.codecElements[0];
10526 if (isvalue(g_pars.expect_mr_s0_s7)) {
10527 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10528 g_pars.expect_mr_s0_s7;
10529 }
10530 }
10531 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10532 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10533 log("expecting ASS COMPL like this: ", exp_compl);
10534
10535 f_establish_fully(ass_cmd, exp_compl);
10536
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010537 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 +000010538
10539 var RSL_Message rsl;
10540
10541 timer T := 5.0;
10542 T.start;
10543 alt {
10544 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10545 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10546 log("Rx L3 from net: ", l3);
10547 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10548 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10549 mtc.stop;
10550 }
10551 }
10552 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10553 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10554 mtc.stop;
10555 }
10556 [] T.timeout {
10557 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10558 setverdict(pass);
10559 }
10560 }
10561 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010562
10563 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010564}
10565
10566/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10567 * osmo-bsc. */
10568testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10569 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10570 var MSC_ConnHdlr vc_conn;
10571
10572 f_init(1, true);
10573 f_sleep(1.0);
10574
10575 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10576 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10577 vc_conn.done;
10578 f_shutdown_helper();
10579}
10580
10581/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10582 */
10583testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10584 f_init_vty();
10585
10586 f_init(1, false);
10587 f_sleep(1.0);
10588
10589 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10590
10591 var ASP_RSL_Unitdata rx_rsl_ud;
10592 timer T := 5.0;
10593
10594 T.start;
10595 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010596 [] IPA_RSL[0][0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010597 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10598 T.stop;
10599 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10600 mtc.stop;
10601 }
10602 repeat;
10603 }
10604 [] T.timeout {
10605 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10606 setverdict(pass);
10607 }
10608 }
10609}
10610
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010611private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10612 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010613 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010614
10615 /* Trigger re-assignment to another lchan */
10616 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10617
10618 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10619 * one MDCX on MGCP. */
10620 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10621
10622 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10623 * as the old lchan used. */
10624 g_media.bts.ipa_crcx_seen := false;
10625 g_media.bts.ipa_mdcx_seen := false;
10626
10627 /* Send different BTS side RTP port number for the new lchan */
10628 g_media.bts.bts.port_nr := 4223;
10629
10630 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10631
10632 /* Trigger re-assignment. */
10633 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10634
10635 timer T := 5.0;
10636 T.start;
10637 alt {
10638 [] as_assignment(assignment_st);
10639 [] as_Media();
10640 [] T.timeout {
10641 break;
10642 }
10643 }
10644
10645 if (not assignment_st.assignment_done) {
10646 setverdict(fail, "Assignment did not complete");
10647 mtc.stop;
10648 }
10649
10650 f_check_mgcp_expectations()
10651 setverdict(pass);
10652
10653 f_sleep(2.0);
10654 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10655
10656 /* Instruct BSC to clear channel */
10657 var BssmapCause cause := 0;
10658 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10659 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010660 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10661 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010662 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010663 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010664 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010665 }
10666 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10667 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10668 }
10669 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010670 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010671
10672 f_sleep(0.5);
10673}
10674
10675testcase TC_reassignment_fr() runs on test_CT {
10676 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10677 var MSC_ConnHdlr vc_conn;
10678
10679 f_init(1, true);
10680 f_sleep(1.0);
10681
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010682 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010683
10684 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10685 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10686 vc_conn.done;
10687
10688 /* from f_establish_fully() */
10689 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10690 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10691 /* from re-assignment */
10692 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10693 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10694 f_ctrs_bsc_and_bts_verify();
10695 f_shutdown_helper();
10696}
10697
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010698const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10699const charstring REEST_CLEAR := "REEST_CLEAR";
10700const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10701
10702/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10703 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10704 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10705 * the MSC as the CM Re-Establishment is handled.
10706 *
10707 * MS bts0 bts1 bsc msc test-component
10708 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10709 * | | _1 wait a bit, to settle down
10710 * |<-x x--| | _1 "lose connection"
10711 * | | REEST_LOST_CONNECTION
10712 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10713 * | | REEST_CLEAR
10714 * | |<-0---| _1 Clear Command on first A-conn
10715 * | |--0-->| _1 Clear Complete
10716 * | |<----------------->| | _1 Release first channel
10717 * | | REEST_CLEAR_DONE
10718 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10719 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10720 *
10721 */
10722private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10723 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10724 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10725
10726 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10727 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10728
10729 f_establish_fully(ass_cmd, exp_compl);
10730
10731 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10732 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10733 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10734 f_sleep(2.0);
10735 COORD.send(REEST_LOST_CONNECTION);
10736
10737 alt {
10738 [] COORD.receive(REEST_CLEAR);
10739 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10740 setverdict(fail, "Unexpected channel release");
10741 mtc.stop;
10742 }
10743 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10744 setverdict(fail, "Unexpected channel release");
10745 mtc.stop;
10746 }
10747 }
10748 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010749 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010750 COORD.send(REEST_CLEAR_DONE);
10751}
10752
10753private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10754 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10755
10756 /* The MS lost the connection on the first channel, now establishes another one */
10757 COORD.receive(REEST_LOST_CONNECTION);
10758
10759 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10760 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10761 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10762
10763 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010764 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 +020010765 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10766
10767 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10768 COORD.send(REEST_CLEAR);
10769 COORD.receive(REEST_CLEAR_DONE);
10770
10771 f_sleep(2.0);
10772
10773 /* Answer the CM Re-Establishment with an Assignment Command. */
10774 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10775 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10776 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10777 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10778
10779 var AssignmentState st := valueof(ts_AssignmentStateInit);
10780 st.voice_call := true;
10781 st.is_assignment := true;
10782
10783 var ExpectCriteria mgcpcrit := {
10784 connid := omit,
10785 endpoint := omit,
10786 transid := omit
10787 };
10788 f_create_mgcp_expect(mgcpcrit);
10789
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010790 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010791
10792 BSSAP.send(ass_cmd);
10793
10794 var PDU_BSSAP bssap;
10795
10796 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010797 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10798 [] as_Media_ipacc(RSL1, RSL2);
10799 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010800 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10801 break;
10802 }
10803 }
10804
10805 f_sleep(3.0);
10806
10807 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010808 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010809}
10810
10811testcase TC_cm_reestablishment() runs on test_CT {
10812 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10813 var MSC_ConnHdlr vc_conn1;
10814
10815 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10816 var MSC_ConnHdlr vc_conn2;
10817 pars2.imsi := pars1.imsi;
10818 pars2.media_nr := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010819 pars2.expect_tsc := c_BtsParams[1].tsc;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010820
10821 f_init(2, true, guard_timeout := 40.0);
10822 f_sleep(1.0);
10823
10824 vc_conn1 := f_start_handler_create(pars1);
10825 vc_conn2 := f_start_handler_create(pars2);
10826 connect(vc_conn1:COORD, vc_conn2:COORD);
10827 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10828 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10829 vc_conn1.done;
10830 vc_conn2.done;
10831
10832 f_shutdown_helper();
10833}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010834
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010835function f_exp_ipa_rx_nonfatal(template (present) RSL_Message t_rx,
10836 boolean ignore_other_rx := true,
10837 BtsTrxIdx idx := {0, 0},
10838 float Tval := 2.0)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010839runs on test_CT return template (omit) RSL_Message {
10840 var ASP_RSL_Unitdata rx_rsl_ud;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010841 timer T := Tval;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010842
10843 T.start;
10844 alt {
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010845 [] IPA_RSL[idx.bts][idx.trx].receive(tr_ASP_RSL_UD(t_rx, ?)) -> value rx_rsl_ud {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010846 T.stop;
10847 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010848 [ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive { repeat; }
10849 [not ignore_other_rx] IPA_RSL[idx.bts][idx.trx].receive {
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010850 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10851 T.stop;
10852 return omit;
10853 }
10854 [] T.timeout {
10855 return omit;
10856 }
10857 }
10858 return rx_rsl_ud.rsl;
10859}
10860
10861private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
10862 f_vty_enter_cfg_bts(pt, bts_nr);
10863 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
10864 f_vty_transceive(pt, "exit");
10865 f_vty_transceive(pt, "exit");
10866 f_vty_transceive(pt, "exit");
10867}
10868
10869private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030010870 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010871 template (present) uint12_t arfcn := ?,
10872 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010873{
10874 var RSL_IE_Body full_imm_ass_info;
10875 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10876 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10877 mtc.stop;
10878 }
10879
10880 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10881 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10882 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010883 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010884 page_mode := ?);
10885 if (not match(rr_imm_ass, expect_imm_ass)) {
10886 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10887 setverdict(fail, "Failed to match Immediate Assignment");
10888 mtc.stop;
10889 }
10890}
10891
10892testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10893 var RSL_Message chan_act;
10894 var RSL_Message imm_ass;
10895
10896 f_init(1, false);
10897 f_sleep(1.0);
10898
10899 /* (should be the default anyway, just to make things clear) */
10900 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10901
10902 /* RA containing reason=LU */
10903 var GsmFrameNumber fn := 2342;
10904 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010905 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010906
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010907 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010908
10909 /* First send the Chan Act ACK */
10910 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010911 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010912 var RSL_IE_Body chan_ident_ie;
10913 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10914 setverdict(fail, "RSL Channel Identification IE is absent");
10915 mtc.stop;
10916 }
10917
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010918 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010919
10920 /* Then expect the Immediate Assignment, after we ACKed the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010921 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010922
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010923 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10924 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010925
10926 /* Check that the lchan is working */
10927 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010928 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010929
10930 var BSSAP_N_CONNECT_ind rx_c_ind;
10931 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010932 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010933 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10934
10935 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010936 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010937 f_shutdown_helper();
10938}
10939
10940testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10941 var RSL_Message chan_act;
10942 var RSL_Message imm_ass;
10943
10944 f_init(1, false);
10945 f_sleep(1.0);
10946
10947 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10948
10949 /* RA containing reason=LU */
10950 var GsmFrameNumber fn := 2342;
10951 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010952 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010953
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010954 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010955 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010956 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010957 var RSL_IE_Body chan_ident_ie;
10958 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10959 setverdict(fail, "RSL Channel Identification IE is absent");
10960 mtc.stop;
10961 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010962
Vadim Yanitskiy69170512022-06-03 01:49:42 +060010963 /* (set bts 0 cfg back to default) */
10964 f_vty_set_imm_ass(BSCVTY);
10965
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010966 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010967 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010968 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10969 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010970
10971 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010972 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010973
10974 /* Check that the lchan is working */
10975 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060010976 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010977
10978 var BSSAP_N_CONNECT_ind rx_c_ind;
10979 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010980 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010981 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10982
10983 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010984 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010985 f_shutdown_helper();
10986}
10987
Neels Hofmeyr23158742021-09-07 19:08:07 +020010988testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10989 var RSL_Message chan_act;
10990 var RSL_Message imm_ass;
10991
10992 f_init(1, false);
10993 f_sleep(1.0);
10994
10995 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10996
10997 /* RA containing reason=LU */
10998 var GsmFrameNumber fn := 2342;
10999 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011000 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011001
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011002 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011003 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011004 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr23158742021-09-07 19:08:07 +020011005 var RSL_IE_Body chan_ident_ie;
11006 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11007 setverdict(fail, "RSL Channel Identification IE is absent");
11008 mtc.stop;
11009 }
11010
Vadim Yanitskiy69170512022-06-03 01:49:42 +060011011 /* (set bts 0 cfg back to default) */
11012 f_vty_set_imm_ass(BSCVTY);
11013
Neels Hofmeyr23158742021-09-07 19:08:07 +020011014 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011015 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011016 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11017 chan_ident_ie.chan_ident.ch_desc.v.tsc);
11018
11019 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011020 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011021
11022 /* Check that the lchan is working */
11023 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011024 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyr23158742021-09-07 19:08:07 +020011025
11026 var BSSAP_N_CONNECT_ind rx_c_ind;
11027 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011028 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020011029 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11030
11031 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011032 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020011033 f_shutdown_helper();
11034}
11035
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011036testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
11037 /* change Timeslot 6 before f_init() starts RSL */
11038 f_init_vty();
11039 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11040 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11041
11042 f_init(1, false);
11043 f_sleep(1.0);
11044
11045 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11046 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011047 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11048 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011049
11050 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11051 f_ts_set_chcomb(0, 0, 6, "PDCH");
11052
11053 /* block all static timeslots so that the dyn TS will be used */
11054 f_disable_all_tch_f();
11055 f_disable_all_tch_h();
11056 f_disable_all_sdcch();
11057
11058 var RSL_Message chan_act;
11059 var RSL_Message imm_ass;
11060
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011061 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
11062
11063 /* RA containing reason=LU */
11064 var GsmFrameNumber fn := 2342;
11065 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011066 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011067
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011068 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011069 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
11070 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011071
11072 /* Now activation as SDCCH8 */
11073 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011074 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011075
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011076 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011077 var RSL_IE_Body chan_ident_ie;
11078 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11079 setverdict(fail, "RSL Channel Identification IE is absent");
11080 mtc.stop;
11081 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011082
11083 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011084 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011085 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11086 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011087
11088 /* Only now send the Chan Act ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011089 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011090
11091 /* Check that the lchan is working */
11092 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011093 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011094
11095 var BSSAP_N_CONNECT_ind rx_c_ind;
11096 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011097 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011098 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11099
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011100 /* (set bts 0 cfg back to default) */
11101 f_vty_set_imm_ass(BSCVTY);
11102
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011103 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011104 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011105 f_shutdown_helper();
11106}
11107
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011108testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
11109 /* change Timeslot 6 before f_init() starts RSL */
11110 f_init_vty();
11111 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
11112 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11113
11114 f_init(1, false);
11115 f_sleep(1.0);
11116
11117 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
11118 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011119 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11120 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011121
11122 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
11123 f_ts_set_chcomb(0, 0, 6, "PDCH");
11124
11125 /* block all static timeslots so that the dyn TS will be used */
11126 f_disable_all_tch_f();
11127 f_disable_all_tch_h();
11128 f_disable_all_sdcch();
11129
11130 var RSL_Message chan_act;
11131 var RSL_Message imm_ass;
11132
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011133 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
11134
11135 /* RA containing reason=LU */
11136 var GsmFrameNumber fn := 2342;
11137 var uint8_t ra := 2;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011138 f_ipa_tx(ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011139
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011140 /* Expect the dyn TS to deactivate PDCH first */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011141 f_exp_ipa_rx(tr_RSL_RF_CHAN_REL(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011142
11143 /* And already the Immediate Assignment even before the PDCH Deact ACK */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011144 imm_ass := f_exp_ipa_rx(tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011145
11146 /* continue the Osmo style PDCH Deact (usual chan rel) */
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011147 f_ipa_tx(ts_RSL_RF_CHAN_REL_ACK(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011148
11149 /* Now activation as SDCCH8 */
11150 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011151 var DchanTuple dt := {-, chan_nr, {0, 0}};
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011152
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011153 chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011154 var RSL_IE_Body chan_ident_ie;
11155 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11156 setverdict(fail, "RSL Channel Identification IE is absent");
11157 mtc.stop;
11158 }
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011159 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011160
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011161 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11162 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011163
11164 /* Check that the lchan is working */
11165 var octetstring l3 := '00010203040506'O;
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011166 f_ipa_tx(ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011167
11168 var BSSAP_N_CONNECT_ind rx_c_ind;
11169 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011170 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011171 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11172
Vadim Yanitskiy31778dd2022-06-14 20:55:16 +070011173 /* (set bts 0 cfg back to default) */
11174 f_vty_set_imm_ass(BSCVTY);
11175
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011176 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011177 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011178 f_shutdown_helper();
11179}
11180
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011181/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11182testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11183 var MSC_ConnHdlr vc_conn;
11184
11185 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11186 f_sleep(1.0);
11187
11188 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11189 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11190 "0,0,operational,unlocked,on,rsl-up;" &
11191 "1,0,operational,unlocked,on,rsl-up;" &
11192 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011193 "2,1,operational,unlocked,on,rsl-down;" &
11194 "2,2,operational,unlocked,on,rsl-down;" &
11195 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011196 "3,0,inoperational,locked,on,rsl-down;");
11197
11198 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11199 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11200 /* give it a moment to settle the FSM status */
11201 f_sleep(1.0);
11202
11203 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11204 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11205 * of "off"? But that's for a future patch if at all. */
11206 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11207 "0,0,operational,unlocked,on,rsl-up;" &
11208 "1,0,operational,locked,on,rsl-up;" &
11209 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011210 "2,1,operational,unlocked,on,rsl-down;" &
11211 "2,2,operational,unlocked,on,rsl-down;" &
11212 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011213 "3,0,inoperational,locked,on,rsl-down;");
11214
11215 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11216 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11217 f_sleep(1.0);
11218 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11219 "0,0,operational,unlocked,on,rsl-up;" &
11220 "1,0,operational,locked,on,rsl-up;" &
11221 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011222 "2,1,operational,unlocked,on,rsl-down;" &
11223 "2,2,operational,unlocked,on,rsl-down;" &
11224 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011225 "3,0,inoperational,locked,on,rsl-down;");
11226
11227 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11228 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11229 f_sleep(1.0);
11230 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11231 "0,0,operational,unlocked,on,rsl-up;" &
11232 "1,0,operational,unlocked,on,rsl-up;" &
11233 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011234 "2,1,operational,unlocked,on,rsl-down;" &
11235 "2,2,operational,unlocked,on,rsl-down;" &
11236 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011237 "3,0,inoperational,locked,on,rsl-down;");
11238
11239 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11240 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11241 f_sleep(1.0);
11242 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11243 "0,0,operational,unlocked,on,rsl-up;" &
11244 "1,0,operational,unlocked,on,rsl-up;" &
11245 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011246 "2,1,operational,unlocked,on,rsl-down;" &
11247 "2,2,operational,unlocked,on,rsl-down;" &
11248 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011249 "3,0,inoperational,locked,on,rsl-down;");
11250
11251 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11252 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11253 f_sleep(1.0);
11254 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11255 "0,0,operational,unlocked,on,rsl-up;" &
11256 "1,0,operational,unlocked,on,rsl-up;" &
11257 "2,0,operational,unlocked,on,rsl-down;" &
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011258 "2,1,operational,unlocked,on,rsl-down;" &
11259 "2,2,operational,unlocked,on,rsl-down;" &
11260 "2,3,operational,unlocked,on,rsl-down;" &
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011261 "3,0,inoperational,locked,on,rsl-down;");
11262
11263 f_shutdown_helper();
11264}
11265
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011266const CounterNameVals counternames_cm_serv_rej := {
11267 { "cm_serv_rej", 0 },
11268 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11269 { "cm_serv_rej:illegal_ms", 0 },
11270 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11271 { "cm_serv_rej:imei_not_accepted", 0 },
11272 { "cm_serv_rej:illegal_me", 0 },
11273 { "cm_serv_rej:plmn_not_allowed", 0 },
11274 { "cm_serv_rej:loc_not_allowed", 0 },
11275 { "cm_serv_rej:roaming_not_allowed", 0 },
11276 { "cm_serv_rej:network_failure", 0 },
11277 { "cm_serv_rej:synch_failure", 0 },
11278 { "cm_serv_rej:congestion", 0 },
11279 { "cm_serv_rej:srv_opt_not_supported", 0 },
11280 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11281 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11282 { "cm_serv_rej:call_can_not_be_identified", 0 },
11283 { "cm_serv_rej:incorrect_message", 0 },
11284 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11285 { "cm_serv_rej:msg_type_not_implemented", 0 },
11286 { "cm_serv_rej:msg_type_not_compatible", 0 },
11287 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11288 { "cm_serv_rej:condtional_ie_error", 0 },
11289 { "cm_serv_rej:msg_not_compatible", 0 },
11290 { "cm_serv_rej:protocol_error", 0 },
11291 { "cm_serv_rej:retry_in_new_cell", 0 }
11292};
11293
11294private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11295{
11296 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011297 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011298 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011299 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11300 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011301 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011302}
11303testcase TC_cm_serv_rej() runs on test_CT {
11304 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11305 var MSC_ConnHdlr vc_conn;
11306
11307 f_init(1, true);
11308 f_sleep(1.0);
11309
11310 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11311
11312 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11313 vc_conn.done;
11314
11315 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11316 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11317 f_ctrs_bts_verify();
11318
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011319 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011320 f_shutdown_helper();
11321}
11322
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011323/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11324 * Activ Ack (SYS#5627). */
11325private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11326 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011327
11328 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11329 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011330
11331 var BSSMAP_FIELD_CodecType codecType;
11332 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11333
11334 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11335
11336 /* First establish a signalling lchan */
11337 f_create_chan_and_exp();
11338 f_rslem_dchan_queue_enable();
11339
11340 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011341
11342 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011343 activate(as_Media_mgw(fail_on_dlcx := false));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011344
11345 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11346 f_rslem_register(0, chan_nr);
11347
11348 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11349 BSSAP.send(ass_cmd);
11350
11351
11352 /* Wait for the Channel Activ for the TCH channel */
11353 var ASP_RSL_Unitdata rx_rsl_ud;
11354 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11355
11356 /* make the original SDCCH disappear */
11357 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11358
11359 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11360 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11361
11362 interleave {
11363 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11364 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11365 }
11366
11367 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11368 BSSAP.receive(tr_BSSMAP_ClearComplete);
11369 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11370
11371 var MgcpCommand mgcp;
Vadim Yanitskiy6be4cf42022-06-04 21:25:47 +060011372 var MGCP_RecvFrom mrf;
11373 var template MgcpMessage msg_dlcx := { command := tr_DLCX };
11374 alt {
11375 [g_pars.aoip] MGCP.receive(tr_DLCX) -> value mgcp {
11376 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11377 }
11378 [not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
11379 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, MgcpMessage:{
11380 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
11381 }));
11382 }
11383 }
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011384
11385 f_sleep(0.5);
11386}
11387testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11388 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11389 var MSC_ConnHdlr vc_conn;
11390
11391 f_init(1, true);
11392 f_sleep(1.0);
11393
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011394 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11395 vc_conn.done;
11396
11397 f_shutdown_helper();
11398}
11399
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011400const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11401 { "all_allocated:sdcch", 0 },
11402 { "all_allocated:static_sdcch", 0 },
11403 { "all_allocated:tch", 0 },
11404 { "all_allocated:static_tch", 0 }
11405}
11406
11407private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11408{
11409 /* Make sure counters settle first */
11410 f_sleep(1.0);
11411
11412 /* Take a baseline of counters */
11413 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11414
11415 /* Elapse some time so that we see changes in counters, hopefully where expected */
11416 f_sleep(2.0);
11417
11418 /* Get new counters */
11419 var charstring_list all_changed := {};
11420 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11421 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11422
11423 /* Compare with expectations */
11424 var charstring_list all_expect_changed := {};
11425 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11426 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11427 }
11428 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11429}
11430
11431testcase TC_ratectr_all_available_allocated() runs on test_CT {
11432 var ASP_RSL_Unitdata rsl_ud;
11433 var integer i;
11434 var integer chreq_total, chreq_nochan;
11435
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011436 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011437 f_sleep(1.0);
11438
11439 /* Exhaust all dedicated SDCCH lchans.
11440 /* GSM 44.018 Table 9.1.8.2:
11441 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11442 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011443 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011444 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011445 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011446 }
11447
11448 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11449 * level.
11450 * All SDCCH are now occupied. */
11451 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11452
11453 /* Also fill up all remaining (TCH) channels */
11454 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011455 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011456 }
11457
11458 /* All TCH are now also occupied */
11459 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11460 "all_allocated:tch", "all_allocated:static_tch"});
11461
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011462 /* Clean up SDCCH lchans */
11463 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11464 f_perform_clear_test_ct(chan_cleanup[i]);
11465 }
11466
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011467 f_shutdown_helper();
11468}
11469
11470testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11471 var ASP_RSL_Unitdata rsl_ud;
11472 var integer i;
11473 var integer chreq_total, chreq_nochan;
11474
11475 f_init_vty();
11476 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11477 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11478 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11479
11480 f_init(1, guard_timeout := 60.0);
11481 f_sleep(1.0);
11482
11483 /* The dyn TS wants to activate PDCH mode, ACK that. */
11484 var RslChannelNr chan_nr;
11485 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011486 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11487 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011488
11489 /* Exhaust all dedicated SDCCH lchans.
11490 /* GSM 44.018 Table 9.1.8.2:
11491 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11492 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011493 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011494 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011495 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011496 }
11497
11498 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11499 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11500 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11501
11502 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11503 * Will release them later, so remember all the DchanTuples. */
11504 var DchanTuples dyn_sddch := {};
11505 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11506
11507 /* Also occupy the seven other SDCCH of the dyn TS */
11508 for (i := 0; i < 7; i := i+1) {
11509 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11510 }
11511
11512 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11513 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11514
11515 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11516 for (i := 0; i < 5; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011517 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011518 }
11519
11520 /* All TCH lchans are now also occupied, both static and dynamic */
11521 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11522 "all_allocated:tch", "all_allocated:static_tch"});
11523
11524 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11525 * incrementing. */
11526 var BssmapCause cause := 0;
11527 var DchanTuple dt := dyn_sddch[0];
11528 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011529 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011530
11531 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11532 * count as occupied, so those still both increment. */
11533 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11534 "all_allocated:tch", "all_allocated:static_tch"});
11535
11536 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11537 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11538 dt := dyn_sddch[i];
11539 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011540 f_exp_chan_rel_and_clear(dt);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011541 }
11542
11543 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11544 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiye5d393c2022-05-29 16:55:42 +060011545 f_exp_ipa_rx(tr_RSL_CHAN_ACT_PDCH(chan_nr));
11546 f_ipa_tx(ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011547
11548 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11549 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11550
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011551 /* Clean up SDCCH lchans */
11552 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11553 f_perform_clear_test_ct(chan_cleanup[i]);
11554 }
11555
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011556 /* clean up config */
11557 f_ts_reset_chcomb(0);
11558
11559 f_shutdown_helper();
11560}
11561
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060011562private function f_TC_chan_alloc_algo(DchanTuple dt, BtsTrxIdx idx)
11563runs on test_CT {
11564 /* MSC sends an Assignment Request */
11565 var PDU_BSSAP ass_cmd := f_gen_ass_req();
11566 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11567 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
11568 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
11569
11570 /* Expect the BSC to allocate a TCH channel on the given BTS/TRX */
11571 var RSL_Message rsl_chan_act := f_exp_ipa_rx(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), idx);
11572 /* Send CHAN ACT NACK, so that the requested TCH channel becomes BORKEN */
11573 f_ipa_tx(ts_RSL_CHAN_ACT_NACK(rsl_chan_act.ies[0].body.chan_nr, RSL_ERR_EQUIPMENT_FAIL), idx);
11574 /* Expect to receive an Assignment Failure */
11575 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail));
11576}
11577
11578testcase TC_chan_alloc_algo_ascending() runs on test_CT {
11579 /* We need to access BTS2, which has 4 TRXs */
11580 f_init(nr_bts := 3);
11581
11582 /* HACK: work around "Couldn't find Expect for CRCX" */
11583 vc_MGCP.stop;
11584
11585 f_vty_enter_cfg_bts(BSCVTY, 2);
11586 f_vty_transceive(BSCVTY, "channel allocator ascending");
11587 f_vty_transceive(BSCVTY, "end");
11588
11589 /* Expect the BSC to allocate 4 x TCH/F channels on BTS2/TRX0 */
11590 for (var integer i := 0; i < 4; i := i + 1) {
11591 var DchanTuple dt := f_est_dchan('23'O, 23, '00000000'O, {2, 0});
11592 f_TC_chan_alloc_algo(dt, {2, 0});
11593 f_perform_clear_test_ct(dt);
11594 }
11595
11596 /* At this point all 4 x TCH/F channels are BORKEN, but they will be
11597 * resurrected upon the A-bis/OML link re-establishment. */
11598 f_shutdown_helper();
11599}
11600
11601testcase TC_chan_alloc_algo_descending() runs on test_CT {
11602 /* We need to access BTS2, which has 4 TRXs */
11603 f_init(nr_bts := 3);
11604
11605 /* HACK: work around "Couldn't find Expect for CRCX" */
11606 vc_MGCP.stop;
11607
11608 f_vty_enter_cfg_bts(BSCVTY, 2);
11609 f_vty_transceive(BSCVTY, "channel allocator descending");
11610 f_vty_transceive(BSCVTY, "end");
11611
11612 /* Expect the BSC to allocate 5 x TCH/F channels on BTS2/TRX3 */
11613 for (var integer i := 0; i < 5; i := i + 1) {
11614 var DchanTuple dt := f_est_dchan('23'O, 23, '00000000'O, {2, 0});
11615 f_TC_chan_alloc_algo(dt, {2, 3});
11616 f_perform_clear_test_ct(dt);
11617 }
11618
11619 /* At this point all 5 x TCH/F channels are BORKEN, but they will be
11620 * resurrected upon the A-bis/OML link re-establishment. */
11621 f_shutdown_helper();
11622}
11623
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011624testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
11625 const BtsTrxIdx TRX0 := {2, 0};
11626 const BtsTrxIdx TRX3 := {2, 3};
11627
11628 /* We need to access BTS2, which has 4 TRXs */
11629 f_init(nr_bts := 3);
11630
11631 /* HACK: work around "Couldn't find Expect for CRCX" */
11632 vc_MGCP.stop;
11633
11634 f_vty_enter_cfg_bts(BSCVTY, 2);
11635 f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
11636 f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
11637 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
11638 f_vty_transceive(BSCVTY, "end");
11639
11640 var DchanTuple dt;
11641
11642 f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
11643 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11644 f_TC_chan_alloc_algo(dt, TRX0);
11645 f_perform_clear_test_ct(dt);
11646
11647 f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
11648 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11649 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11650 ts_RSL_IE_UplinkMeas(30, 0),
11651 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011652 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011653 f_TC_chan_alloc_algo(dt, TRX0);
11654 f_perform_clear_test_ct(dt);
11655
11656 f_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
11657 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11658 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11659 ts_RSL_IE_UplinkMeas(45, 0),
11660 ts_RSL_IE_BS_Power(0)), TRX0);
11661 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11662 ts_RSL_IE_UplinkMeas(48, 0),
11663 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011664 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011665 f_TC_chan_alloc_algo(dt, TRX0);
11666 f_perform_clear_test_ct(dt);
11667
11668 f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
11669 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11670 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11671 ts_RSL_IE_UplinkMeas(50, 0),
11672 ts_RSL_IE_BS_Power(0)), TRX0);
11673 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11674 ts_RSL_IE_UplinkMeas(58, 0),
11675 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011676 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011677 f_TC_chan_alloc_algo(dt, TRX3);
11678 f_perform_clear_test_ct(dt);
11679
11680 f_vty_enter_cfg_bts(BSCVTY, 2);
11681 f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
11682 f_vty_transceive(BSCVTY, "end");
11683
11684 f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
11685 dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
11686 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
11687 ts_RSL_IE_UplinkMeas(50, 0),
11688 ts_RSL_IE_BS_Power(0)), TRX0);
11689 f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
11690 ts_RSL_IE_UplinkMeas(58, 0),
11691 ts_RSL_IE_BS_Power(0)), TRX0);
Vadim Yanitskiy5f6dd352022-08-24 03:08:32 +070011692 f_sleep(0.3); /* give the IUT some time to process sent MRs */
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070011693 f_TC_chan_alloc_algo(dt, TRX0);
11694 f_perform_clear_test_ct(dt);
11695
11696 f_vty_enter_cfg_bts(BSCVTY, 2);
11697 f_vty_transceive(BSCVTY, "channel allocator ascending");
11698 f_vty_transceive(BSCVTY, "end");
11699
11700 /* At this point some TCH/F channels are BORKEN, but they will be
11701 * resurrected upon the A-bis/OML link re-establishment. */
11702 f_shutdown_helper();
11703}
11704
Harald Welte28d943e2017-11-25 15:00:50 +010011705control {
Harald Welte898113b2018-01-31 18:32:21 +010011706 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010011707 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010011708 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020011709 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
11710 * these in the AoIP test suite. */
11711 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11712 execute( TC_stat_num_msc_connected_1() );
11713 execute( TC_stat_num_msc_connected_2() );
11714 execute( TC_stat_num_msc_connected_3() );
11715 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020011716 execute( TC_stat_num_bts_connected_1() );
11717 execute( TC_stat_num_bts_connected_2() );
11718 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010011719 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011720 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020011721 execute( TC_ctrl_location() );
11722 }
Harald Welte898113b2018-01-31 18:32:21 +010011723
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011724 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020011725 execute( TC_si2quater_2_earfcns() );
11726 execute( TC_si2quater_3_earfcns() );
11727 execute( TC_si2quater_4_earfcns() );
11728 execute( TC_si2quater_5_earfcns() );
11729 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020011730 execute( TC_si2quater_12_earfcns() );
11731 execute( TC_si2quater_23_earfcns() );
11732 execute( TC_si2quater_32_earfcns() );
11733 execute( TC_si2quater_33_earfcns() );
11734 execute( TC_si2quater_42_earfcns() );
11735 execute( TC_si2quater_48_earfcns() );
11736 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020011737 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020011738 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011739
Harald Welte898113b2018-01-31 18:32:21 +010011740 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010011741 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010011742 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010011743 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020011744 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020011745 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010011746 execute( TC_chan_act_ack_est_ind_noreply() );
11747 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010011748 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010011749 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070011750 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010011751 execute( TC_chan_rel_rll_rel_ind() );
11752 execute( TC_chan_rel_conn_fail() );
11753 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020011754 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
11755 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010011756 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010011757 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020011758 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010011759 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010011760 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020011761 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010011762
Harald Weltecfe2c962017-12-15 12:09:32 +010011763 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010011764
11765 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010011766 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010011767 execute( TC_assignment_csd() );
11768 execute( TC_assignment_ctm() );
11769 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011770 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11771 execute( TC_assignment_aoip_tla_v6() );
11772 }
Harald Welte235ebf12017-12-15 14:18:16 +010011773 execute( TC_assignment_fr_a5_0() );
11774 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011775 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020011776 execute( TC_assignment_fr_a5_1_codec_missing() );
11777 }
Harald Welte235ebf12017-12-15 14:18:16 +010011778 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020011779 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020011780 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020011781 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011782 execute( TC_ciph_mode_a5_0() );
11783 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020011784 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020011785 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011786 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020011787 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010011788
Harald Welte60aa5762018-03-21 19:33:13 +010011789 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020011790 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010011791 execute( TC_assignment_codec_hr() );
11792 execute( TC_assignment_codec_efr() );
11793 execute( TC_assignment_codec_amr_f() );
11794 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011795
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011796 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010011797 execute( TC_assignment_codec_amr_f_S1() );
11798 execute( TC_assignment_codec_amr_h_S1() );
11799 execute( TC_assignment_codec_amr_f_S124() );
11800 execute( TC_assignment_codec_amr_h_S124() );
11801 execute( TC_assignment_codec_amr_f_S0() );
11802 execute( TC_assignment_codec_amr_f_S02() );
11803 execute( TC_assignment_codec_amr_f_S024() );
11804 execute( TC_assignment_codec_amr_f_S0247() );
11805 execute( TC_assignment_codec_amr_h_S0() );
11806 execute( TC_assignment_codec_amr_h_S02() );
11807 execute( TC_assignment_codec_amr_h_S024() );
11808 execute( TC_assignment_codec_amr_h_S0247() );
11809 execute( TC_assignment_codec_amr_f_S01234567() );
11810 execute( TC_assignment_codec_amr_f_S0234567() );
11811 execute( TC_assignment_codec_amr_f_zero() );
11812 execute( TC_assignment_codec_amr_f_unsupp() );
11813 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000011814 execute( TC_assignment_codec_amr_f_start_mode_auto() );
11815 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000011816 execute( TC_assignment_codec_amr_f_start_mode_4() );
11817 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000011818 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011819 }
Harald Welte60aa5762018-03-21 19:33:13 +010011820
Philipp Maierac09bfc2019-01-08 13:41:39 +010011821 execute( TC_assignment_codec_fr_exhausted_req_hr() );
11822 execute( TC_assignment_codec_fr_exhausted_req_fr() );
11823 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
11824 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
11825 execute( TC_assignment_codec_hr_exhausted_req_fr() );
11826 execute( TC_assignment_codec_hr_exhausted_req_hr() );
11827 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
11828 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
11829 execute( TC_assignment_codec_req_hr_fr() );
11830 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020011831 execute( TC_assignment_sdcch_exhausted_req_signalling() );
11832 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
11833 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010011834
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020011835 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020011836
Harald Welte898113b2018-01-31 18:32:21 +010011837 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010011838 execute( TC_rll_est_ind_inact_lchan() );
11839 execute( TC_rll_est_ind_inval_sapi1() );
11840 execute( TC_rll_est_ind_inval_sapi3() );
11841 execute( TC_rll_est_ind_inval_sacch() );
11842
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070011843 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
11844 execute( TC_tch_dlci_link_id_sapi() );
11845
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011846 /* SAPI N Reject triggered by RLL establishment failures */
11847 execute( TC_rll_rel_ind_sapi_n_reject() );
11848 execute( TC_rll_err_ind_sapi_n_reject() );
11849 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070011850 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011851
Harald Welte898113b2018-01-31 18:32:21 +010011852 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010011853 execute( TC_paging_imsi_nochan() );
11854 execute( TC_paging_tmsi_nochan() );
11855 execute( TC_paging_tmsi_any() );
11856 execute( TC_paging_tmsi_sdcch() );
11857 execute( TC_paging_tmsi_tch_f() );
11858 execute( TC_paging_tmsi_tch_hf() );
11859 execute( TC_paging_imsi_nochan_cgi() );
11860 execute( TC_paging_imsi_nochan_lac_ci() );
11861 execute( TC_paging_imsi_nochan_ci() );
11862 execute( TC_paging_imsi_nochan_lai() );
11863 execute( TC_paging_imsi_nochan_lac() );
11864 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010011865 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
11866 execute( TC_paging_imsi_nochan_rnc() );
11867 execute( TC_paging_imsi_nochan_lac_rnc() );
11868 execute( TC_paging_imsi_nochan_lacs() );
11869 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010011870 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010011871 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010011872 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010011873 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010011874 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020011875 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020011876 execute( TC_paging_450req_no_paging_load_ind() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010011877
11878 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010011879 execute( TC_rsl_unknown_unit_id() );
11880
11881 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011882
11883 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020011884 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011885 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010011886 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010011887 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010011888 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010011889 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011890
Harald Welte261af4b2018-02-12 21:20:39 +010011891 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020011892 execute( TC_ho_int_a5_0() );
11893 execute( TC_ho_int_a5_1() );
11894 execute( TC_ho_int_a5_3() );
11895 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000011896 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011897
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011898 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020011899 execute( TC_ho_out_fail_no_msc_response() );
11900 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020011901 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011902
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011903 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020011904 execute( TC_ho_into_this_bsc_a5_0() );
11905 execute( TC_ho_into_this_bsc_a5_1() );
11906 execute( TC_ho_into_this_bsc_a5_3() );
11907 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010011908 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
11909 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010011910 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011911 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11912 execute( TC_ho_into_this_bsc_tla_v6() );
11913 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020011914 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030011915 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010011916 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020011917 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020011918 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
11919 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011920 execute( TC_ho_in_fail_msc_clears() );
11921 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
11922 execute( TC_ho_in_fail_no_detect() );
11923 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010011924 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011925
Neels Hofmeyr91401012019-07-11 00:42:35 +020011926 execute( TC_ho_neighbor_config_1() );
11927 execute( TC_ho_neighbor_config_2() );
11928 execute( TC_ho_neighbor_config_3() );
11929 execute( TC_ho_neighbor_config_4() );
11930 execute( TC_ho_neighbor_config_5() );
11931 execute( TC_ho_neighbor_config_6() );
11932 execute( TC_ho_neighbor_config_7() );
11933
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011934 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010011935 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010011936 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020011937
11938 execute( TC_dyn_pdch_ipa_act_deact() );
11939 execute( TC_dyn_pdch_ipa_act_nack() );
11940 execute( TC_dyn_pdch_osmo_act_deact() );
11941 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010011942 execute( TC_dyn_ts_sdcch8_act_deact() );
11943 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
11944 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
11945 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011946
Stefan Sperling0796a822018-10-05 13:01:39 +020011947 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020011948 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020011949
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010011950 /* Power control related */
11951 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020011952 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020011953
11954 /* MSC pooling */
11955 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
11956 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
11957 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
11958 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
11959 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11960 execute( TC_mscpool_L3Compl_on_1_msc() );
11961 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
11962 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
11963 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
11964 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
11965 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
11966 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
11967 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
11968 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
11969 execute( TC_mscpool_paging_and_response_imsi() );
11970 execute( TC_mscpool_paging_and_response_tmsi() );
11971 execute( TC_mscpool_no_allow_attach_round_robin() );
11972 execute( TC_mscpool_no_allow_attach_valid_nri() );
11973 }
11974
Harald Welte99f3ca02018-06-14 13:40:29 +020011975 execute( TC_early_conn_fail() );
11976 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020011977 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011978
Philipp Maier783681c2020-07-16 16:47:06 +020011979 /* Emergency call handling (deny / allow) */
11980 execute( TC_assignment_emerg_setup_allow() );
11981 execute( TC_assignment_emerg_setup_deny_msc() );
11982 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020011983 execute( TC_emerg_premption() );
11984
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070011985 /* Frequency hopping parameters handling */
11986 execute( TC_fh_params_chan_activ() );
11987 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070011988 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070011989 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070011990 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020011991
11992 if (mp_enable_lcs_tests) {
11993 execute( TC_lcs_loc_req_for_active_ms() );
11994 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
11995 execute( TC_lcs_loc_req_for_idle_ms() );
11996 execute( TC_lcs_loc_req_no_subscriber() );
11997 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
11998 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
11999 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
12000 execute( TC_cm_service_during_lcs_loc_req() );
12001 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020012002 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr61f9dc52022-05-12 23:04:40 +020012003 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_rel_ind() );
12004 execute( TC_emerg_call_and_lcs_loc_req_early_lchan_conn_fail() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020012005 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000012006
12007 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000012008
12009 execute( TC_refuse_chan_act_to_vamos() );
12010 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000012011
12012 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020012013
12014 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020012015
12016 execute( TC_imm_ass_post_chan_ack() );
12017 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020012018 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020012019 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020012020 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020012021
12022 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012023
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020012024 execute( TC_ratectr_all_available_allocated() );
12025 execute( TC_ratectr_all_available_allocated_dyn() );
12026
Neels Hofmeyrb7581872021-11-07 14:02:49 +010012027 execute( TC_cm_serv_rej() );
12028
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020012029 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012030
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012031 /* Channel allocator */
12032 execute( TC_chan_alloc_algo_ascending() );
12033 execute( TC_chan_alloc_algo_descending() );
Vadim Yanitskiy7c29c4e2022-06-18 03:07:50 +070012034 execute( TC_chan_alloc_algo_ass_dynamic() );
Vadim Yanitskiy1a16d312022-05-31 16:14:01 +060012035
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010012036 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
12037 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
12038 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010012039}
12040
12041}