blob: a553f25990218d147be5a9bf1b4fefebf8174a8d [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;
24
Neels Hofmeyr4f118412020-06-04 15:25:10 +020025import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010026import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010027import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010028import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010029import from IPL4asp_Types all;
30
Harald Welte6f521d82017-12-11 19:52:02 +010031import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020032import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020033import from BSSAP_LE_Adapter all;
34import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020035import from BSSAP_LE_Types all;
36import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010037import from BSSAP_CodecPort all;
38import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010039import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010040import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010041import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020042import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010043import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010044import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010045import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010046import from MGCP_Templates all;
47import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020048import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010049
Harald Welte96c94412017-12-09 03:12:45 +010050import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010051import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010052import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010053
Daniel Willmannebdecc02020-08-12 15:30:17 +020054import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
Harald Weltebc03c762018-02-12 18:09:38 +010059import from Osmocom_VTY_Functions all;
60import from TELNETasp_PortType all;
61
Harald Welte6f521d82017-12-11 19:52:02 +010062import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010063import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010064import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010065import from L3_Templates all;
66import from GSM_RR_Types all;
67
Stefan Sperlingc307e682018-06-14 15:15:46 +020068import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010069import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020070import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010071
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010072import from SCCPasp_Types all;
73
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020074import from GSM_SystemInformation all;
75import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020076import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020077
Neels Hofmeyrbf720202021-10-02 12:58:24 +020078type record of integer integer_list;
79
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 */
Neels Hofmeyrf246a922020-05-13 02:27:10 +020082const integer NUM_MSC := 3;
Harald Welteae026692017-12-09 01:03:01 +010083const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010084
Harald Welte799c97b2017-12-14 17:50:30 +010085/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020086const integer NUM_TCHH_PER_BTS := 2;
87const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020088const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010089
Neels Hofmeyrbf720202021-10-02 12:58:24 +020090/* Default Training Sequence Code expected for bts[i]:
91 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
92 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
93 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
94 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
95 */
96const integer_list BTS_TSC := {
97 2,
98 3,
99 4,
100 4
101}
Harald Welte4003d112017-12-09 22:35:39 +0100102
Harald Welte21b46bd2017-12-17 19:46:32 +0100103/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100104type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100105 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100106 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100107}
108
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200109/* Default list of counters for an 'msc' entity. */
110const CounterNameVals counternames_msc_mscpool := {
111 { "mscpool:subscr:new", 0 },
112 { "mscpool:subscr:known", 0 },
113 { "mscpool:subscr:reattach", 0 },
114 { "mscpool:subscr:attach_lost", 0 },
115 { "mscpool:subscr:paged", 0 }
116};
117
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000118/* List of global mscpool counters, not related to a specific 'msc' entity. */
119const CounterNameVals counternames_bsc_mscpool := {
120 { "mscpool:subscr:no_msc", 0 }
121};
122
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000123/* Default list of counters for 'bsc' and 'bts' entities. */
124const CounterNameVals counternames_bsc_bts_handover := {
125 { "assignment:attempted", 0 },
126 { "assignment:completed", 0 },
127 { "assignment:stopped", 0 },
128 { "assignment:no_channel", 0 },
129 { "assignment:timeout", 0 },
130 { "assignment:failed", 0 },
131 { "assignment:error", 0 },
132
133 { "handover:attempted", 0 },
134 { "handover:completed", 0 },
135 { "handover:stopped", 0 },
136 { "handover:no_channel", 0 },
137 { "handover:timeout", 0 },
138 { "handover:failed", 0 },
139 { "handover:error", 0 },
140
141 { "intra_cell_ho:attempted", 0 },
142 { "intra_cell_ho:completed", 0 },
143 { "intra_cell_ho:stopped", 0 },
144 { "intra_cell_ho:no_channel", 0 },
145 { "intra_cell_ho:timeout", 0 },
146 { "intra_cell_ho:failed", 0 },
147 { "intra_cell_ho:error", 0 },
148
149 { "intra_bsc_ho:attempted", 0 },
150 { "intra_bsc_ho:completed", 0 },
151 { "intra_bsc_ho:stopped", 0 },
152 { "intra_bsc_ho:no_channel", 0 },
153 { "intra_bsc_ho:timeout", 0 },
154 { "intra_bsc_ho:failed", 0 },
155 { "intra_bsc_ho:error", 0 },
156
157 { "interbsc_ho_out:attempted", 0 },
158 { "interbsc_ho_out:completed", 0 },
159 { "interbsc_ho_out:stopped", 0 },
160 { "interbsc_ho_out:timeout", 0 },
161 { "interbsc_ho_out:failed", 0 },
162 { "interbsc_ho_out:error", 0 },
163
164 { "interbsc_ho_in:attempted", 0 },
165 { "interbsc_ho_in:completed", 0 },
166 { "interbsc_ho_in:stopped", 0 },
167 { "interbsc_ho_in:no_channel", 0 },
168 { "interbsc_ho_in:timeout", 0 },
169 { "interbsc_ho_in:failed", 0 },
170 { "interbsc_ho_in:error", 0 }
171};
172
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100173const CounterNameVals counternames_bts_handover := {
174 { "incoming_intra_bsc_ho:attempted", 0 },
175 { "incoming_intra_bsc_ho:completed", 0 },
176 { "incoming_intra_bsc_ho:stopped", 0 },
177 { "incoming_intra_bsc_ho:no_channel", 0 },
178 { "incoming_intra_bsc_ho:timeout", 0 },
179 { "incoming_intra_bsc_ho:failed", 0 },
180 { "incoming_intra_bsc_ho:error", 0 }
181};
182
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200183/* Set of all System Information received during one RSL port's startup.
184 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
185 * broadcast that SI type. That will be reflected as 'omit' here.
186 */
187type record SystemInformationConfig {
188 SystemInformationType1 si1 optional,
189 SystemInformationType2 si2 optional,
190 SystemInformationType2bis si2bis optional,
191 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200192 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200193 SystemInformationType3 si3 optional,
194 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100195 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200196 SystemInformationType5 si5 optional,
197 SystemInformationType5bis si5bis optional,
198 SystemInformationType5ter si5ter optional,
199 SystemInformationType6 si6 optional
200};
201
202const SystemInformationConfig SystemInformationConfig_omit := {
203 si1 := omit,
204 si2 := omit,
205 si2bis := omit,
206 si2ter := omit,
207 si2quater := omit,
208 si3 := omit,
209 si4 := omit,
210 si13 := omit,
211 si5 := omit,
212 si5bis := omit,
213 si5ter := omit,
214 si6 := omit
215};
216
217/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
218template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
219 template uint3_t meas_bw := 3)
220:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
221 meas_bw_presence := '1'B,
222 meas_bw := meas_bw);
223
224/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200225template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200226 template uint3_t prio := 3,
227 template (present) uint5_t thresh_high := 20,
228 template uint5_t thresh_low := 10,
229 template uint5_t qrxlevmin := 22)
230:= tr_EUTRAN_NeighbourCells(
231 cell_desc_list := cell_desc_list,
232 prio_presence := '1'B,
233 prio := prio,
234 thresh_high := thresh_high,
235 thresh_low_presence := '1'B,
236 thresh_low := thresh_low,
237 qrxlevmin_presence := '1'B,
238 qrxlevmin := qrxlevmin);
239
240template SystemInformationConfig SystemInformationConfig_default := {
241 si1 := {
242 cell_chan_desc := '8FB38000000000000000000000000000'O,
243 rach_control := {
244 max_retrans := RACH_MAX_RETRANS_7,
245 tx_integer := '1001'B,
246 cell_barr_access := false,
247 re_not_allowed := true,
248 acc := '0000010000000000'B
249 },
250 rest_octets := ?
251 },
252 si2 := {
253 bcch_freq_list := '00000000000000000000000000000000'O,
254 ncc_permitted := '11111111'B,
255 rach_control := {
256 max_retrans := RACH_MAX_RETRANS_7,
257 tx_integer := '1001'B,
258 cell_barr_access := false,
259 re_not_allowed := true,
260 acc := '0000010000000000'B
261 }
262 },
263 si2bis := omit,
264 si2ter := {
265 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
266 rest_octets := ?
267 },
268 si2quater := {
269 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
270 },
271 si3 := {
272 cell_id := 0,
273 lai := {
274 mcc_mnc := '001F01'H,
275 lac := 1
276 },
277 ctrl_chan_desc := {
278 msc_r99 := true,
279 att := true,
280 bs_ag_blks_res := 1,
281 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
282 si22ind := false,
283 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
284 spare := '00'B,
285 bs_pa_mfrms := 3,
286 t3212 := 30
287 },
288 cell_options := {
289 dn_ind := false,
290 pwrc := false,
291 dtx := MS_SHALL_USE_UL_DTX,
292 radio_link_tout_div4 := 7
293 },
294 cell_sel_par := {
295 cell_resel_hyst_2dB := 2,
296 ms_txpwr_max_cch := 7,
297 acs := '0'B,
298 neci := true,
299 rxlev_access_min := 0
300 },
301 rach_control := {
302 max_retrans := RACH_MAX_RETRANS_7,
303 tx_integer := '1001'B,
304 cell_barr_access := false,
305 re_not_allowed := true,
306 acc := '0000010000000000'B
307 },
308 rest_octets := {
309 sel_params := {
310 presence := '0'B,
311 params := omit
312 },
313 pwr_offset := {
314 presence := '0'B,
315 offset := omit
316 },
317 si_2ter_ind := '1'B,
318 early_cm_ind := '0'B,
319 sched_where := {
320 presence := '0'B,
321 where := omit
322 },
323 gprs_ind := {
324 presence := '1'B,
325 ind := {
326 ra_colour := 0,
327 si13_pos := '0'B
328 }
329 },
330 umts_early_cm_ind := '1'B,
331 si2_quater_ind := {
332 presence := '1'B,
333 ind := '0'B
334 },
335 iu_mode_ind := omit,
336 si21_ind := {
337 presence := '0'B,
338 pos := omit
339 }
340 }
341 },
342 si4 := {
343 lai := {
344 mcc_mnc := '001F01'H,
345 lac := 1
346 },
347 cell_sel_par := {
348 cell_resel_hyst_2dB := 2,
349 ms_txpwr_max_cch := 7,
350 acs := '0'B,
351 neci := true,
352 rxlev_access_min := 0
353 },
354 rach_control := {
355 max_retrans := RACH_MAX_RETRANS_7,
356 tx_integer := '1001'B,
357 cell_barr_access := false,
358 re_not_allowed := true,
359 acc := '0000010000000000'B
360 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200361 cbch_chan_desc := {
362 iei := '64'O,
363 v := {
364 chan_nr := {
365 u := {
366 sdcch4 := {
367 tag := '001'B,
368 sub_chan := 2
369 }
370 },
371 tn := 0
372 },
373 tsc := 2,
374 h := false,
375 arfcn := 871,
376 maio_hsn := omit
377 }
378 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200379 cbch_mobile_alloc := omit,
380 rest_octets := {
381 sel_params := {
382 presence := '0'B,
383 params := omit
384 },
385 pwr_offset := {
386 presence := '0'B,
387 offset := omit
388 },
389 gprs_ind := {
390 presence := '1'B,
391 ind := {
392 ra_colour := 0,
393 si13_pos := '0'B
394 }
395 },
396 s_presence := '0'B,
397 s := omit
398 }
399 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100400 si13 := {
401 rest_octets := {
402 presence := '1'B,
403 bcch_change_mark := ?,
404 si_change_field := '0000'B,
405 presence2 := '0'B,
406 si13_change_mark := omit,
407 gprs_ma := omit,
408 zero := '0'B, /* PBCCH not present in cell */
409 rac := 0,
410 spgc_ccch_sup := '0'B,
411 priority_access_thr := '110'B,
412 network_control_order := '00'B,
413 gprs_cell_opts := {
414 nmo := '01'B,
415 t3168 := '011'B,
416 t3192 := '010'B,
417 drx_timer_max := '011'B,
418 access_burst_type := '0'B,
419 control_ack_type := '1'B,
420 bs_cv_max := 15,
421 pan_presence := '1'B,
422 pan_dec := 1,
423 pan_inc := 1,
424 pan_max := '111'B,
425 ext_info_presence := ?,
426 ext_info_length := *,
427 ext_info := *
428 },
429 gprs_pwr_ctrl_params := {
430 alpha := 0,
431 t_avg_w := '10000'B,
432 t_avg_t := '10000'B,
433 pc_meas_chan := '0'B,
434 n_avg_i := '1000'B
435 }
436 }
437 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200438 si5 := {
439 bcch_freq_list := '10000000000000000000000000000000'O
440 },
441 si5bis := omit,
442 si5ter := {
443 extd_bcch_freq_list := '9E050020000000000000000000000000'O
444 },
445 si6 := {
446 cell_id := 0,
447 lai := {
448 mcc_mnc := '001F01'H,
449 lac := 1
450 },
451 cell_options := {
452 dtx_ext := '1'B,
453 pwrc := false,
454 dtx := '01'B,
455 radio_link_timeout := '0111'B
456 },
457 ncc_permitted := '11111111'B,
Vadim Yanitskiy348b07c2022-03-10 17:11:22 +0300458 rest_octets := {
459 pch_nch_info := ?,
460 vbs_vgcs_options := ?,
461 dtm_support := '0'B,
462 rac := omit,
463 max_lapdm := omit,
464 band_ind := '0'B /* C0 ARFCN indicates 1800 band */
465 }
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200466 }
467 };
468
469
470/* List of all the System Information received on all RSL ports */
471type record of SystemInformationConfig SystemInformationConfig_list;
472
473function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
474{
475 var RSL_IE_Body sysinfo_type_ie;
476 var RSL_IE_SysinfoType si_type;
477 var octetstring data;
478
479 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
480 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
481 mtc.stop;
482 }
483 si_type := sysinfo_type_ie.sysinfo_type;
484
485 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
486 var RSL_IE_Body bcch_ie;
487 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
488 data := bcch_ie.other.payload;
489 }
490 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
491 var RSL_IE_Body l3_ie;
492 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
493 data := l3_ie.l3_info.payload;
494 }
495 } else {
496 setverdict(fail, "Don't understand this System Information message");
497 mtc.stop;
498 }
499
500 var boolean handled := false;
501
502 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
503 handled := true;
504
505 if (si_type == RSL_SYSTEM_INFO_1) {
506 if (not isbound(data)) {
507 si.si1 := omit;
508 } else {
509 si.si1 := dec_SystemInformation(data).payload.si1;
510 }
511 } else if (si_type == RSL_SYSTEM_INFO_2) {
512 if (not isbound(data)) {
513 si.si2 := omit;
514 } else {
515 si.si2 := dec_SystemInformation(data).payload.si2;
516 }
517 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
518 if (not isbound(data)) {
519 si.si2bis := omit;
520 } else {
521 si.si2bis := dec_SystemInformation(data).payload.si2bis;
522 }
523 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
524 if (not isbound(data)) {
525 si.si2ter := omit;
526 } else {
527 si.si2ter := dec_SystemInformation(data).payload.si2ter;
528 }
529 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
530 if (not isbound(data)) {
531 si.si2quater := {};
532 } else {
533 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
534 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
535 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
536 }
537 } else if (si_type == RSL_SYSTEM_INFO_3) {
538 if (not isbound(data)) {
539 si.si3 := omit;
540 } else {
541 si.si3 := dec_SystemInformation(data).payload.si3;
542 }
543 } else if (si_type == RSL_SYSTEM_INFO_4) {
544 if (not isbound(data)) {
545 si.si4 := omit;
546 } else {
547 si.si4 := dec_SystemInformation(data).payload.si4;
548 }
549 } else if (si_type == RSL_SYSTEM_INFO_13) {
550 if (not isbound(data)) {
551 si.si13 := omit;
552 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100553 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200554 }
555 } else {
556 handled := false;
557 }
558 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
559 handled := true;
560
561 if (si_type == RSL_SYSTEM_INFO_5) {
562 if (not isbound(data)) {
563 si.si5 := omit;
564 } else {
565 si.si5 := dec_SystemInformation(data).payload.si5;
566 }
567 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
568 if (not isbound(data)) {
569 si.si5bis := omit;
570 } else {
571 si.si5bis := dec_SystemInformation(data).payload.si5bis;
572 }
573 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
574 if (not isbound(data)) {
575 si.si5ter := omit;
576 } else {
577 si.si5ter := dec_SystemInformation(data).payload.si5ter;
578 }
579 } else if (si_type == RSL_SYSTEM_INFO_6) {
580 if (not isbound(data)) {
581 si.si6 := omit;
582 } else {
583 si.si6 := dec_SystemInformation(data).payload.si6;
584 }
585 } else {
586 handled := false;
587 }
588 }
589
590 if (not handled) {
591 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
592 }
593}
594
Harald Weltea4ca4462018-02-09 00:17:14 +0100595type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100596 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100597 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100598 /* RSL common Channel Port (for RSL_Emulation) */
599 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100600 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100601 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100602 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200603 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
604 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100605 /* Configure/manage IPA_Emulation: */
606 port IPA_CFG_PT IPA_CFG_PORT;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100607
Daniel Willmann191e0d92018-01-17 12:44:35 +0100608 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100609 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100610
Daniel Willmannebdecc02020-08-12 15:30:17 +0200611 /* StatsD */
612 var StatsD_Checker_CT vc_STATSD;
613
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200614 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200615 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100616 /* for old legacy-tests only */
617 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200618 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100619
Harald Welte21b46bd2017-12-17 19:46:32 +0100620 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100621 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100622
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200623 /* Osmux is enabled through VTY */
624 var boolean g_osmux_enabled := false;
625
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100626 /*Configure T(tias) over VTY, seconds */
627 var integer g_bsc_sccp_timer_ias := 7 * 60;
628 /*Configure T(tiar) over VTY, seconds */
629 var integer g_bsc_sccp_timer_iar := 15 * 60;
630
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200631 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100632 timer T_guard := 30.0;
633
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200634 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000635 var CounterNameValsList g_ctr_bsc;
636 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200637
638 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
639 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100640}
641
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200642type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100643modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100644 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100645 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100646 /* port number to which to establish the IPA OML connections */
647 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100648 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100649 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100650 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100651 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200652 /* port number to which to listen for STATSD metrics */
653 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100654 /* IP address at which the test binds */
655 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100656
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200657 RAN_Configurations mp_bssap_cfg := {
658 {
659 transport := BSSAP_TRANSPORT_AoIP,
660 sccp_service_type := "mtp3_itu",
661 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
662 own_pc := 185, /* 0.23.1 first MSC emulation */
663 own_ssn := 254,
664 peer_pc := 187, /* 0.23.3 osmo-bsc */
665 peer_ssn := 254,
666 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200667 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200668 },
669 {
670 transport := BSSAP_TRANSPORT_AoIP,
671 sccp_service_type := "mtp3_itu",
672 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
673 own_pc := 2, /* 0.0.2 second MSC emulation */
674 own_ssn := 254,
675 peer_pc := 187, /* 0.23.3 osmo-bsc */
676 peer_ssn := 254,
677 sio := '83'O,
678 rctx := 2
679 },
680 {
681 transport := BSSAP_TRANSPORT_AoIP,
682 sccp_service_type := "mtp3_itu",
683 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
684 own_pc := 3, /* 0.0.3 third MSC emulation */
685 own_ssn := 254,
686 peer_pc := 187, /* 0.23.3 osmo-bsc */
687 peer_ssn := 254,
688 sio := '83'O,
689 rctx := 3
690 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100691 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200692
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200693 /* Must match per BTS config in osmo-bsc.cfg */
694 phys_chan_configs phys_chan_config := {
695 "CCCH+SDCCH4+CBCH",
696 "TCH/F",
697 "TCH/F",
698 "TCH/F",
699 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600700 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200701 "PDCH",
702 "PDCH"
703 };
704
Harald Welte47cd0e32020-08-21 12:39:11 +0200705 BSSAP_LE_Configuration mp_bssap_le_cfg := {
706 sccp_service_type := "mtp3_itu",
707 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200708 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200709 own_ssn := 252, /* SMLC side SSN */
710 peer_pc := 187, /* 0.23.3 osmo-bsc */
711 peer_ssn := 250, /* BSC side SSN */
712 sio := '83'O,
713 rctx := 6
714 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200715 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200716
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100717 /* Value set in osmo-bsc.cfg "ms max power" */
718 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600719
720 /* Whether to check for memory leaks */
721 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100722}
723
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200724friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200725
726 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200727 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200728 pars.aoip := true;
729 } else {
730 pars.aoip := false;
731 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100732 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200733 pars.mscpool.bssap_idx := bssap_idx;
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200734 pars.expect_tsc := BTS_TSC[0];
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300735 pars.imsi := f_rnd_imsi('00101'H);
736
737 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200738
Philipp Maier48604732018-10-09 15:00:37 +0200739 return pars;
740}
741
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200742/* Convenience functions for rate counters using g_ctr_msc. */
743
744private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
745 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
746 log("initial msc rate counters: ", g_ctr_msc);
747}
748
749private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200750 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200751}
752
753/* f_ctrs_msc_init();
754 * f_do_thing(on_msc := 0);
755 * f_do_thing(on_msc := 0);
756 * f_do_other(on_msc := 1);
757 * f_ctrs_msc_add(0, "thing", 2);
758 * f_ctrs_msc_add(1, "other");
759 * f_ctrs_msc_verify();
760 */
761private function f_ctrs_msc_verify() runs on test_CT {
762 log("verifying msc rate counters: ", g_ctr_msc);
763 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
764}
765
766/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
767 * f_ctrs_msc_init();
768 * f_do_thing(on_msc := 0);
769 * f_do_thing(on_msc := 0);
770 * f_do_thing(on_msc := 0);
771 * f_ctrs_msc_expect(0, "thing", 3);
772 */
773private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
774 f_ctrs_msc_add(msc_nr, countername, val);
775 f_ctrs_msc_verify();
776}
777
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000778/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
779
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100780private 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 +0000781 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100782 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100783}
784
785function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
786 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000787 f_ctrs_bsc_init(counternames);
788}
789
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100790private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
791 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100792 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100793 f_ctrs_bsc_init(counternames_bsc_bts_handover);
794}
795
796private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000797 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100798}
799
800private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
801 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000802 f_ctrs_bsc_add(countername, val);
803}
804
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100805function f_ctrs_bts_verify() runs on test_CT {
806 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
807}
808
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000809/* f_ctrs_bsc_and_bts_init();
810 * f_do_thing(on_bts := 0);
811 * f_do_thing(on_bts := 0);
812 * f_do_other(on_bts := 1);
813 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
814 * f_ctrs_bsc_and_bts_add(1, "other");
815 * f_ctrs_bsc_and_bts_verify();
816 */
817private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100818 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000819 f_ctrs_bsc_verify();
820}
821
822/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
823 * f_ctrs_bsc_and_bts_init();
824 * f_do_thing(on_bts := 0);
825 * f_do_thing(on_bts := 0);
826 * f_do_thing(on_bts := 0);
827 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
828 */
829private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
830 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
831 f_ctrs_bsc_and_bts_verify();
832}
833
834
835/* Convenience functions for rate counters using g_ctr_bsc. */
836
837private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
838 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
839 log("initial bsc rate counters: ", g_ctr_bsc);
840}
841
842private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
843 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
844}
845
846/* f_ctrs_bsc_init();
847 * f_do_thing();
848 * f_do_thing();
849 * f_do_other();
850 * f_ctrs_bsc_add("thing", 2);
851 * f_ctrs_bsc_add("other");
852 * f_ctrs_bsc_verify();
853 */
854private function f_ctrs_bsc_verify() runs on test_CT {
855 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
856}
857
858/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
859 * f_ctrs_bsc_init();
860 * f_do_thing();
861 * f_ctrs_bsc_expect("thing", 1);
862 */
863private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
864 f_ctrs_bsc_add(countername, val);
865 f_ctrs_bsc_verify();
866}
867
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200868
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200869friend function f_shutdown_helper() runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100870 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600871 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100872 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
873 }
874
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200875 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100876 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200877 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100878}
879
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200880private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100881 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200882 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100883 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200884 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
885 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100886 T.start;
887 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200888 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
889 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200890 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100891 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200892 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200893 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100894 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200895 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200896 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100897 repeat;
898 }
899 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200900 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200901 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200902 /* If we received a RESET after ours was sent, it
903 may be a race condition where the other peer beacame
904 available after we sent it, but we are in a desired
905 state anyway, so go forward. */
906 if (not reset_received) {
907 setverdict(fail);
908 }
909 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100910 }
Harald Welte28d943e2017-11-25 15:00:50 +0100911}
912
Harald Welteae026692017-12-09 01:03:01 +0100913type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100914 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100915 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100916 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100917 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100918 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100919 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100920 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100921 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100922}
923
Harald Welte21b46bd2017-12-17 19:46:32 +0100924/*! Start the IPA/RSL related bits for one IPA_Client.
925 * \param clnt IPA_Client for which to establish
926 * \param bsc_host IP address / hostname of the BSC
927 * \param bsc_port TCP port number of the BSC
928 * \param i number identifying this BTS
929 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100930function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
931 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100932runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100933 timer T := 10.0;
934
Harald Welte96c94412017-12-09 03:12:45 +0100935 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100936 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100937 clnt.ccm_pars := c_IPA_default_ccm_pars;
938 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
939 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100940 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100941 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Harald Welte89ab1912018-02-23 18:56:29 +0100942 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100943 }
Harald Welteae026692017-12-09 01:03:01 +0100944
945 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100946 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT);
Harald Welte624f9632017-12-16 19:26:04 +0100947 if (handler_mode) {
948 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
949 } else {
950 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
951 }
Harald Welteae026692017-12-09 01:03:01 +0100952
Harald Welte5d1a2202017-12-13 19:51:29 +0100953 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100954 if (handler_mode) {
955 clnt.vc_RSL.start(RSL_Emulation.main());
956 return;
957 }
Harald Welteae026692017-12-09 01:03:01 +0100958
959 /* wait for IPA RSL link to connect and send ID ACK */
960 T.start;
961 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700962 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100963 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700964 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100965 }
Harald Welte60e823a2017-12-10 14:10:59 +0100966 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100967 [] IPA_RSL[i].receive { repeat }
968 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100969 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200970 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100971 }
972 }
973}
974
Harald Welte12055472018-03-17 20:10:08 +0100975function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100976 var IPL4asp_Types.Result res := {
977 errorCode := omit,
978 connId := omit,
979 os_error_code := omit,
980 os_error_text := omit
981 };
982
Harald Welte12055472018-03-17 20:10:08 +0100983 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
984 return;
985 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100986
987 /* Alive components don't finish sockets (TCP FIN) when they are
988 * stopped. Hence, we need to manually call close() on them to make sure
989 * the IUT knows about it. */
990 f_ipa_cfg_disconnect(IPA_CFG_PORT, res);
991
Harald Welte12055472018-03-17 20:10:08 +0100992 clnt.vc_IPA.stop;
993 if (isbound(clnt.vc_RSL)) {
994 clnt.vc_RSL.stop;
995 }
996}
997
Harald Welte21b46bd2017-12-17 19:46:32 +0100998/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100999function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1000 timer T := secs_max;
1001 T.start;
1002 while (true) {
1003 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1004 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001005 /* the 'degraded' state exists from OML connection time, and we have to wait
1006 * until all MO's are initialized */
1007 T.start(1.0);
1008 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001009 return;
1010 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001011 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001012 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001013 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001014 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001015 }
1016 }
1017}
1018
Harald Welte21b46bd2017-12-17 19:46:32 +01001019/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001020altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001021 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001022 [] T_guard.timeout {
1023 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001024 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001025 }
Harald Welte60e823a2017-12-10 14:10:59 +01001026 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001027 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001028 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001029 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +01001030 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001031 }
Harald Welte28d943e2017-11-25 15:00:50 +01001032}
1033
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001034altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001035 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001036 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001037 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001038 }
1039}
1040
Daniel Willmann191e0d92018-01-17 12:44:35 +01001041function f_init_mgcp(charstring id) runs on test_CT {
1042 id := id & "-MGCP";
1043
1044 var MGCPOps ops := {
1045 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1046 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1047 };
1048 var MGCP_conn_parameters mgcp_pars := {
1049 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001050 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001051 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001052 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001053 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1054 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001055 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001056 };
1057
Harald Welte71389132021-12-09 21:58:18 +01001058 vc_MGCP := MGCP_Emulation_CT.create(id) alive;
Daniel Willmann191e0d92018-01-17 12:44:35 +01001059 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1060}
1061
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001062/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1063 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1064 * OsmuxCID IE.
1065 */
1066private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1067 f_vty_enter_cfg_msc(BSCVTY, 0);
1068 if (allow) {
1069 f_vty_transceive(BSCVTY, "osmux on");
1070 } else {
1071 f_vty_transceive(BSCVTY, "osmux off");
1072 }
1073 f_vty_transceive(BSCVTY, "exit");
1074 f_vty_transceive(BSCVTY, "exit");
1075 g_osmux_enabled := allow;
1076}
1077
Max2253c0b2018-11-06 19:28:05 +01001078function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001079 if (BSCVTY.checkstate("Mapped")) {
1080 /* skip initialization if already executed once */
1081 return;
1082 }
Harald Weltebc03c762018-02-12 18:09:38 +01001083 map(self:BSCVTY, system:BSCVTY);
1084 f_vty_set_prompts(BSCVTY);
1085 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001086 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1087 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001088}
1089
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001090friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001091{
1092 // log on TTCN3 log output
1093 log(log_msg);
1094 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001095 if (pt.checkstate("Mapped")) {
1096 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1097 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001098}
1099
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001100private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1101{
1102 if (rsl_idx >= lengthof(g_system_information)) {
1103 g_system_information[rsl_idx] := SystemInformationConfig_omit
1104 }
1105 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1106}
1107
1108altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1109 var ASP_RSL_Unitdata rx_rsl_ud;
1110
1111 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1112 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1113 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1114 repeat;
1115 }
1116 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1117 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1118 repeat;
1119 }
1120 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1121 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1122 repeat;
1123 }
1124 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1125 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1126 repeat;
1127 }
1128
1129 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1130 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1131 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1132 repeat;
1133 }
1134 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1135 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1136 repeat;
1137 }
1138 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1139 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1140 repeat;
1141 }
1142 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1143 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1144 repeat;
1145 }
1146}
1147
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001148/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1149private type record of boolean my_BooleanList;
1150
1151private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1152{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001153 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1154
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001155 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001156 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1157 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1158 * stepping into that config node. */
1159 log("msc ", msc_nr, " is not configured, skipping");
1160 continue;
1161 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001162 f_vty_enter_cfg_msc(pt, msc_nr);
1163 if (allow_attach_list[msc_nr]) {
1164 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1165 f_vty_transceive(pt, "allow-attach", strict := false);
1166 } else {
1167 f_vty_transceive(pt, "no allow-attach", strict := false);
1168 }
1169 f_vty_transceive(pt, "exit");
1170 f_vty_transceive(pt, "exit");
1171 }
1172}
1173
Harald Welte21b46bd2017-12-17 19:46:32 +01001174/* global initialization function
1175 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001176 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1177 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1178 */
1179function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001180 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001181 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001182
Harald Welteae026692017-12-09 01:03:01 +01001183 if (g_initialized) {
1184 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001185 }
Harald Welteae026692017-12-09 01:03:01 +01001186 g_initialized := true;
1187
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001188 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001189 activate(as_Tguard());
1190
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001191 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001192 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001193
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001194 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001195 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1196
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001197 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1198 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1199 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1200 }
1201
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001202 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001203 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001204 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1205 * MSC-side BSSAP emulation */
1206 if (handler_mode) {
1207 var RanOps ranops := MSC_RanOps;
1208 ranops.use_osmux := g_osmux_enabled;
1209 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1210 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1211 f_ran_adapter_start(g_bssap[bssap_idx]);
1212 } else {
1213 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1214 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1215 f_ran_adapter_start(g_bssap[bssap_idx]);
1216 f_legacy_bssap_reset();
1217 }
Harald Welte67089ee2018-01-17 22:19:03 +01001218 }
Harald Welted5833a82018-05-27 16:52:56 +02001219
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001220 if (mp_enable_lcs_tests) {
1221 if (handler_mode) {
1222 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1223 } else {
1224 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1225 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1226 }
1227 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001228 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001229
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001230 /* start the test with exactly all enabled MSCs allowed to attach */
1231 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1232
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001233 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001234
Daniel Willmann191e0d92018-01-17 12:44:35 +01001235 f_init_mgcp("VirtMSC");
1236
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001237 for (var integer i := 0; i < nr_bts; i := i+1) {
1238 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001239 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001240
1241 /* Emit a marker to appear in the SUT's own logging output */
1242 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001243}
Harald Welte696ddb62017-12-08 14:01:43 +01001244
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001245function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1246runs on test_CT {
1247 /* wait until osmo-bts-omldummy has respawned */
1248 f_wait_oml(bts_idx, "degraded", 5.0);
1249
1250 /* start RSL connection */
1251 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1252 /* wait until BSC tells us "connected" */
1253 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001254}
1255
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001256function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1257 template SystemInformationConfig expect_si)
1258runs on test_CT {
1259 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1260
1261 f_init_bts(bts_idx, handler_mode);
1262
1263 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1264 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1265 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1266 */
1267 f_sleep(5.0);
1268 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1269
1270 deactivate(sysinfo);
1271
1272 if (match(g_system_information[bts_idx], expect_si)) {
1273 setverdict(pass);
1274 } else {
1275 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1276 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1277 setverdict(fail, "received SI does not match expectations");
1278 return;
1279 }
1280}
1281
Maxd4e56962018-10-31 19:08:25 +01001282/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001283function f_exp_ipa_rx(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001284runs on test_CT return RSL_Message {
1285 var ASP_RSL_Unitdata rx_rsl_ud;
1286 timer T := t_secs;
1287
1288 T.start;
1289 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001290 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001291 T.stop;
1292 }
1293 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001294 [] T.timeout {
1295 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001296 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001297 }
Harald Welteae026692017-12-09 01:03:01 +01001298 }
1299 return rx_rsl_ud.rsl;
1300}
1301
Harald Welte21b46bd2017-12-17 19:46:32 +01001302/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001303function f_ipa_tx(integer bts_nr, template (value) RSL_Message t_tx, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001304runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001305 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001306}
1307
1308
Harald Welte4003d112017-12-09 22:35:39 +01001309/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001310testcase TC_chan_act_noreply() runs on test_CT {
1311 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001312 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001313
Harald Welte89d42e82017-12-17 16:42:41 +01001314 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001315
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001316 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001317 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001318 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001319}
1320
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001321const CounterNameVals counternames_bts_chreq := {
1322 { "chreq:total", 0 },
1323 { "chreq:attempted_emerg", 0 },
1324 { "chreq:attempted_call", 0 },
1325 { "chreq:attempted_location_upd", 0 },
1326 { "chreq:attempted_pag", 0 },
1327 { "chreq:attempted_pdch", 0 },
1328 { "chreq:attempted_other", 0 },
1329 { "chreq:attempted_unknown", 0 },
1330 { "chreq:successful", 0 },
1331 { "chreq:successful_emerg", 0 },
1332 { "chreq:successful_call", 0 },
1333 { "chreq:successful_location_upd", 0 },
1334 { "chreq:successful_pag", 0 },
1335 { "chreq:successful_pdch", 0 },
1336 { "chreq:successful_other", 0 },
1337 { "chreq:successful_unknown", 0 },
1338 { "chreq:no_channel", 0 },
1339 { "chreq:max_delay_exceeded", 0 }
1340};
1341
1342/* verify the "chreq:*" counters */
1343private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1344{
1345 var GsmFrameNumber fn := 23;
1346
1347 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1348
1349 var RSL_Message rx_rsl;
1350 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1351 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1352 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1353
1354 f_ctrs_bts_add(0, "chreq:total");
1355 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1356 f_ctrs_bts_verify();
1357
1358 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1359 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1360
1361 f_ctrs_bts_add(0, "chreq:successful");
1362 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1363 f_ctrs_bts_verify();
1364
1365 /* test is done, release RSL Conn Fail Ind to clean up */
1366 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1367 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1368 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
1369 f_sleep(1.0);
1370}
1371
Harald Welte4003d112017-12-09 22:35:39 +01001372testcase TC_chan_act_counter() runs on test_CT {
1373 var BSSAP_N_UNITDATA_ind ud_ind;
1374 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001375 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001376
Harald Welte89d42e82017-12-17 16:42:41 +01001377 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001378
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001379 f_vty_allow_emerg_bts(true, 0);
1380
1381 f_ctrs_bts_init(1, counternames_bts_chreq);
1382
1383 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1384 f_chan_act_counter('a3'O, "emerg");
1385
1386 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1387 f_chan_act_counter('43'O, "call");
1388
1389 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1390 f_chan_act_counter('03'O, "location_upd");
1391
1392 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1393 f_chan_act_counter('23'O, "pag");
1394 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1395 f_chan_act_counter('33'O, "pag");
1396
1397 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1398 /* no PCU, so PDCH not allowed. Skip this test for now. */
1399 /* f_chan_act_counter('7b'O, "pdch"); */
1400
1401 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1402 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001403
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001404 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001405}
1406
Harald Welteae026692017-12-09 01:03:01 +01001407/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001408private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001409 var RSL_Message rx_rsl;
1410
Harald Welteae026692017-12-09 01:03:01 +01001411 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001412 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001413
1414 /* expect BSC to disable the channel again if there's no RLL EST IND */
1415 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1416
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001417 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001418}
1419
Philipp Maier9c60a622020-07-09 15:08:46 +02001420/* Normal variant */
1421testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001422 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001423 f_TC_chan_act_ack_noest();
1424}
1425
1426/* Emergency call variant */
1427testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1428 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001429 f_init(1);
1430 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001431 f_TC_chan_act_ack_noest(ra := 'A5'O);
1432}
1433
Philipp Maier606f07d2020-08-12 17:21:58 +02001434/* Emergency call variant, but emergency calls are not allowed */
1435testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1436 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1437
1438 var RSL_Message rx_rsl;
1439 var GsmRrMessage rr;
1440
1441 f_init(1);
1442 f_vty_allow_emerg_bts(false, 0);
1443
1444 IPA_RSL[0].clear;
1445 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1446
1447 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1448 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1449 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1450 setverdict(pass);
1451 } else {
1452 setverdict(fail, "immediate assignment not rejected");
1453 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001454
1455 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001456}
1457
Harald Welteae026692017-12-09 01:03:01 +01001458/* Test behavior if MSC never answers to CR */
1459testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001460 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1461 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001462 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001463 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001464
Harald Welte89d42e82017-12-17 16:42:41 +01001465 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001466
1467 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001468 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001469
1470 var octetstring l3 := '00010203040506'O
1471 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1472
1473 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1474
1475 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001476 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001477 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001478 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001479}
1480
1481/* Test behavior if MSC answers with CREF to CR */
1482testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1483 var BSSAP_N_CONNECT_ind rx_c_ind;
1484 var RSL_Message rx_rsl;
1485
Harald Welte89d42e82017-12-17 16:42:41 +01001486 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001487
1488 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001489 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001490
1491 var octetstring l3 := '00010203040506'O
1492 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1493
1494 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1495 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1496
1497 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001498 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001499 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001500}
1501
Harald Welte618ef642017-12-14 14:58:20 +01001502/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1503testcase TC_chan_act_nack() runs on test_CT {
1504 var RSL_Message rx_rsl;
1505 var integer chact_nack;
1506
Harald Welte89d42e82017-12-17 16:42:41 +01001507 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001508
1509 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1510
1511 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1512 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1513 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1514
1515 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1516
1517 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1518 f_sleep(0.5);
1519
1520 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1521
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001522 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001523}
1524
Harald Welte799c97b2017-12-14 17:50:30 +01001525/* Test for channel exhaustion due to RACH overload */
1526testcase TC_chan_exhaustion() runs on test_CT {
1527 var ASP_RSL_Unitdata rsl_ud;
1528 var integer i;
1529 var integer chreq_total, chreq_nochan;
1530
Harald Welte89d42e82017-12-17 16:42:41 +01001531 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001532
1533 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1534 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1535
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001536 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001537 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1538 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001539 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 +01001540 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001541 }
1542
1543 IPA_RSL[0].clear;
1544
Harald Weltedd8cbf32018-01-28 12:07:52 +01001545 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001546 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001547
1548 /* now expect additional channel activations to fail */
1549 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1550
1551 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001552 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001553 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1554 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001555 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001556 var GsmRrMessage rr;
1557 /* match on IMM ASS REJ */
1558 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1559 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1560 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001561 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001562 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1563 chreq_nochan+1);
1564 setverdict(pass);
1565 } else {
1566 repeat;
1567 }
1568 }
1569 [] IPA_RSL[0].receive { repeat; }
1570 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001571 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001572}
1573
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001574/* Test channel deactivation due to silence from MS */
1575testcase TC_chan_deact_silence() runs on test_CT {
1576 var RslChannelNr chan_nr;
1577
1578 f_init(1);
1579
1580 /* Request for a dedicated channel */
1581 chan_nr := f_chreq_act_ack('23'O);
1582
1583 /* Wait some time until the channel is released */
1584 f_sleep(2.0);
1585
1586 /* Expect CHANnel RELease */
1587 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001588 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001589 log("Received CHANnel RELease");
1590 setverdict(pass);
1591 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001592 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001593 /* See OS#3709, OsmoBSC should not send Immediate
1594 * Assignment Reject since a dedicated channel was
1595 * already allocated, and Immediate Assignment was
1596 * already sent. */
1597 setverdict(fail, "Unexpected Immediate Assignment!");
1598 }
1599 [] IPA_RSL[0].receive {
1600 setverdict(fail, "Unexpected RSL message!");
1601 }
1602 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001603 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001604}
1605
Harald Weltecfe2c962017-12-15 12:09:32 +01001606/***********************************************************************
1607 * Assignment Testing
1608 ***********************************************************************/
1609
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001610/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1611 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001612testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001613 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001614
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001615 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1616 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001617 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001618 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001619}
1620
Harald Welte16a4adf2017-12-14 18:54:01 +01001621/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001622testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001623 var BSSAP_N_CONNECT_ind rx_c_ind;
1624 var RSL_Message rx_rsl;
1625 var DchanTuple dt;
1626
Harald Welte89d42e82017-12-17 16:42:41 +01001627 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001628
1629 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001630 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001631 /* send assignment without AoIP IEs */
1632 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1633 } else {
1634 /* Send assignmetn without CIC in IPA case */
1635 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1636 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1637 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1638 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001639 alt {
1640 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1641 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1642 }
Harald Welte235ebf12017-12-15 14:18:16 +01001643 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001644 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1645 setverdict(pass);
1646 }
1647 [] BSSAP.receive { repeat; }
1648 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001649 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001650 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001651}
1652
Harald Welteed848512018-05-24 22:27:58 +02001653/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001654function 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 +02001655 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001656 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001657 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001658 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001659 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001660 if (osmux_enabled) {
1661 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1662 } else {
1663 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1664 }
Harald Welteed848512018-05-24 22:27:58 +02001665 } else {
1666 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001667 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001668 }
1669 return ass_cmd;
1670}
1671
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001672function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001673 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001674 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1675 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001676 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001677
1678 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1679 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001680 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1681 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001682 if (ispresent(enc)) {
1683 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001684 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1685 if (ispresent(v_enc.enc_alg_chosen)) {
1686 chosenEncryptionAlgorithm := valueof(
1687 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1688 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1689 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001690 if (ispresent(v_enc.enc_kc128)) {
1691 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1692 }
1693 }
1694
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001695 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001696 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001697 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001698 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1699 cell_id_source := cell_id_source,
1700 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001701 encryptionInformation := encryptionInformation,
1702 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001703 kC128 := kc128,
1704 /* on AoIP, allow "all" codecs (until we add more concise
1705 * tests) */
1706 codecList := ts_BSSMAP_IE_CodecList(
1707 {ts_CodecAMR_F, ts_CodecAMR_H,
1708 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001709 } else {
1710 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001711 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1712 cell_id_source := cell_id_source,
1713 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001714 encryptionInformation := encryptionInformation,
1715 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1716 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001717 }
1718 return ho_req;
1719}
1720
Harald Welteed848512018-05-24 22:27:58 +02001721/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001722function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001723 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001724 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001725 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001726 if (expect_osmux) {
1727 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1728 } else {
1729 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1730 }
Harald Welteed848512018-05-24 22:27:58 +02001731 } else {
1732 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001733 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001734 }
1735 return exp_compl;
1736}
1737
Harald Welte235ebf12017-12-15 14:18:16 +01001738/* Run everything required up to sending a caller-specified assignment command and expect response */
1739function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001740runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001741 var BSSAP_N_CONNECT_ind rx_c_ind;
1742 var RSL_Message rx_rsl;
1743 var DchanTuple dt;
1744
Harald Welte89d42e82017-12-17 16:42:41 +01001745 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001746
1747 dt := f_est_dchan('23'O, 23, '00000000'O);
1748 /* send assignment without AoIP IEs */
1749 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1750 alt {
1751 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1752 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1753 setverdict(pass);
1754 } else {
1755 setverdict(fail, fail_text);
1756 }
1757 }
1758 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1759 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1760 setverdict(pass);
1761 } else {
1762 setverdict(fail, fail_text);
1763 }
1764 }
1765 [] BSSAP.receive { repeat; }
1766 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001767 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001768}
1769testcase TC_assignment_csd() runs on test_CT {
1770 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001771 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001772 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1773 //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 +01001774 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1775 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001776 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001777}
1778
1779testcase TC_assignment_ctm() runs on test_CT {
1780 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001781 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001782 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1783 //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 +01001784 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1785 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001786 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001787}
1788
Harald Welte4003d112017-12-09 22:35:39 +01001789type record DchanTuple {
1790 integer sccp_conn_id,
1791 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001792}
1793
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001794type record of DchanTuple DchanTuples;
1795
Harald Welted6939652017-12-13 21:02:46 +01001796/* Send CHAN RQD and wait for allocation; acknowledge it */
1797private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1798runs on test_CT return RslChannelNr {
1799 var RSL_Message rx_rsl;
1800 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1801 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1802 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1803 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001804 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001805 return chan_nr;
1806}
1807
Harald Welte4003d112017-12-09 22:35:39 +01001808/* helper function to establish a dedicated channel via BTS and MSC */
1809function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1810runs on test_CT return DchanTuple {
1811 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001812 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001813
Harald Welte4003d112017-12-09 22:35:39 +01001814 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001815 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001816
1817 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1818
1819 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1820 dt.sccp_conn_id := rx_c_ind.connectionId;
1821 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1822
1823 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001824}
1825
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001826/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1827function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1828runs on test_CT return DchanTuple {
1829 var BSSAP_N_CONNECT_ind rx_c_ind;
1830 var DchanTuple dt;
1831
1832 /* Send CHAN RQD */
1833 var RSL_Message rx_rsl;
1834 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1835
1836 /* The dyn TS first deactivates PDCH */
1837 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1838 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1839 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1840
1841 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1842 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1843
1844 /* Now activates the signalling channel */
1845 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1846 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1847
1848 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1849
1850 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1851 dt.sccp_conn_id := rx_c_ind.connectionId;
1852 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1853
1854 return dt;
1855}
1856
Harald Welte641fcbe2018-06-14 10:58:35 +02001857/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1858private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1859 var RSL_Message rx_rsl;
1860 /* expect BSC to disable the channel */
1861 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1862 /* respond with CHAN REL ACK */
1863 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1864
1865 /* expect Clear Complete from BSC */
1866 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1867
1868 /* MSC disconnects as instructed. */
1869 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1870}
1871
Harald Welte4003d112017-12-09 22:35:39 +01001872/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1873testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001874 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001875 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001876
Harald Welte89d42e82017-12-17 16:42:41 +01001877 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001878
Harald Welte4003d112017-12-09 22:35:39 +01001879 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1880
1881 /* simulate RLL REL IND */
1882 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1883
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001884 /* expect Clear Request on MSC side */
1885 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1886
1887 /* Instruct BSC to clear channel */
1888 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1889 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1890
Harald Welte4003d112017-12-09 22:35:39 +01001891 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001892 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001893
1894 /* wait for SCCP emulation to do its job */
1895 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001896
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001897 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001898}
1899
1900/* Test behavior of channel release after CONN FAIL IND from BTS */
1901testcase TC_chan_rel_conn_fail() runs on test_CT {
1902 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001903 var DchanTuple dt;
1904
Harald Welte89d42e82017-12-17 16:42:41 +01001905 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001906
1907 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1908
1909 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001910 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001911 /* TODO: different cause values? */
1912
Harald Welte4003d112017-12-09 22:35:39 +01001913 /* expect Clear Request from BSC */
1914 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1915
1916 /* Instruct BSC to clear channel */
1917 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1918 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1919
Harald Welte6ff76ea2018-01-28 13:08:01 +01001920 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001921 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001922
1923 /* wait for SCCP emulation to do its job */
1924 f_sleep(1.0);
1925
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001926 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001927}
1928
Harald Welte99f3ca02018-06-14 13:40:29 +02001929/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1930/* See also https://www.osmocom.org/issues/3182 */
1931testcase TC_early_conn_fail() runs on test_CT {
1932 var RSL_Message rx_rsl;
1933 var DchanTuple dt;
1934
1935 f_init(1);
1936
1937 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001938 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001939
1940 /* BTS->BSC: simulate CONN FAIL IND */
1941 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1942
1943 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1944 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1945
1946 /* BTS<-BSC: respond with CHAN REL ACK */
1947 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1948
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001949 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001950}
1951
1952/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1953/* See also https://www.osmocom.org/issues/3182 */
1954testcase TC_late_conn_fail() runs on test_CT {
1955 var RSL_Message rx_rsl;
1956 var DchanTuple dt;
1957
1958 f_init(1);
1959
1960 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1961
1962 /* BSC<-MSC: Instruct BSC to clear connection */
1963 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1964
1965 /* BTS->BSC: expect BSC to deactivate SACCH */
1966 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1967
1968 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1969 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1970
1971 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1972 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1973 /* BTS->BSC: respond with CHAN REL ACK */
1974 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1975
1976 /* BSC->MSC: expect Clear Complete from BSC */
1977 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1978
1979 /* BSC<-MSC: MSC disconnects as requested. */
1980 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1981
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001982 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001983}
1984
Oliver Smithaf03bef2021-08-24 15:34:51 +02001985private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1986 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1987 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1988
1989 f_statsd_reset();
1990
1991 /* Establish SDCCH */
1992 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1993 f_establish_fully(ass_cmd, exp_fail);
1994
1995 /* Expect stats to be 0 */
1996 var StatsDExpects expect := {
1997 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1998 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1999 };
2000 f_statsd_expect(expect);
2001
2002 /* Simulate CONN FAIL IND on SDCCH */
2003 RSL.send(ts_ASP_RSL_UD(
2004 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2005 IPAC_PROTO_RSL_TRX0));
2006
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002007 f_sleep(1.0);
2008
Oliver Smithaf03bef2021-08-24 15:34:51 +02002009 /* Expect stats to be 1 */
2010 expect := {
2011 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2012 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2013 };
2014 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002015 BSSAP.receive(tr_BSSMAP_ClearRequest);
2016 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002017}
2018testcase TC_stats_conn_fail() runs on test_CT {
2019 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2020 var MSC_ConnHdlr vc_conn;
2021
2022 f_init(1, true);
2023 f_sleep(1.0);
2024
2025 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2026 vc_conn.done;
2027
2028 f_shutdown_helper();
2029}
2030
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01002031function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002032 boolean expect_deact_sacch := true,
2033 boolean expect_rr_chan_rel := true,
2034 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002035 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002036 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002037 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002038 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002039
2040 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002041 var boolean got_deact_sacch := false;
2042 var boolean got_rr_chan_rel := false;
2043 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002044 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002045 var RSL_IE_Body l3_ie;
2046 var PDU_ML3_NW_MS l3;
2047 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002048 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2049 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002050 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002051 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002052 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002053 repeat;
2054 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002055 [not istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE_CellSelectInd))) -> value ud {
Harald Welte99787102019-02-04 10:41:36 +01002056 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002057
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002058 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2059 setverdict(fail, "cannot find L3");
2060 mtc.stop;
2061 }
2062 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2063
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002064 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002065 var CellSelIndValue cells := dec_CellSelIndValue(
2066 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2067
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002068 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2069 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002070 setverdict(pass);
2071 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002072 log("EXPECTED CELLS: ", expect_cells);
2073 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002074 }
2075 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002076
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002077 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2078 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2079 if (match(got_cause, expect_rr_cause)) {
2080 setverdict(pass);
2081 } else {
2082 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2083 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002084 }
Harald Welte99787102019-02-04 10:41:36 +01002085 repeat;
2086 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002087 [istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) -> value ud {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002088 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002089
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002090 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2091 setverdict(fail, "cannot find L3");
2092 mtc.stop;
2093 }
2094 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002095
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002096 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2097 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2098 if (match(got_cause, expect_rr_cause)) {
2099 setverdict(pass);
2100 } else {
2101 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2102 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002103 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01002104 repeat;
2105 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002106 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002107 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002108 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002109 if (handle_rll_rel) {
2110 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
2111 }
Harald Welte91d54a52018-01-28 15:35:07 +01002112 repeat;
2113 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002114 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002115 /* respond with CHAN REL ACK */
2116 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
2117 }
2118 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002119 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002120 repeat;
2121 }
2122 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002123
2124 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2125 " got_rll_rel_req=", got_rll_rel_req);
2126
2127 if (expect_deact_sacch != got_deact_sacch) {
2128 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2129 }
2130 if (expect_rr_chan_rel != got_rr_chan_rel) {
2131 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2132 }
2133 if (expect_rll_rel_req != got_rll_rel_req) {
2134 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2135 }
Harald Welte91d54a52018-01-28 15:35:07 +01002136}
2137
Harald Welte4003d112017-12-09 22:35:39 +01002138/* Test behavior of channel release after hard Clear Command from MSC */
2139testcase TC_chan_rel_hard_clear() runs on test_CT {
2140 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002141 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002142
Harald Welte89d42e82017-12-17 16:42:41 +01002143 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002144
2145 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2146
2147 /* Instruct BSC to clear channel */
2148 var BssmapCause cause := 0;
2149 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2150
2151 /* expect Clear Complete from BSC on A */
2152 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2153 /* release the SCCP connection */
2154 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2155 }
2156
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002157 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002158 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002159}
2160
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002161function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2162 var BSSAP_N_DATA_ind rx_di;
2163 var DchanTuple dt;
2164
2165 f_init(1);
2166
2167 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2168 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2169 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2170 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2171
2172 /* Instruct BSC to clear channel */
2173 var BssmapCause cause := 0;
2174 if (tx_csfb_ind) {
2175 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2176 } else {
2177 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2178 }
2179
2180 /* expect Clear Complete from BSC on A */
2181 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2182 /* release the SCCP connection */
2183 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2184 }
2185
2186 /* 1 neighbor is added by default in osmo-bts.cfg and
2187 SystemInformationConfig_default, use that: */
2188 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2189
2190 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2191 f_shutdown_helper();
2192}
2193
2194/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2195 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2196 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2197 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2198 Indicator or not shouldn't matter at all. */
2199testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2200 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2201}
2202
2203/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2204 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2205 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2206 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2207testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2208 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2209}
2210
2211/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2212 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2213 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2214 CSFB Indicator should not be used anymore, and hence, there should be no
2215 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2216 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002217testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2218 var BSSAP_N_DATA_ind rx_di;
2219 var DchanTuple dt;
2220
2221 f_init(1);
2222
2223 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2224
2225 /* Instruct BSC to clear channel */
2226 var BssmapCause cause := 0;
2227 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2228
2229 /* expect Clear Complete from BSC on A */
2230 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2231 /* release the SCCP connection */
2232 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2233 }
2234
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002235 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002236 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002237}
2238
Harald Welted8c36cd2017-12-09 23:05:31 +01002239/* Test behavior of channel release after hard RLSD from MSC */
2240testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002241 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002242
Harald Welte89d42e82017-12-17 16:42:41 +01002243 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002244
2245 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2246
2247 /* release the SCCP connection */
2248 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2249
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002250 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002251 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002252}
2253
Harald Welte550daf92018-06-11 19:22:13 +02002254/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2255testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2256 var DchanTuple dt;
2257
2258 f_init(1);
2259
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
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002265 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002266 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002267}
2268
Harald Welte85804d42017-12-10 14:11:58 +01002269/* Test behavior of channel release after BSSMAP RESET from MSC */
2270testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002271 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002272
Harald Welte89d42e82017-12-17 16:42:41 +01002273 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002274
2275 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2276
2277 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2278 IPA_RSL[0].clear;
2279
2280 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002281 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)));
Harald Welte85804d42017-12-10 14:11:58 +01002282 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002283 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
Harald Welte85804d42017-12-10 14:11:58 +01002284 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2285 }
2286
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002287 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002288 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002289}
2290
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002291/* Verify T(iar) triggers and releases the channel */
2292testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2293 var DchanTuple dt;
2294
2295 /* Set T(iar) in BSC low enough that it will trigger before other side
2296 has time to keep alive with a T(ias). Keep recommended ratio of
2297 T(iar) >= T(ias)*2 */
2298 g_bsc_sccp_timer_ias := 2;
2299 g_bsc_sccp_timer_iar := 5;
2300
2301 f_init(1);
2302
2303 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2304 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002305 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002306}
2307
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002308private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2309 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002310runs on test_CT
2311{
2312 var DchanTuple dt;
2313
2314 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2315 var BssmapCause cause := 0;
2316 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2317 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2318 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2319 }
2320
2321 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_rr_cause := expect_rr_cause);
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002322}
2323
2324/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2325testcase TC_chan_rel_rr_cause() runs on test_CT {
2326 f_init(1);
2327
2328 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2329 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2330 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2331 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2332 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2333 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002334
2335 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002336}
2337
Harald Welte5cd20ed2017-12-13 21:03:20 +01002338/* Test behavior if RSL EST IND for non-active channel */
2339testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2340 timer T := 2.0;
2341
Harald Welte89d42e82017-12-17 16:42:41 +01002342 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002343
2344 var octetstring l3 := '00010203040506'O;
2345 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2346 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2347
2348 T.start;
2349 alt {
2350 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2351 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2352 }
2353 [] BSSAP.receive {}
2354 [] IPA_RSL[0].receive {}
2355 [] T.timeout {}
2356 }
2357
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002358 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002359}
2360
2361/* Test behavior if RSL EST IND for invalid SAPI */
2362testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2363 var RslChannelNr chan_nr;
2364
Harald Welte89d42e82017-12-17 16:42:41 +01002365 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002366
2367 chan_nr := f_chreq_act_ack()
2368
2369 var octetstring l3 := '00010203040506'O;
2370 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2371
2372 timer T := 2.0;
2373 T.start;
2374 alt {
2375 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2376 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2377 }
2378 [] BSSAP.receive { repeat; }
2379 [] IPA_RSL[0].receive { repeat; }
2380 [] T.timeout {}
2381 }
2382
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002383 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002384}
2385
2386/* Test behavior if RSL EST IND for invalid SAPI */
2387testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2388 timer T := 2.0;
2389
Harald Welte89d42e82017-12-17 16:42:41 +01002390 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002391
2392 var RslChannelNr chan_nr := f_chreq_act_ack();
2393
2394 var octetstring l3 := '00010203040506'O;
2395 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2396
2397 T.start;
2398 alt {
2399 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2400 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2401 }
2402 [] BSSAP.receive { repeat; }
2403 [] IPA_RSL[0].receive { repeat; }
2404 [] T.timeout {}
2405 }
2406
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002407 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002408}
2409
2410/* Test behavior if RSL EST IND for invalid SACCH */
2411testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2412 timer T := 2.0;
2413
Harald Welte89d42e82017-12-17 16:42:41 +01002414 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002415
2416 var RslChannelNr chan_nr := f_chreq_act_ack();
2417
2418 var octetstring l3 := '00010203040506'O;
2419 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2420
2421 T.start;
2422 alt {
2423 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2424 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2425 }
2426 [] BSSAP.receive { repeat; }
2427 [] IPA_RSL[0].receive { repeat; }
2428 [] T.timeout {}
2429 }
2430
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002431 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002432}
2433
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002434/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2435private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2436 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2437 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2438
2439 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2440 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2441
2442 f_establish_fully(ass_cmd, exp_compl);
2443
2444 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2445 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2446 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2447 BSSAP.receive(PDU_BSSAP:{
2448 discriminator := '1'B,
2449 spare := '0000000'B,
2450 dlci := 'C3'O,
2451 lengthIndicator := ?,
2452 pdu := { dtap := '0904'O }
2453 });
2454
2455 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2456 for (var integer i := 0; i < 32; i := i + 1) {
2457 var octetstring l3 := '09'O & f_rnd_octstring(14);
2458 var template (value) RslLinkId link_id;
2459 var template (value) OCT1 dlci;
2460
2461 if (i mod 2 == 0) {
2462 /* SAPI0 on FACCH or SDCCH */
2463 link_id := ts_RslLinkID_DCCH(0);
2464 dlci := '80'O;
2465 } else {
2466 /* SAPI3 on SACCH */
2467 link_id := ts_RslLinkID_SACCH(3);
2468 dlci := 'C3'O;
2469 }
2470
2471 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002472 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002473 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002474 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002475 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002476 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002477}
2478testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2479 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2480 var MSC_ConnHdlr vc_conn;
2481
2482 f_init(1, true);
2483 f_sleep(1.0);
2484
2485 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2486 vc_conn.done;
2487
2488 f_shutdown_helper();
2489}
2490
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002491private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002492 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002493 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002494 float T_val := 2.0)
2495runs on test_CT {
2496 var BSSAP_N_DATA_ind rx_di;
2497 timer T;
2498
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002499 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2500 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002501
2502 T.start(T_val);
2503 alt {
2504 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2505 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2506 if (not match(rx_cause, tr_cause)) {
2507 setverdict(fail, "Rx unexpected Cause IE: ",
2508 rx_cause, " vs expected ", tr_cause);
2509 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002510
2511 /* Who ever on the earth decided to define this field as two separate bits?!? */
2512 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2513 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2514 if (not match(rx_cc, cc)) {
2515 setverdict(fail, "Rx unexpected Control Channel type: ",
2516 rx_cc, " vs expected ", cc);
2517 }
2518
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002519 setverdict(pass);
2520 }
2521 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2522 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2523 }
2524 [] T.timeout {
2525 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2526 }
2527 }
2528}
2529
2530/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2531testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2532 var octetstring rnd_data := f_rnd_octstring(16);
2533 var RSL_Message rx_rsl;
2534 var DchanTuple dt;
2535
2536 f_init(1);
2537
2538 /* MS establishes a SAPI=0 link on DCCH */
2539 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2540
2541 /* MSC sends some data on (not yet established) SAPI=3 link */
2542 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2543 /* BSC attempts to establish a SAPI=3 link on DCCH */
2544 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2545
2546 /* MS sends unexpected RELease INDication on SAPI=3 */
2547 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2548 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2549 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2550
2551 /* Clean up the connection */
2552 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2553 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2554
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002555 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002556}
2557
2558/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2559testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2560 var octetstring rnd_data := f_rnd_octstring(16);
2561 var RSL_Message rx_rsl;
2562 var DchanTuple dt;
2563
2564 f_init(1);
2565
2566 /* MS establishes a SAPI=0 link on DCCH */
2567 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2568
2569 /* MSC sends some data on (not yet established) SAPI=3 link */
2570 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2571 /* BSC attempts to establish a SAPI=3 link on DCCH */
2572 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2573
2574 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2575 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2576 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2577 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2578
2579 /* Clean up the connection */
2580 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2581 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2582
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002583 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002584}
2585
2586/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2587testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2588 var octetstring rnd_data := f_rnd_octstring(16);
2589 var RSL_Message rx_rsl;
2590 var DchanTuple dt;
2591
2592 f_init(1);
2593
2594 /* MS establishes a SAPI=0 link on DCCH */
2595 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2596
2597 /* MSC sends some data on (not yet established) SAPI=3 link */
2598 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2599 /* BSC attempts to establish a SAPI=3 link on DCCH */
2600 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2601
2602 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2603 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2604
2605 /* Clean up the connection */
2606 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2607 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2608
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002609 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002610}
2611
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002612/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2613testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
2614 var octetstring rnd_data := f_rnd_octstring(16);
2615 var RSL_Message rx_rsl;
2616 var DchanTuple dt;
2617
2618 f_init(1);
2619
2620 /* MS establishes a SAPI=0 link on DCCH */
2621 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2622
2623 /* MSC sends some data on (not yet established) SAPI=3 link */
2624 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2625 /* BSC attempts to establish a SAPI=3 link on DCCH */
2626 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2627
2628 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
2629 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002630 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002631
2632 /* Clean up the connection */
2633 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2634 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2635
2636 f_shutdown_helper();
2637}
2638
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002639testcase TC_si_default() runs on test_CT {
2640 f_init(0);
2641 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002642 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002643}
Harald Welte4003d112017-12-09 22:35:39 +01002644
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002645/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2646 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2647private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2648{
2649 select (earfcn_index) {
2650 case (0) {
2651 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2652 return 111;
2653 }
2654 case (1) {
2655 return 1;
2656 }
2657 case (2) {
2658 return 0;
2659 }
2660 case (3) {
2661 return 65535;
2662 }
2663 case else {
2664 return 23 * (earfcn_index - 3);
2665 }
2666 }
2667}
2668
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002669function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2670 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002671
2672 f_init(0);
2673
2674 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2675 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002676 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2677 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002678 }
2679
2680 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2681
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002682 if (not istemplatekind(expect_cells, "omit")) {
2683 /* Also check that RR Channel Release contains these EARFCNs.
2684 * (copied code from TC_chan_rel_hard_clear_csfb) */
2685 var BSSAP_N_DATA_ind rx_di;
2686 var DchanTuple dt;
2687
2688 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002689 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2690 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2691 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002692
2693 /* Instruct BSC to clear channel */
2694 var BssmapCause cause := 0;
2695 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2696
2697 /* expect Clear Complete from BSC on A */
2698 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2699 /* release the SCCP connection */
2700 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2701 }
2702
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002703 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002704 }
2705
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002706 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002707 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 +02002708 }
2709}
2710
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002711private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2712{
2713 var template SI2quaterRestOctetsList si2quater := {};
2714 var integer si2quater_count := (count + 2) / 3;
2715
2716 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002717 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002718 var integer index := i / 3;
2719 var integer earfcn_index := i mod 3;
2720 if (index >= lengthof(si2quater)) {
2721 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2722 }
2723 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);
2724 }
2725
2726 return si2quater;
2727}
2728
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002729private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2730{
2731 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2732
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002733 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002734 for (var integer i := 0; i < count; i := i + 1) {
2735 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002736 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002737 }
2738
2739 return tr_CellSelIndValue_EUTRAN(cells);
2740}
2741
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002742private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2743{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002744 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002745 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002746 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2747 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002748}
2749
2750testcase TC_si2quater_2_earfcns() runs on test_CT {
2751 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002752 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002753}
2754
2755testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002756 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002757 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002758}
2759
2760testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002761 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002762 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002763}
2764
2765testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002766 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002767 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002768}
2769
2770testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002771 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002772 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002773}
2774
2775testcase TC_si2quater_12_earfcns() runs on test_CT {
2776 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002777 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002778}
2779
2780testcase TC_si2quater_23_earfcns() runs on test_CT {
2781 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002782 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002783}
2784
2785testcase TC_si2quater_32_earfcns() runs on test_CT {
2786 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002787 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002788}
2789
2790testcase TC_si2quater_33_earfcns() runs on test_CT {
2791 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002792 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002793}
2794
2795testcase TC_si2quater_42_earfcns() runs on test_CT {
2796 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002797 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002798}
2799
2800testcase TC_si2quater_48_earfcns() runs on test_CT {
2801 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002802 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002803}
2804
2805/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2806 * 48 EARFCNs. */
2807testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002808 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002809 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2810 f_init(0);
2811
2812 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002813 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2814 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002815 }
2816
2817 /* The 49th EARFCN no longer fits, expect VTY error */
2818 f_vty_enter_cfg_bts(BSCVTY, 0);
2819 var charstring vty_error;
2820 vty_error := f_vty_transceive_ret(BSCVTY,
2821 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2822 f_vty_transceive(BSCVTY, "end");
2823
2824 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2825 log("Got expected VTY error: ", vty_error);
2826 setverdict(pass);
2827 } else {
2828 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2829 }
2830
2831 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2832
2833 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002834 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 +02002835 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002836 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002837}
2838
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002839private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2840{
2841 var uint8_t count := 0;
2842 for (var integer i := 5; i < 16; i := i + 1) {
2843 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2844 count := count + 1;
2845 }
2846 }
2847 return count;
2848}
2849
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002850private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2851{
2852 var ASP_RSL_Unitdata rx_rsl_ud;
2853 var SystemInformationType1 last_si1;
2854
2855 timer T := 30.0;
2856 T.start;
2857 alt {
2858 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2859 tr_RSL_BCCH_INFO,
2860 tr_RSL_NO_SACCH_FILL,
2861 tr_RSL_SACCH_FILL))
2862 ) -> value rx_rsl_ud {
2863 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2864 if (g_system_information[rsl_idx].si1 == omit) {
2865 repeat;
2866 }
2867 last_si1 := g_system_information[rsl_idx].si1;
2868 g_system_information[rsl_idx].si1 := omit;
2869 T.stop;
2870 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002871 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002872 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2873 }
2874 return last_si1;
2875}
2876
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002877/* verify ACC rotate feature */
2878testcase TC_si_acc_rotate() runs on test_CT {
2879 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002880 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002881 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002882 var uint8_t count;
2883 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2884
2885 f_init(0, guard_timeout := 60.0);
2886
2887 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2888 "access-control-class-rotate 3",
2889 "access-control-class-rotate-quantum 1"});
2890
2891 /* Init and get first sysinfo */
2892 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2893
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002894 for (var integer i:= 0; i < 20; i := i + 1) {
2895 last_si1 := f_recv_next_si1(0);
2896 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002897 count := f_acc09_count_allowed(acc);
2898 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2899
2900 if (count != 3) {
2901 log("RSL: EXPECTED SI ACC len=3");
2902 setverdict(fail, "received SI does not match expectations");
2903 break;
2904 }
2905
2906 for (var integer j := 0; j < 10; j := j + 1) {
2907 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2908 times_allowed[j] := times_allowed[j] + 1;
2909 }
2910 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002911 }
2912
2913 for (var integer j := 0; j < 10; j := j + 1) {
2914 log("ACC", j, " allowed ", times_allowed[j], " times" );
2915 if (j != 5 and times_allowed[j] < 3) {
2916 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2917 } else if (j == 5 and times_allowed[j] > 0) {
2918 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2919 }
2920 }
2921
2922 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2923 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002924 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002925}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002926
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002927/* verify ACC startup ramp+rotate feature */
2928testcase TC_si_acc_ramp_rotate() runs on test_CT {
2929 var template SystemInformationConfig sic := SystemInformationConfig_default;
2930 var SystemInformationType1 last_si1;
2931 var AccessControlClass acc;
2932 var ASP_RSL_Unitdata rx_rsl_ud;
2933 var uint8_t count;
2934 var uint8_t prev_count;
2935 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2936
2937 f_init(0, guard_timeout := 80.0);
2938
2939 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2940 "access-control-class-rotate 0",
2941 "access-control-class-rotate-quantum 1",
2942 "access-control-class-ramping",
2943 "access-control-class-ramping-step-interval 5",
2944 "access-control-class-ramping-step-size 5"});
2945
2946 /* Init and get first sysinfo */
2947 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2948 last_si1 := g_system_information[0].si1;
2949 acc := last_si1.rach_control.acc;
2950 count := f_acc09_count_allowed(acc);
2951 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2952 while (count > 0) {
2953 last_si1 := f_recv_next_si1(0);
2954 acc := last_si1.rach_control.acc;
2955 count := f_acc09_count_allowed(acc);
2956 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2957 }
2958
2959 /* Increase adm subset size, we should see ramping start up */
2960 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2961 prev_count := 0;
2962 while (true) {
2963 last_si1 := f_recv_next_si1(0);
2964 acc := last_si1.rach_control.acc;
2965 count := f_acc09_count_allowed(acc);
2966 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2967
2968 if (prev_count > count) {
2969 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2970 break;
2971 }
2972
2973 if (count == 9) {
2974 break; /* Maximum reached (10 - 1 perm barred), done here */
2975 }
2976
2977 prev_count := count;
2978 }
2979
2980 setverdict(pass);
2981
2982 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2983 "rach access-control-class 4 allowed",
2984 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002985 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002986}
2987
Harald Welte4003d112017-12-09 22:35:39 +01002988testcase TC_ctrl_msc_connection_status() runs on test_CT {
2989 var charstring ctrl_resp;
2990
Harald Welte89d42e82017-12-17 16:42:41 +01002991 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002992
2993 /* See https://osmocom.org/issues/2729 */
2994 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002995 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002996}
2997
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002998testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2999 var charstring ctrl_resp;
3000
3001 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003002
3003 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003004 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003005}
3006
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003007/* Verify correct stats on the number of configured and connected MSCs */
3008private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3009 g_pars := f_gen_test_hdlr_pars();
3010 var StatsDExpects expect := {
3011 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3012 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3013 };
3014 f_statsd_expect(expect);
3015}
3016
3017private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3018{
3019 var MSC_ConnHdlr vc_conn;
3020
3021 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3022 f_sleep(1.0);
3023 vc_conn := f_start_handler(tc_fn);
3024 vc_conn.done;
3025
3026 /* Also verify stat exposed on CTRL interface */
3027 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3028 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3029
3030 f_shutdown_helper();
3031}
3032
3033/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3034private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3035 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3036}
3037testcase TC_stat_num_msc_connected_1() runs on test_CT {
3038 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3039}
3040
3041/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3042private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3043 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3044}
3045testcase TC_stat_num_msc_connected_2() runs on test_CT {
3046 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3047}
3048
3049/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3050private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3051 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3052}
3053testcase TC_stat_num_msc_connected_3() runs on test_CT {
3054 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3055}
3056
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003057/* Verify correct stats on the number of configured and connected MSCs */
3058private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
3059 g_pars := f_gen_test_hdlr_pars();
3060 var StatsDExpects expect := {
3061 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3062 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3063 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
3064 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3065 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
3066 };
3067 f_statsd_expect(expect);
3068}
3069
3070private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
3071 var MSC_ConnHdlr vc_conn;
3072
3073 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3074 f_sleep(1.0);
3075 vc_conn := f_start_handler(tc_fn);
3076 vc_conn.done;
3077
3078 /* Also verify stat exposed on CTRL interface */
3079 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3080 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
3081 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
3082 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
3083
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003084 /* Verify rf_states exposed on CTRL interface */
3085 var charstring expect_net_rf_states := "";
3086 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
3087 var charstring expect_bts_rf_states := int2str(i) & ",0,";
3088 if (i < NUM_BTS) {
3089 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3090 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3091 } else {
3092 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3093 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3094 }
3095 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3096 expect_bts_rf_states := expect_bts_rf_states & "on,";
3097 if (i < nr_bts) {
3098 /* For BTS where RSL is connected, the RSL state will be "up" */
3099 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3100 } else {
3101 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3102 }
3103
3104 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3105 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3106 }
3107 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3108
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003109 f_shutdown_helper();
3110}
3111
3112/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3113private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3114 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3115}
3116testcase TC_stat_num_bts_connected_1() runs on test_CT {
3117 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3118}
3119
3120/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3121private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3122 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3123}
3124testcase TC_stat_num_bts_connected_2() runs on test_CT {
3125 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3126}
3127
3128/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3129private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3130 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3131}
3132testcase TC_stat_num_bts_connected_3() runs on test_CT {
3133 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3134}
3135
Harald Welte4003d112017-12-09 22:35:39 +01003136testcase TC_ctrl() runs on test_CT {
3137 var charstring ctrl_resp;
3138
Harald Welte89d42e82017-12-17 16:42:41 +01003139 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003140
3141 /* all below values must match the osmo-bsc.cfg config file used */
3142
Harald Welte6a129692018-03-17 17:30:14 +01003143 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3144 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003145 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003146
3147 var integer bts_nr := 0;
3148 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3149 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3150 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3151 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3152 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3153 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3154 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3155
3156 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3157 f_sleep(2.0);
3158 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3159 setverdict(fail, "oml-uptime not incrementing as expected");
3160 }
3161 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3162
3163 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3164
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003165 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003166}
3167
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003168/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3169 "location-state" over the SCCPlite IPA conn */
3170testcase TC_ctrl_location() runs on test_CT {
3171 var MSC_ConnHdlr vc_conn;
3172 var integer bts_nr := 0;
3173
3174 f_init(1, true);
3175 f_sleep(1.0);
3176
3177 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3178 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3179 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3180
3181 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3182 f_sleep(2.0);
3183
3184 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3185 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3186 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3187
3188 /* should match the one from config */
3189 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3190
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003191 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003192}
3193
Harald Welte6f521d82017-12-11 19:52:02 +01003194
3195/***********************************************************************
3196 * Paging Testing
3197 ***********************************************************************/
3198
3199type record Cell_Identity {
3200 GsmMcc mcc,
3201 GsmMnc mnc,
3202 GsmLac lac,
3203 GsmCellId ci
3204};
Harald Welte24135bd2018-03-17 19:27:53 +01003205private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003206private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003207
Harald Welte5d1a2202017-12-13 19:51:29 +01003208type set of integer BtsIdList;
3209
3210private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3211 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3212 if (bts_id == bts_ids[j]) {
3213 return true;
3214 }
3215 }
3216 return false;
3217}
Harald Welte6f521d82017-12-11 19:52:02 +01003218
3219/* core paging test helper function; used by most paging test cases */
3220private function f_pageing_helper(hexstring imsi,
3221 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003222 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003223 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003224 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003225{
3226 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003227 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003228 var RSL_Message rx_rsl;
3229 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003230 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003231
3232 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003233
3234 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003235 for (i := 0; i < NUM_BTS; i := i + 1) {
3236 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003237 }
Harald Welte6f521d82017-12-11 19:52:02 +01003238
3239 if (isvalue(rsl_chneed)) {
3240 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3241 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3242 } else {
3243 bssmap_chneed := omit;
3244 }
3245
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003246 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3247 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003248
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003249 if (not istemplatekind(tmsi, "omit")) {
3250 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003251 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003252 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003253 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003254
Harald Welte5d1a2202017-12-13 19:51:29 +01003255 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003256 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003257 /* check channel type, paging group */
3258 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3259 setverdict(fail, "Paging for wrong paging group");
3260 }
3261 if (ispresent(rsl_chneed) and
3262 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3263 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3264 }
Harald Welte6f521d82017-12-11 19:52:02 +01003265 }
Harald Welte2fccd982018-01-31 15:48:19 +01003266 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003267 /* do a quick check on all not-included BTSs if they received paging */
3268 for (i := 0; i < NUM_BTS; i := i + 1) {
3269 timer T := 0.1;
3270 if (f_bts_in_list(i, bts_ids)) {
3271 continue;
3272 }
3273 T.start;
3274 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003275 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003276 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3277 }
3278 [] IPA_RSL[i].receive { repeat; }
3279 [] T.timeout { }
3280 }
Harald Welte6f521d82017-12-11 19:52:02 +01003281 }
3282
3283 setverdict(pass);
3284}
3285
Harald Welte5d1a2202017-12-13 19:51:29 +01003286const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003287const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003288const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3289const BtsIdList c_BtsId_LAC2 := { 2 };
3290
Harald Welte6f521d82017-12-11 19:52:02 +01003291/* PAGING by IMSI + TMSI */
3292testcase TC_paging_imsi_nochan() runs on test_CT {
3293 var BSSMAP_FIELD_CellIdentificationList cid_list;
3294 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003295 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003296 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003297}
3298
3299/* PAGING by IMSI + TMSI */
3300testcase TC_paging_tmsi_nochan() runs on test_CT {
3301 var BSSMAP_FIELD_CellIdentificationList cid_list;
3302 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003303 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003304 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003305}
3306
3307/* Paging with different "channel needed' values */
3308testcase TC_paging_tmsi_any() runs on test_CT {
3309 var BSSMAP_FIELD_CellIdentificationList cid_list;
3310 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003311 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003312 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003313}
3314testcase TC_paging_tmsi_sdcch() runs on test_CT {
3315 var BSSMAP_FIELD_CellIdentificationList cid_list;
3316 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003317 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003318 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003319}
3320testcase TC_paging_tmsi_tch_f() runs on test_CT {
3321 var BSSMAP_FIELD_CellIdentificationList cid_list;
3322 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003323 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003324 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003325}
3326testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3327 var BSSMAP_FIELD_CellIdentificationList cid_list;
3328 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003329 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003330 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003331}
3332
3333/* Paging by CGI */
3334testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3335 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3336 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003337 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003338 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003339}
3340
3341/* Paging by LAC+CI */
3342testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3343 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3344 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003345 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003346 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003347}
3348
3349/* Paging by CI */
3350testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3351 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3352 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003353 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003354 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003355}
3356
3357/* Paging by LAI */
3358testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3359 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3360 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003361 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003362 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003363}
3364
3365/* Paging by LAC */
3366testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3367 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3368 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003369 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003370 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003371}
3372
3373/* Paging by "all in BSS" */
3374testcase TC_paging_imsi_nochan_all() runs on test_CT {
3375 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3376 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003377 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003378 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003379}
3380
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003381/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003382testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3383 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3384 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 +01003385 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003386 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003387}
Harald Welte6f521d82017-12-11 19:52:02 +01003388
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003389/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003390testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3391 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3392 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003393 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003394 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003395}
3396
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003397/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003398testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3399 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3400 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003401 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003402 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003403}
3404
Harald Welte6f521d82017-12-11 19:52:02 +01003405/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003406testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3407 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3408 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3409 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003410 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003411}
3412
3413/* Paging on empty list: Verify none of them page */
3414testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3415 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3416 cid_list := { cIl_LAC := { } };
3417 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003418 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003419}
3420
Stefan Sperling049a86e2018-03-20 15:51:00 +01003421/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3422testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3423 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3424 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3425 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3426 f_shutdown_helper();
3427}
3428
Harald Welte6f521d82017-12-11 19:52:02 +01003429/* Verify paging retransmission interval + count */
3430/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003431/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003432
Harald Weltee65d40e2017-12-13 00:09:06 +01003433/* Verify PCH load */
3434testcase TC_paging_imsi_load() runs on test_CT {
3435 var BSSMAP_FIELD_CellIdentificationList cid_list;
3436 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003437 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003438 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003439 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003440
3441 /* tell BSC there is no paging space anymore */
3442 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003443 f_sleep(0.2);
3444 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003445
3446 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3447 * there would be 8 retransmissions during 4 seconds */
3448 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003449 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003450 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003451 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003452 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003453 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003454 }
Harald Welte2caa1062018-03-17 18:19:05 +01003455 [] T_retrans.timeout {
3456 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3457 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3458 T_retrans.start;
3459 repeat;
3460 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003461 [] T.timeout {
3462 setverdict(pass);
3463 }
3464 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003465
3466 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003467}
3468
Harald Welte235ebf12017-12-15 14:18:16 +01003469/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003470testcase TC_paging_counter() runs on test_CT {
3471 var BSSMAP_FIELD_CellIdentificationList cid_list;
3472 timer T := 4.0;
3473 var integer i;
3474 var integer paging_attempted_bsc;
3475 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003476 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003477 var integer paging_expired_bts[NUM_BTS];
3478 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3479
3480 f_init();
3481
3482 /* read counters before paging */
3483 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003484 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3485 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3486 }
Harald Welte1ff69992017-12-14 12:31:17 +01003487 for (i := 0; i < NUM_BTS; i := i+1) {
3488 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3489 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3490 }
3491
3492 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3493
3494 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3495 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3496 for (i := 0; i < NUM_BTS; i := i+1) {
3497 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3498 paging_attempted_bts[i]+1);
3499 }
3500
3501 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3502 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003503 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3504 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3505 }
Harald Welte1ff69992017-12-14 12:31:17 +01003506 for (i := 0; i < NUM_BTS; i := i+1) {
3507 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3508 paging_expired_bts[i]+1);
3509 }
Harald Welte1ff69992017-12-14 12:31:17 +01003510
Philipp Maier282ca4b2018-02-27 17:17:00 +01003511 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003512}
3513
3514
Harald Welte10985002017-12-12 09:29:15 +01003515/* Verify paging stops after A-RESET */
3516testcase TC_paging_imsi_a_reset() runs on test_CT {
3517 var BSSMAP_FIELD_CellIdentificationList cid_list;
3518 timer T := 3.0;
3519 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003520 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003521
3522 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003523 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)));
Harald Welte10985002017-12-12 09:29:15 +01003524 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003525 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
Harald Welte10985002017-12-12 09:29:15 +01003526 [] BSSAP.receive { repeat; }
3527 }
3528
Daniel Willmanncbef3982018-07-30 09:22:40 +02003529 /* Wait to avoid a possible race condition if a paging message is
3530 * received right before the reset ACK. */
3531 f_sleep(0.2);
3532
Harald Welte10985002017-12-12 09:29:15 +01003533 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003534 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3535 IPA_RSL[i].clear;
3536 }
Harald Welte10985002017-12-12 09:29:15 +01003537
3538 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3539 T.start;
3540 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003541 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003542 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003543 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003544 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003545 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003546 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003547 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003548 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003549 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003550 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003551 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003552 }
Harald Welte10985002017-12-12 09:29:15 +01003553 [] T.timeout {
3554 setverdict(pass);
3555 }
3556 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003557
3558 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003559}
Harald Welteae026692017-12-09 01:03:01 +01003560
Philipp Maierf45824a2019-08-14 14:44:10 +02003561/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3562 * paging response we can not know which MSC is in charge, so we will blindly
3563 * pick the first configured MSC. This behavior is required in order to make
3564 * MT-CSFB calls working because in those cases the BSC can not know that the
3565 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3566 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003567 */
3568testcase TC_paging_resp_unsol() runs on test_CT {
3569
3570 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003571 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003572
3573 var BSSAP_N_CONNECT_ind rx_c_ind;
3574 var DchanTuple dt;
3575 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003576 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003577
3578 /* Send CHAN RQD and wait for allocation; acknowledge it */
3579 dt.rsl_chan_nr := f_chreq_act_ack();
3580
3581 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3582 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3583
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003584
Philipp Maierf45824a2019-08-14 14:44:10 +02003585 /* Expevct a CR with a matching Paging response on the A-Interface */
3586 T.start;
3587 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003588 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003589 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003590 dt.sccp_conn_id := rx_c_ind.connectionId;
3591 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003592 }
3593 [] BSSAP.receive {
3594 setverdict(fail, "Received unexpected message on A-Interface!");
3595 }
3596 [] T.timeout {
3597 setverdict(fail, "Received nothing on A-Interface!");
3598 }
3599 }
3600
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003601 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003602 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003603}
3604
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003605/* Test RSL link drop causes counter increment */
3606testcase TC_rsl_drop_counter() runs on test_CT {
3607 var integer rsl_fail;
3608
Harald Welte89d42e82017-12-17 16:42:41 +01003609 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003610
3611 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3612
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01003613 f_ipa_rsl_stop(bts[0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003614
3615 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3616
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003617 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003618}
3619
3620/* TODO: Test OML link drop causes counter increment */
3621
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003622/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3623function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3624 timer T := 10.0;
3625
3626 bts[0].rsl.id := "IPA-0-RSL";
Harald Welte71389132021-12-09 21:58:18 +01003627 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA") alive;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003628 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3629 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003630 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003631
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003632 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003633
3634 f_init_mgcp("VirtMSC");
3635
3636 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3637 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3638 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3639 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3640
3641 /* wait for IPA OML link to connect and then disconnect */
3642 T.start;
3643 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003644 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003645 T.stop;
3646 return true;
3647 }
3648 [] IPA_RSL[0].receive { repeat }
3649 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003650 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003651 }
3652 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003653 return false;
3654}
3655
3656/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3657testcase TC_rsl_unknown_unit_id() runs on test_CT {
3658 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3659 setverdict(pass);
3660 } else {
3661 setverdict(fail, "Timeout RSL waiting for connection to close");
3662 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003663 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003664}
3665
3666
3667/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3668testcase TC_oml_unknown_unit_id() runs on test_CT {
3669 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3670 setverdict(pass);
3671 } else {
3672 setverdict(fail, "Timeout OML waiting for connection to close");
3673 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003674 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003675}
3676
3677
Harald Weltec1a2fff2017-12-17 11:06:19 +01003678/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003679 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003680 ***********************************************************************/
3681
Harald Welte6811d102019-04-14 22:23:14 +02003682import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003683import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003684import from RSL_Emulation all;
3685import from MSC_ConnectionHandler all;
3686
3687type function void_fn(charstring id) runs on MSC_ConnHdlr;
3688
Harald Welte336820c2018-05-31 20:34:52 +02003689/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003690private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3691 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003692 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003693 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003694 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003695 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003696 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3697 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3698 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003699 if (isvalue(bts[2])) {
3700 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3701 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3702 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003703 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003704 if (mp_enable_lcs_tests) {
3705 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3706 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3707 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003708 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003709 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003710 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003711}
3712
Neels Hofmeyrda436782021-07-20 22:09:06 +02003713function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003714runs on test_CT return MSC_ConnHdlr {
3715 var charstring id := testcasename();
3716 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003717 var integer bssap_idx := 0;
3718 if (isvalue(pars)) {
3719 bssap_idx := valueof(pars).mscpool.bssap_idx;
3720 }
Harald Welte336820c2018-05-31 20:34:52 +02003721 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003722 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003723 return vc_conn;
3724}
3725
3726function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3727runs on test_CT return MSC_ConnHdlr {
3728 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003729 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003730 return vc_conn;
3731}
3732
Neels Hofmeyrda436782021-07-20 22:09:06 +02003733function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3734runs on test_CT return MSC_ConnHdlr {
3735 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3736}
3737
Harald Weltea0630032018-03-20 21:09:55 +01003738/* first function inside ConnHdlr component; sets g_pars + starts function */
3739private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3740runs on MSC_ConnHdlr {
3741 if (isvalue(pars)) {
3742 g_pars := valueof(pars);
3743 }
3744 fn.apply(id);
3745}
3746
Oliver Smith26a3db72021-07-09 13:51:29 +02003747private function f_vty_encryption_a5(charstring options) runs on test_CT {
3748 f_vty_transceive(BSCVTY, "configure terminal");
3749 f_vty_transceive(BSCVTY, "network");
3750 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3751 f_vty_transceive(BSCVTY, "exit");
3752 f_vty_transceive(BSCVTY, "exit");
3753}
3754
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003755const charstring VTY_A5_DEFAULT := "0 1 3";
3756
Oliver Smith26a3db72021-07-09 13:51:29 +02003757private function f_vty_encryption_a5_reset() runs on test_CT {
3758 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003759 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003760}
3761
Harald Welte3c86ea02018-05-10 22:28:05 +02003762/* Establish signalling channel (non-assignment case) followed by cipher mode */
3763private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003764 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3765 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003766 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003767 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3768 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3769 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3770 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003771
Philipp Maier23000732018-05-18 11:25:37 +02003772 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003773 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003774}
3775testcase TC_ciph_mode_a5_0() runs on test_CT {
3776 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003777 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003778 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3779
3780 f_init(1, true);
3781 f_sleep(1.0);
3782 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3783 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003784 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003785}
3786testcase TC_ciph_mode_a5_1() runs on test_CT {
3787 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003788 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003789 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3790
3791 f_init(1, true);
3792 f_sleep(1.0);
3793 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3794 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003795 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003796}
Oliver Smith50b98122021-07-09 15:00:28 +02003797/* OS#4975: verify that A5/2 is preferred over A5/0 */
3798testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3799 var MSC_ConnHdlr vc_conn;
3800 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3801
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003802 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003803
3804 f_init(1, true);
3805 f_vty_encryption_a5("0 1 2 3");
3806 f_sleep(1.0);
3807 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3808 vc_conn.done;
3809 f_vty_encryption_a5_reset();
3810 f_shutdown_helper();
3811}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003812/* OS#4975: verify that A5/1 is preferred over A5/2 */
3813testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3814 var MSC_ConnHdlr vc_conn;
3815 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3816
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003817 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003818
3819 f_init(1, true);
3820 f_vty_encryption_a5("1 2");
3821 f_sleep(1.0);
3822 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3823 vc_conn.done;
3824 f_vty_encryption_a5_reset();
3825 f_shutdown_helper();
3826}
Harald Welte3c86ea02018-05-10 22:28:05 +02003827testcase TC_ciph_mode_a5_3() runs on test_CT {
3828 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003829 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003830 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3831
3832 f_init(1, true);
3833 f_sleep(1.0);
3834 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3835 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003836 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003837}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003838/* Establish a Signalling channel with A5/4 encryption. */
3839testcase TC_ciph_mode_a5_4() runs on test_CT {
3840 var MSC_ConnHdlr vc_conn;
3841 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3842 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003843
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003844 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003845 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003846 f_sleep(1.0);
3847 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3848 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003849 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003850 f_shutdown_helper();
3851}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003852/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3853private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3854 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3855 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3856 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3857 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3858
3859 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003860 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003861}
3862testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3863 var MSC_ConnHdlr vc_conn;
3864 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3865
3866 f_init(1, true);
3867 f_sleep(1.0);
3868 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3869 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003870 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003871}
3872
Harald Welte3c86ea02018-05-10 22:28:05 +02003873
3874/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003875private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003876 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3877 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003878
Harald Welte552620d2017-12-16 23:21:36 +01003879 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3880 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003881
Harald Weltea0630032018-03-20 21:09:55 +01003882 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003883 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003884}
Harald Welte552620d2017-12-16 23:21:36 +01003885testcase TC_assignment_fr_a5_0() runs on test_CT {
3886 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003887 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003888 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003889
Harald Welte89d42e82017-12-17 16:42:41 +01003890 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003891 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003892 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003893 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003894 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003895}
Harald Welte552620d2017-12-16 23:21:36 +01003896testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003897 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003898 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003899 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003900
Harald Welte89d42e82017-12-17 16:42:41 +01003901 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003902 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003903 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3904 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003905 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003906}
3907testcase TC_assignment_fr_a5_3() runs on test_CT {
3908 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003909 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003910 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003911
Harald Welte651fcdc2018-05-10 20:23:16 +02003912 f_init(1, true);
3913 f_sleep(1.0);
3914 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003915 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003916 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003917}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003918/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3919testcase TC_assignment_fr_a5_4() runs on test_CT {
3920 var MSC_ConnHdlr vc_conn;
3921 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3922 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3923
3924 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003925 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003926 f_sleep(1.0);
3927 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3928 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003929 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003930 f_shutdown_helper();
3931}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003932
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003933/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3934testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3935 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3936 var MSC_ConnHdlr vc_conn;
3937
3938 f_init(1, true);
3939 f_sleep(1.0);
3940
3941 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3942 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3943 vc_conn.done;
3944 f_shutdown_helper();
3945}
3946
Harald Welte552620d2017-12-16 23:21:36 +01003947/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3948private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003949 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003950 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003951 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003952
3953 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003954 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3955
Harald Weltea0630032018-03-20 21:09:55 +01003956 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003957 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003958}
Harald Welte552620d2017-12-16 23:21:36 +01003959testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3960 var MSC_ConnHdlr vc_conn;
3961
Harald Welte89d42e82017-12-17 16:42:41 +01003962 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003963 f_sleep(1.0);
3964
Harald Welte8863fa12018-05-10 20:15:27 +02003965 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003966 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003967 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003968}
3969
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003970private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3971 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3972 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003973
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003974 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3975 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3976
3977 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3978
3979 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003980
3981 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3982 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3983
3984 f_create_chan_and_exp();
3985 /* we should now have a COMPL_L3 at the MSC */
3986
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003987 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003988 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003989 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003990}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003991testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3992 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003993 var MSC_ConnHdlr vc_conn;
3994
Harald Welte89d42e82017-12-17 16:42:41 +01003995 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003996 f_sleep(1.0);
3997
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003998 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003999 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004000 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004001 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004002}
4003
4004
Harald Welte4532e0a2017-12-23 02:05:44 +01004005private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004006 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004007 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004008 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004009 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004010
4011 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004012 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004013
4014 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004015 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4016 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004017 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4018 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4019 };
4020 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004021 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004022}
4023
4024testcase TC_assignment_sign() runs on test_CT {
4025 var MSC_ConnHdlr vc_conn;
4026
4027 f_init(1, true);
4028 f_sleep(1.0);
4029
Harald Welte8863fa12018-05-10 20:15:27 +02004030 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004031 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004032 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004033}
4034
Harald Welte60aa5762018-03-21 19:33:13 +01004035/***********************************************************************
4036 * Codec (list) testing
4037 ***********************************************************************/
4038
4039/* check if the given rsl_mode is compatible with the a_elem */
4040private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4041return boolean {
4042 select (a_elem.codecType) {
4043 case (GSM_FR) {
4044 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4045 return true;
4046 }
4047 }
4048 case (GSM_HR) {
4049 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4050 return true;
4051 }
4052 }
4053 case (GSM_EFR) {
4054 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4055 return true;
4056 }
4057 }
4058 case (FR_AMR) {
4059 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4060 return true;
4061 }
4062 }
4063 case (HR_AMR) {
4064 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4065 return true;
4066 }
4067 }
4068 case else { }
4069 }
4070 return false;
4071}
4072
4073/* check if the given rsl_mode is compatible with the a_list */
4074private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4075return boolean {
4076 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4077 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4078 return true;
4079 }
4080 }
4081 return false;
4082}
4083
4084/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004085function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004086return BSSMAP_IE_ChannelType {
4087 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4088 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4089 select (a_elem.codecType) {
4090 case (GSM_FR) {
4091 ret.channelRateAndType := ChRate_TCHF;
4092 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4093 }
4094 case (GSM_HR) {
4095 ret.channelRateAndType := ChRate_TCHH;
4096 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4097 }
4098 case (GSM_EFR) {
4099 ret.channelRateAndType := ChRate_TCHF;
4100 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4101 }
4102 case (FR_AMR) {
4103 ret.channelRateAndType := ChRate_TCHF;
4104 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4105 }
4106 case (HR_AMR) {
4107 ret.channelRateAndType := ChRate_TCHH;
4108 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4109 }
4110 case else {
4111 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004112 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004113 }
4114 }
4115 return ret;
4116}
4117
Harald Weltea63b9102018-03-22 20:36:16 +01004118private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4119return template RSL_IE_Body {
4120 var template RSL_IE_Body mode_ie := {
4121 chan_mode := {
4122 len := ?,
4123 reserved := ?,
4124 dtx_d := ?,
4125 dtx_u := ?,
4126 spd_ind := RSL_SPDI_SPEECH,
4127 ch_rate_type := -,
4128 coding_alg_rate := -
4129 }
4130 }
4131
4132 select (a_elem.codecType) {
4133 case (GSM_FR) {
4134 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4135 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4136 }
4137 case (GSM_HR) {
4138 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4139 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4140 }
4141 case (GSM_EFR) {
4142 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4143 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4144 }
4145 case (FR_AMR) {
4146 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4147 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4148 }
4149 case (HR_AMR) {
4150 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4151 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4152 }
4153 }
4154 return mode_ie;
4155}
4156
Harald Welte60aa5762018-03-21 19:33:13 +01004157type record CodecListTest {
4158 BSSMAP_IE_SpeechCodecList codec_list,
4159 charstring id
4160}
4161type record of CodecListTest CodecListTests
4162
4163private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004164 f_assignment_codec(id);
4165}
4166
4167private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004168 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
4169 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01004170
4171 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004172 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004173 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4174 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4175 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004176 if (isvalue(g_pars.expect_mr_s0_s7)) {
4177 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4178 g_pars.expect_mr_s0_s7;
4179 }
Harald Welte79f3f542018-05-25 20:02:37 +02004180 }
Harald Welte60aa5762018-03-21 19:33:13 +01004181 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4182 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004183 log("expecting ASS COMPL like this: ", exp_compl);
4184
4185 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004186
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004187 if (not g_pars.expect_channel_mode_modify) {
4188 /* Verify that the RSL-side activation actually matches our expectations */
4189 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004190
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004191 var RSL_IE_Body mode_ie;
4192 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4193 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004194 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004195 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004196 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4197 if (not match(mode_ie, t_mode_ie)) {
4198 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4199 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004200 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004201
4202 var RSL_IE_Body mr_conf;
4203 if (g_pars.expect_mr_conf_ie != omit) {
4204 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4205 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4206 mtc.stop;
4207 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004208 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004209
4210 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4211 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4212 g_pars.expect_mr_conf_ie);
4213 }
4214 } else {
4215 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4216 log("found RSL MR CONFIG IE: ", mr_conf);
4217 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4218 mtc.stop;
4219 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004220 }
4221 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004222
4223 if (do_perform_clear) {
4224 f_perform_clear();
4225 }
Harald Welte60aa5762018-03-21 19:33:13 +01004226}
4227
Philipp Maierd0e64b02019-03-13 14:15:23 +01004228private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4229
4230 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4231 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4232
4233 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004234 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004235 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4236 }
4237 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4238 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4239 log("expecting ASS FAIL like this: ", exp_fail);
4240
4241 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004242 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004243}
4244
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004245const CounterNameVals counternames_bsc_bts_assignment := {
4246 { "assignment:attempted", 0 },
4247 { "assignment:completed", 0 },
4248 { "assignment:stopped", 0 },
4249 { "assignment:no_channel", 0 },
4250 { "assignment:timeout", 0 },
4251 { "assignment:failed", 0 },
4252 { "assignment:error", 0 }
4253};
4254
4255const CounterNameVals counternames_bts_assignment := {
4256 { "assignment:attempted_sign", 0 },
4257 { "assignment:attempted_speech", 0 },
4258 { "assignment:completed_sign", 0 },
4259 { "assignment:completed_speech", 0 },
4260 { "assignment:stopped_sign", 0 },
4261 { "assignment:stopped_speech", 0 },
4262 { "assignment:no_channel_sign", 0 },
4263 { "assignment:no_channel_speech", 0 },
4264 { "assignment:timeout_sign", 0 },
4265 { "assignment:timeout_speech", 0 },
4266 { "assignment:failed_sign", 0 },
4267 { "assignment:failed_speech", 0 },
4268 { "assignment:error_sign", 0 },
4269 { "assignment:error_speech", 0 }
4270};
4271
4272function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4273 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4274 f_ctrs_bts_init(bts_count, bts_names);
4275 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4276}
4277
Harald Welte60aa5762018-03-21 19:33:13 +01004278testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004279 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004280 var MSC_ConnHdlr vc_conn;
4281
4282 f_init(1, true);
4283 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004284 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004285
4286 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004287 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004288 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004289
4290 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4291 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4292 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4293 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4294 f_ctrs_bts_verify();
4295
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004296 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004297}
4298
4299testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004300 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004301 var MSC_ConnHdlr vc_conn;
4302
4303 f_init(1, true);
4304 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004305 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004306
4307 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004308 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004309 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004310
4311 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4312 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4313 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4314 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4315 f_ctrs_bts_verify();
4316
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004317 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004318}
4319
4320testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004321 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004322 var MSC_ConnHdlr vc_conn;
4323
4324 f_init(1, true);
4325 f_sleep(1.0);
4326
4327 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004328 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004329 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004330 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004331}
4332
Philipp Maierd0e64b02019-03-13 14:15:23 +01004333/* Allow 5,90k only (current default config) */
4334private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004335 f_vty_cfg_msc(BSCVTY, 0, {
4336 "amr-config 12_2k forbidden",
4337 "amr-config 10_2k forbidden",
4338 "amr-config 7_95k forbidden",
4339 "amr-config 7_40k forbidden",
4340 "amr-config 6_70k forbidden",
4341 "amr-config 5_90k allowed",
4342 "amr-config 5_15k forbidden",
4343 "amr-config 4_75k forbidden"
4344 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004345}
4346
4347/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4348 * ("Config-NB-Code = 1") */
4349private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004350 f_vty_cfg_msc(BSCVTY, 0, {
4351 "amr-config 12_2k allowed",
4352 "amr-config 10_2k forbidden",
4353 "amr-config 7_95k forbidden",
4354 "amr-config 7_40k allowed",
4355 "amr-config 6_70k forbidden",
4356 "amr-config 5_90k allowed",
4357 "amr-config 5_15k forbidden",
4358 "amr-config 4_75k allowed"
4359 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004360}
4361
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004362private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4363 var charstring tch;
4364 if (fr) {
4365 tch := "tch-f";
4366 } else {
4367 tch := "tch-h";
4368 }
4369 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4370}
4371
4372/* Set the AMR start-mode for this TCH back to the default configuration. */
4373private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4374 f_vty_amr_start_mode_set(fr, "auto");
4375}
4376
Harald Welte60aa5762018-03-21 19:33:13 +01004377testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004378 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004379 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004380
4381 /* Note: This setups the codec configuration. The parameter payload in
4382 * mr_conf must be consistant with the parameter codecElements in pars
4383 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004384 var RSL_IE_Body mr_conf := {
4385 other := {
4386 len := 2,
4387 payload := '2804'O
4388 }
4389 };
Harald Welte60aa5762018-03-21 19:33:13 +01004390
Philipp Maier7695a0d2018-09-27 17:52:14 +02004391 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004392 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004393 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4394 pars.expect_mr_conf_ie := mr_conf;
4395
Harald Welte60aa5762018-03-21 19:33:13 +01004396 f_init(1, true);
4397 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004398 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004399 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004400
Harald Welte8863fa12018-05-10 20:15:27 +02004401 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004402 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004403
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004404 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4405 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4406 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4407 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4408 f_ctrs_bts_verify();
4409
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004410 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004411 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004412}
4413
4414testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004415 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004416 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004417
4418 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004419 var RSL_IE_Body mr_conf := {
4420 other := {
4421 len := 2,
4422 payload := '2804'O
4423 }
4424 };
Harald Welte60aa5762018-03-21 19:33:13 +01004425
Philipp Maier7695a0d2018-09-27 17:52:14 +02004426 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004427 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004428 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4429 pars.expect_mr_conf_ie := mr_conf;
4430
Harald Welte60aa5762018-03-21 19:33:13 +01004431 f_init(1, true);
4432 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004433 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004434 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004435
Harald Welte8863fa12018-05-10 20:15:27 +02004436 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004437 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004438
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004439 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4440 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4441 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4442 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4443 f_ctrs_bts_verify();
4444
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004445 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004446 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004447}
4448
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004449/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4450testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4451 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4452 var MSC_ConnHdlr vc_conn;
4453
4454 f_init(1, true);
4455 f_sleep(1.0);
4456
4457 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4458 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4459 * expecting a Channel Mode Modify if the channel type is compatible. */
4460 f_disable_all_sdcch();
4461 f_disable_all_tch_h();
4462
4463 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4464 pars.expect_channel_mode_modify := true;
4465 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4466 vc_conn.done;
4467
4468 f_enable_all_sdcch();
4469 f_enable_all_tch();
4470 f_shutdown_helper();
4471}
4472
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004473/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4474testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4475 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4476 var MSC_ConnHdlr vc_conn;
4477
4478 var RSL_IE_Body mr_conf := {
4479 other := {
4480 len := 2,
4481 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4482 }
4483 };
4484
4485 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4486 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4487 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4488 pars.expect_mr_conf_ie := mr_conf;
4489
4490 f_init(1, true);
4491 f_sleep(1.0);
4492
4493 /* First set nonzero start mode bits */
4494 f_vty_amr_start_mode_set(true, "4");
4495 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4496 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4497 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4498 f_vty_amr_start_mode_set(true, "auto");
4499
4500 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4501 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004502
4503 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4504 f_vty_amr_start_mode_set(true, "1");
4505 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004506 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004507}
4508
Neels Hofmeyr21863562020-11-26 00:34:33 +00004509function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4510 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004511runs on test_CT {
4512
4513 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4514 var MSC_ConnHdlr vc_conn;
4515
4516 /* See note above */
4517 var RSL_IE_Body mr_conf := {
4518 other := {
4519 len := lengthof(mrconf),
4520 payload := mrconf
4521 }
4522 };
4523
4524 if (fr) {
4525 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4526 } else {
4527 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4528 }
4529 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4530 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4531 pars.expect_mr_conf_ie := mr_conf;
4532 pars.expect_mr_s0_s7 := exp_s8_s0;
4533
4534 f_init(1, true);
4535 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004536 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004537 f_sleep(1.0);
4538
4539 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4540 vc_conn.done;
4541 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004542 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004543}
4544
4545function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4546runs on test_CT {
4547
4548 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4549 var MSC_ConnHdlr vc_conn;
4550
4551 if (fr) {
4552 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4553 } else {
4554 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4555 }
4556 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4557 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4558
4559 f_init(1, true);
4560 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004561 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004562 f_sleep(1.0);
4563
4564 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4565 vc_conn.done;
4566 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004567 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004568}
4569
4570
4571/* Set S1, we expect an AMR multirate configuration IE with all four rates
4572 * set. */
4573testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004574 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004575 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004576}
4577
4578/* Set S1, we expect an AMR multirate configuration IE with the lower three
4579 * rates set. */
4580testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004581 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004582 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004583}
4584
4585/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4586 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4587testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004588 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004589 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004590}
4591
4592/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4593 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4594testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004595 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004596 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004597}
4598
4599/* The following block of tests selects more and more rates until all four
4600 * possible rates are in the active set (full rate) */
4601testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004602 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004603 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004604}
4605
4606testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004607 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004608 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004609}
4610
4611testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004612 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004613 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004614}
4615
4616testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004617 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004618 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004619}
4620
4621/* The following block of tests selects more and more rates until all three
4622 * possible rates are in the active set (half rate) */
4623testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004624 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004625 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004626}
4627
4628testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004629 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004630 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004631}
4632
4633testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004634 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004635 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004636}
4637
4638/* The following block tests what happens when the MSC does offer rate
4639 * configurations that are not supported by the BSC. Normally such situations
4640 * should not happen because the MSC gets informed by the BSC in advance via
4641 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4642 * to offer rates that are not applicable anyway. */
4643
4644testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004645 /* Try to include 12,2k in into the active set even though the channel
4646 * is half rate only. The BSC is expected to remove the 12,0k */
4647 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004648 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004649}
4650
4651testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004652 /* See what happens when all rates are selected at once. Since then
4653 * Also S1 is selected, this setting will be prefered and we should
4654 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4655 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004656 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004657}
4658
4659testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004660 /* Same as above, but with S1 missing, the MSC is then expected to
4661 * select the currently supported rates, which are also 12.2k, 7,40k,
4662 * 5,90k, and 4,75k, into the active set. */
4663 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004664 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004665}
4666
4667testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004668 /* Try to select no rates at all */
4669 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004670 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004671}
4672
4673testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004674 /* Try to select only unsupported rates */
4675 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004676 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004677}
4678
4679testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004680 /* Try to select 12,2k for half rate */
4681 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004682 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004683}
4684
Neels Hofmeyr21863562020-11-26 00:34:33 +00004685testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4686 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4687 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004688 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004689}
4690
4691testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4692 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4693 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004694 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004695}
4696
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004697testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004698 /* "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 +00004699 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4700 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004701 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004702}
4703
4704testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004705 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4706 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004707 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004708 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004709}
4710
Philipp Maierac09bfc2019-01-08 13:41:39 +01004711private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004712 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4713 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4714 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4715 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004716}
4717
4718private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004719 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4720 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004721}
4722
4723private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004724 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4725 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4726 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4727 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4728 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4729 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004730}
4731
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004732private function f_disable_all_sdcch() runs on test_CT {
4733 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4734 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4735 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4736 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4737}
4738
4739private function f_enable_all_sdcch() runs on test_CT {
4740 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4741 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4742 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4743 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4744}
4745
Philipp Maierac09bfc2019-01-08 13:41:39 +01004746/* Allow HR only */
4747private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4748 g_pars := f_gen_test_hdlr_pars();
4749 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4750 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4751 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4752 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4753 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4754 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4755 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004756 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004757}
4758
4759/* Allow FR only */
4760private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4761 g_pars := f_gen_test_hdlr_pars();
4762 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4763 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4764 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4765 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4766 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4767 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4768 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004769 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004770}
4771
4772/* Allow HR only (expect assignment failure) */
4773private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4774 g_pars := f_gen_test_hdlr_pars();
4775 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4776 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4777 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4778 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4779 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4780 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4781 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004782 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004783}
4784
4785/* Allow FR only (expect assignment failure) */
4786private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4787 g_pars := f_gen_test_hdlr_pars();
4788 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4789 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4790 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4791 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4792 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4793 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4794 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004795 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004796}
4797
4798/* Allow FR and HR, but prefer FR */
4799private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4800 g_pars := f_gen_test_hdlr_pars();
4801 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4802 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4803 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4804 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4805 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4806 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4807 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4808 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004809 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004810}
4811
4812/* Allow FR and HR, but prefer HR */
4813private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4814 g_pars := f_gen_test_hdlr_pars();
4815 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4816 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4817 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4818 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4819 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4820 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4821 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4822 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004823 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004824}
4825
4826/* Allow FR and HR, but prefer FR */
4827private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4828 g_pars := f_gen_test_hdlr_pars();
4829 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4830 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4831 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4832 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4833 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4834 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4835 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4836 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004837 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004838}
4839
4840/* Allow FR and HR, but prefer HR */
4841private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4842 g_pars := f_gen_test_hdlr_pars();
4843 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4844 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4845 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4846 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4847 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4848 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4849 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4850 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004851 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004852}
4853
4854/* Request a HR channel while all FR channels are exhausted, this is expected
4855 * to work without conflicts */
4856testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4857 var MSC_ConnHdlr vc_conn;
4858 f_init(1, true);
4859 f_sleep(1.0);
4860 f_enable_all_tch();
4861 f_disable_all_tch_f();
4862 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4863 vc_conn.done;
4864 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004865 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004866}
4867
4868/* Request a FR channel while all FR channels are exhausted, this is expected
4869 * to fail. */
4870testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4871 var MSC_ConnHdlr vc_conn;
4872 f_init(1, true);
4873 f_sleep(1.0);
4874 f_enable_all_tch();
4875 f_disable_all_tch_f();
4876 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4877 vc_conn.done;
4878 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004879 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004880}
4881
4882/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4883 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4884testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4885 var MSC_ConnHdlr vc_conn;
4886 f_init(1, true);
4887 f_sleep(1.0);
4888 f_enable_all_tch();
4889 f_disable_all_tch_f();
4890 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4891 vc_conn.done;
4892 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004893 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004894}
4895
4896/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4897 * are exhausted, this is expected to work without conflicts. */
4898testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4899 var MSC_ConnHdlr vc_conn;
4900 f_init(1, true);
4901 f_sleep(1.0);
4902 f_enable_all_tch();
4903 f_disable_all_tch_f();
4904 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4905 vc_conn.done;
4906 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004907 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004908}
4909
4910/* Request a FR channel while all HR channels are exhausted, this is expected
4911 * to work without conflicts */
4912testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4913 var MSC_ConnHdlr vc_conn;
4914 f_init(1, true);
4915 f_sleep(1.0);
4916 f_enable_all_tch();
4917 f_disable_all_tch_h();
4918 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4919 vc_conn.done;
4920 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004921 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004922}
4923
4924/* Request a HR channel while all HR channels are exhausted, this is expected
4925 * to fail. */
4926testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4927 var MSC_ConnHdlr vc_conn;
4928 f_init(1, true);
4929 f_sleep(1.0);
4930 f_enable_all_tch();
4931 f_disable_all_tch_h();
4932 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4933 vc_conn.done;
4934 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004935 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004936}
4937
4938/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4939 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4940testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4941 var MSC_ConnHdlr vc_conn;
4942 f_init(1, true);
4943 f_sleep(1.0);
4944 f_enable_all_tch();
4945 f_disable_all_tch_h();
4946 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4947 vc_conn.done;
4948 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004949 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004950}
4951
4952/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4953 * are exhausted, this is expected to work without conflicts. */
4954testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4955 var MSC_ConnHdlr vc_conn;
4956 f_init(1, true);
4957 f_sleep(1.0);
4958 f_enable_all_tch();
4959 f_disable_all_tch_h();
4960 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4961 vc_conn.done;
4962 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004963 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004964}
4965
4966/* Allow FR and HR, but prefer HR */
4967private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4968 g_pars := f_gen_test_hdlr_pars();
4969 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4970 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4971 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4972 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4973 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4974 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4975 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4976 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004977 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004978}
4979
4980/* Allow FR and HR, but prefer FR */
4981private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4982 g_pars := f_gen_test_hdlr_pars();
4983 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4984 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4985 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4986 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4987 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4988 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4989 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4990 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004991 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004992}
4993
4994/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4995 * HR, which is the prefered type, is selected. */
4996testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4997 var MSC_ConnHdlr vc_conn;
4998 f_init(1, true);
4999 f_sleep(1.0);
5000 f_enable_all_tch();
5001 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5002 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005003 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005004}
5005
5006/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5007 * FR, which is the prefered type, is selected. */
5008testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5009 var MSC_ConnHdlr vc_conn;
5010 f_init(1, true);
5011 f_sleep(1.0);
5012 f_enable_all_tch();
5013 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5014 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005015 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005016}
5017
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005018/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5019private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5020 g_pars := f_gen_test_hdlr_pars();
5021 g_pars.ra := '02'O; /* RA containing reason=LU */
5022
5023 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5024 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5025 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5026 var template uint3_t tsc := ?;
5027
5028 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5029 f_create_bssmap_exp(l3_enc);
5030 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5031 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5032
5033 /* we should now have a COMPL_L3 at the MSC */
5034 timer T := 10.0;
5035 T.start;
5036 alt {
5037 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5038 [] T.timeout {
5039 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5040 }
5041 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005042
5043 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005044}
5045testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5046 var MSC_ConnHdlr vc_conn;
5047 f_init(1, true);
5048 f_sleep(1.0);
5049 f_disable_all_sdcch();
5050 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5051 vc_conn.done;
5052 f_enable_all_sdcch();
5053 f_shutdown_helper();
5054}
5055
5056/* Request a signalling channel with all SDCCH exhausted, it is
5057 expected that no TCH will be selected for signalling and assigment will fail
5058 because it's dictated by VTY config */
5059testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5060 var RSL_Message rsl_unused, rsl_msg;
5061 var GsmRrMessage rr;
5062 f_init(1, false);
5063 f_sleep(1.0);
5064 f_vty_allow_tch_for_signalling(false, 0);
5065 f_disable_all_sdcch();
5066
5067 /* RA containing reason=LU */
5068 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
5069 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
5070 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5071 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5072 setverdict(fail, "Expected reject");
5073 }
5074
5075 f_vty_allow_tch_for_signalling(true, 0);
5076 f_enable_all_sdcch();
5077 f_shutdown_helper();
5078}
5079
5080/* Request a voice channel with all SDCCH exhausted, it is
5081 * expected that TCH channel will be allocated since the VTY option is only
5082 * aimed at signalling requests */
5083private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5084 g_pars := f_gen_test_hdlr_pars();
5085 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5086
5087 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5088 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5089 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5090 var template uint3_t tsc := ?;
5091
5092 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5093 f_create_bssmap_exp(l3_enc);
5094 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5095 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5096
5097 /* we should now have a COMPL_L3 at the MSC */
5098 timer T := 10.0;
5099 T.start;
5100 alt {
5101 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5102 [] T.timeout {
5103 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5104 }
5105 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005106 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005107}
5108testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5109 var MSC_ConnHdlr vc_conn;
5110 f_init(1, true);
5111 f_sleep(1.0);
5112 f_vty_allow_tch_for_signalling(false, 0);
5113 f_disable_all_sdcch();
5114
5115 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5116 vc_conn.done;
5117
5118 f_vty_allow_tch_for_signalling(true, 0);
5119 f_enable_all_sdcch();
5120 f_shutdown_helper();
5121}
5122
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005123testcase TC_assignment_osmux() runs on test_CT {
5124 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5125 var MSC_ConnHdlr vc_conn;
5126
5127 /* See note above */
5128 var RSL_IE_Body mr_conf := {
5129 other := {
5130 len := 2,
5131 payload := '2804'O
5132 }
5133 };
5134
5135 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5136 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5137 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
5138 pars.expect_mr_conf_ie := mr_conf;
5139 pars.use_osmux := true;
5140
5141 f_init(1, true, true);
5142 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005143 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005144
5145 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5146 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005147
5148 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005149 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005150}
5151
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005152/* test the procedure of the MSC requesting a Classmark Update:
5153 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5154 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005155private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005156 g_pars := f_gen_test_hdlr_pars();
5157
Harald Weltea0630032018-03-20 21:09:55 +01005158 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005159 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005160
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005161 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5162 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5163
Harald Welte898113b2018-01-31 18:32:21 +01005164 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5165 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5166 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005167
5168 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005169}
5170testcase TC_classmark() runs on test_CT {
5171 var MSC_ConnHdlr vc_conn;
5172 f_init(1, true);
5173 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005174 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005175 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005176 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005177}
5178
Harald Welteeddf0e92020-06-21 19:42:15 +02005179/* Send a CommonID from the simulated MSC and verify that the information is used to
5180 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5181private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5182 g_pars := f_gen_test_hdlr_pars();
5183 f_MscConnHdlr_init_vty();
5184
5185 f_create_chan_and_exp();
5186 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005187
5188 /* Send CommonID */
5189 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5190
5191 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5192 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5193 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5194
5195 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005196
5197 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005198}
5199testcase TC_common_id() runs on test_CT {
5200 var MSC_ConnHdlr vc_conn;
5201 f_init(1, true);
5202 f_sleep(1.0);
5203 vc_conn := f_start_handler(refers(f_tc_common_id));
5204 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005205 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005206}
5207
Harald Weltee3bd6582018-01-31 22:51:25 +01005208private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005209 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005210 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005211 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005212
Harald Weltee3bd6582018-01-31 22:51:25 +01005213 /* send the single message we want to send */
5214 f_rsl_send_l3(l3);
5215}
5216
5217private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5218 timer T := sec;
5219 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005220 T.start;
5221 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005222 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5223 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005224 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005225 }
5226 [] T.timeout {
5227 setverdict(pass);
5228 }
5229 }
5230}
5231
Harald Weltee3bd6582018-01-31 22:51:25 +01005232/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5233private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5234 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5235 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005236 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005237}
Harald Welte898113b2018-01-31 18:32:21 +01005238testcase TC_unsol_ass_fail() runs on test_CT {
5239 var MSC_ConnHdlr vc_conn;
5240 f_init(1, true);
5241 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005242 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005243 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005244 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005245}
Harald Welte552620d2017-12-16 23:21:36 +01005246
Harald Welteea99a002018-01-31 20:46:43 +01005247
5248/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5249private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005250 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5251 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005252 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005253}
5254testcase TC_unsol_ass_compl() runs on test_CT {
5255 var MSC_ConnHdlr vc_conn;
5256 f_init(1, true);
5257 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005258 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005259 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005260 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005261}
5262
5263
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005264/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5265private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005266 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5267 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005268 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005269}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005270testcase TC_unsol_ho_fail() runs on test_CT {
5271 var MSC_ConnHdlr vc_conn;
5272 f_init(1, true);
5273 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005274 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005275 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005276 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005277}
5278
5279
Harald Weltee3bd6582018-01-31 22:51:25 +01005280/* short message from MS should be ignored */
5281private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005282 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005283 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005284 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005285
5286 /* send short message */
5287 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5288 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005289 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005290}
5291testcase TC_err_82_short_msg() runs on test_CT {
5292 var MSC_ConnHdlr vc_conn;
5293 f_init(1, true);
5294 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005295 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005296 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005297 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005298}
5299
5300
Harald Weltee9e02e42018-01-31 23:36:25 +01005301/* 24.008 8.4 Unknown message must trigger RR STATUS */
5302private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5303 f_est_single_l3(ts_RRM_UL_REL('00'O));
5304 timer T := 3.0
5305 alt {
5306 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5307 setverdict(pass);
5308 }
5309 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005310 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005311 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005312 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005313}
5314testcase TC_err_84_unknown_msg() runs on test_CT {
5315 var MSC_ConnHdlr vc_conn;
5316 f_init(1, true);
5317 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005318 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005319 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005320 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005321}
5322
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005323/***********************************************************************
5324 * Handover
5325 ***********************************************************************/
5326
Harald Welte94e0c342018-04-07 11:33:23 +02005327/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5328private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5329runs on test_CT {
5330 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5331 " timeslot "&int2str(ts_nr)&" ";
5332 f_vty_transceive(BSCVTY, cmd & suffix);
5333}
5334
Harald Welte261af4b2018-02-12 21:20:39 +01005335/* 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 +07005336private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5337 uint8_t bts_nr, uint8_t trx_nr,
5338 in RslChannelNr chan_nr)
5339{
Harald Welte261af4b2018-02-12 21:20:39 +01005340 /* FIXME: resolve those from component-global state */
5341 var integer ts_nr := chan_nr.tn;
5342 var integer ss_nr;
5343 if (ischosen(chan_nr.u.ch0)) {
5344 ss_nr := 0;
5345 } else if (ischosen(chan_nr.u.lm)) {
5346 ss_nr := chan_nr.u.lm.sub_chan;
5347 } else if (ischosen(chan_nr.u.sdcch4)) {
5348 ss_nr := chan_nr.u.sdcch4.sub_chan;
5349 } else if (ischosen(chan_nr.u.sdcch8)) {
5350 ss_nr := chan_nr.u.sdcch8.sub_chan;
5351 } else {
5352 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005353 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005354 }
5355
5356 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5357 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005358 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005359}
5360
Neels Hofmeyr91401012019-07-11 00:42:35 +02005361/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5362 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5363 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5364 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5365 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005366private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5367 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5368{
5369 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005370}
5371
5372/* intra-BSC hand-over between BTS0 and BTS1 */
5373private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005374 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5375 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005376
5377 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5378 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5379
Harald Weltea0630032018-03-20 21:09:55 +01005380 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005381 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005382
5383 var HandoverState hs := {
5384 rr_ho_cmpl_seen := false,
5385 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005386 old_chan_nr := -,
5387 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005388 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005389 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005390 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005391 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5392 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005393
5394 /* From the MGW perspective, a handover is is characterized by
5395 * performing one MDCX operation with the MGW. So we expect to see
5396 * one more MDCX during handover. */
5397 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5398
Harald Welte261af4b2018-02-12 21:20:39 +01005399 alt {
5400 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005401 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005402
Philipp Maier4dae0652018-11-12 12:03:26 +01005403 /* Since this is an internal handover we expect the BSC to inform the
5404 * MSC about the event */
5405 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5406
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005407 /* Check the amount of MGCP transactions is still consistant with the
5408 * test expectation */
5409 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005410
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005411 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5412
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005413 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5414 * 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 +02005415 f_verify_encr_info(chan_act);
5416
5417 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005418
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005419 f_perform_clear(RSL1, RSL1_PROC);
5420
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005421 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005422}
5423
5424testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005425 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005426 var MSC_ConnHdlr vc_conn;
5427 f_init(2, true);
5428 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005429
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005430 pars.expect_tsc := BTS_TSC[0];
5431
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005432 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005433
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005434 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005435 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005436
5437 /* from f_establish_fully() */
5438 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5439 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5440 /* from handover */
5441 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5442 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5443 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5444 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005445 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5446 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005447 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005448 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005449}
Harald Weltee9e02e42018-01-31 23:36:25 +01005450
Oliver Smith7eabd312021-07-12 14:18:56 +02005451function 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 +02005452 var MSC_ConnHdlr vc_conn;
5453 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5454 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5455
5456 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005457 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005458 f_sleep(1.0);
5459
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005460 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005461
5462 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5463 vc_conn.done;
5464
5465 /* from f_establish_fully() */
5466 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5467 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5468 /* from handover */
5469 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5470 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5471 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5472 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005473 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5474 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005475 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005476 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005477 f_shutdown_helper();
5478}
5479
5480testcase TC_ho_int_a5_0() runs on test_CT {
5481 f_tc_ho_int_a5('01'O);
5482}
5483
5484testcase TC_ho_int_a5_1() runs on test_CT {
5485 f_tc_ho_int_a5('02'O);
5486}
5487
5488testcase TC_ho_int_a5_3() runs on test_CT {
5489 f_tc_ho_int_a5('08'O);
5490}
5491
5492testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005493 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005494}
5495
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005496/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5497private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5498 g_pars := f_gen_test_hdlr_pars();
5499 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5500 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005501
5502 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5503 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5504
5505 f_establish_fully(ass_cmd, exp_compl);
5506 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5507
5508 var HandoverState hs := {
5509 rr_ho_cmpl_seen := false,
5510 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005511 old_chan_nr := -,
5512 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005513 };
5514 /* issue hand-over command on VTY */
5515 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5516 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5517 f_rslem_suspend(RSL1_PROC);
5518
5519 /* From the MGW perspective, a handover is is characterized by
5520 * performing one MDCX operation with the MGW. So we expect to see
5521 * one more MDCX during handover. */
5522 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5523
5524 var RSL_Message rsl;
5525 var PDU_ML3_NW_MS l3;
5526 var RslChannelNr new_chan_nr;
5527 var GsmArfcn arfcn;
5528 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5529 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5530 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5531 setverdict(fail, "Expected handoverCommand");
5532 mtc.stop;
5533 }
5534 }
5535 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5536 new_chan_nr, arfcn);
5537
5538 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5539
5540 /* resume processing of RSL DChan messages, which was temporarily suspended
5541 * before performing a hand-over */
5542 f_rslem_resume(RSL1_PROC);
5543 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5544
5545 f_sleep(1.0);
5546
5547 /* Handover fails because no HANDO DET appears on the new lchan,
5548 * and the old lchan reports a Radio Link Failure. */
5549 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5550
5551 var PDU_BSSAP rx_clear_request;
5552 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5553 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5554 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5555
5556 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5557
5558 var MgcpCommand mgcp;
5559 interleave {
5560 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5561 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005562 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005563 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005564 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005565 }
5566 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005567 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005568 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005569 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005570 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005571 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5572 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5573 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005574 }
5575
5576 f_sleep(0.5);
5577 setverdict(pass);
5578}
5579testcase TC_ho_int_radio_link_failure() runs on test_CT {
5580 var MSC_ConnHdlr vc_conn;
5581 f_init(2, true);
5582 f_sleep(1.0);
5583
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005584 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005585
5586 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5587 vc_conn.done;
5588
5589 /* from f_establish_fully() */
5590 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5591 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5592 /* from handover */
5593 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5594 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5595 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5596 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005597 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5598 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005599 f_ctrs_bsc_and_bts_verify();
5600 f_shutdown_helper();
5601}
5602
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005603/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005604private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005605 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005606 var template MgcpResponse mgcp_resp;
5607 var MGCP_RecvFrom mrf;
5608 var template MgcpMessage msg_resp;
5609 var template MgcpMessage msg_dlcx := {
5610 command := tr_DLCX()
5611 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005612
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005613 if (g_pars.aoip) {
5614 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005615 log("Got first DLCX: ", mgcp);
5616 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005617 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005618
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005619 MGCP.receive(tr_DLCX()) -> value mgcp {
5620 log("Got second DLCX: ", mgcp);
5621 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5622 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005623 } else {
5624 /* For SCCPLite, BSC doesn't handle the MSC-side */
5625 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5626 log("Got first DLCX: ", mrf.msg.command);
5627 msg_resp := {
5628 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5629 }
5630 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5631 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005632 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005633}
5634
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005635private 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 +01005636
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005637 var NcellReports neighbor_rep := {
5638 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5639 };
5640 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5641 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5642 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005643
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005644 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005645
5646 f_sleep(0.5);
5647 /* The MSC negotiates Handover Request and Handover Request Ack with
5648 * the other BSS and comes back with a BSSMAP Handover Command
5649 * containing an RR Handover Command coming from the target BSS... */
5650
5651 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5652 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5653 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5654 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5655 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5656
5657 /* expect the Handover Command to go out on RR */
5658 var RSL_Message rsl_ho_cmd
5659 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5660 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5661 var RSL_IE_Body rsl_ho_cmd_l3;
5662 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5663 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5664 setverdict(fail);
5665 } else {
5666 log("Found L3 Info: ", rsl_ho_cmd_l3);
5667 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5668 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5669 setverdict(fail);
5670 } else {
5671 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5672 setverdict(pass);
5673 }
5674 }
5675
5676 /* When the other BSS has reported a completed handover, this side is
5677 * torn down. */
5678
5679 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5680 var BssmapCause cause := enum2int(cause_val);
5681 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5682
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005683 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005684
5685 interleave {
5686 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5687 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5688 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005689 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5690 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5691 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005692 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005693 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005694}
5695
5696private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5697 g_pars := f_gen_test_hdlr_pars();
5698 var PDU_BSSAP ass_req := f_gen_ass_req();
5699 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5700 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5701 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5702 f_establish_fully(ass_req, exp_compl);
5703
5704 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005705}
5706testcase TC_ho_out_of_this_bsc() runs on test_CT {
5707 var MSC_ConnHdlr vc_conn;
5708
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005709 f_init_vty();
5710 f_bts_0_cfg(BSCVTY,
5711 {"neighbor-list mode automatic",
5712 "handover 1",
5713 "handover algorithm 2",
5714 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005715 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005716 "neighbor lac 99 arfcn 123 bsic any"});
5717 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5718
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005719 f_init(1, true);
5720 f_sleep(1.0);
5721
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005722 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005723
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005724 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5725 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005726
5727 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5728 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5729 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5730 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5731 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5732 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5733 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005734 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005735}
5736
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005737private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5738 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005739 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005740 octetstring l3 := '0123456789'O)
5741runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005742 /* The old lchan and conn should still be active. See that arbitrary L3
5743 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005744 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005745 var template PDU_BSSAP exp_data := {
5746 discriminator := '1'B,
5747 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005748 dlci := dlci,
5749 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005750 pdu := {
5751 dtap := l3
5752 }
5753 };
5754 BSSAP.receive(exp_data);
5755 setverdict(pass);
5756}
5757
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005758private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5759 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005760 template (value) OCT1 dlci := '00'O,
5761 octetstring l3 := '0123456789'O)
5762runs on MSC_ConnHdlr {
5763 BSSAP.send(PDU_BSSAP:{
5764 discriminator := '1'B,
5765 spare := '0000000'B,
5766 dlci := dlci,
5767 lengthIndicator := lengthof(l3),
5768 pdu := {
5769 dtap := l3
5770 }
5771 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005772 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005773 setverdict(pass);
5774}
5775
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005776/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5777 * simply never sends a BSSMAP Handover Command. */
5778private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005779 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005780
5781 var PDU_BSSAP ass_req := f_gen_ass_req();
5782 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5783 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5784 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5785 f_establish_fully(ass_req, exp_compl);
5786
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005787 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005788 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5789
5790 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5791
5792 /* osmo-bsc should time out 10 seconds after the handover started.
5793 * Let's give it a bit extra. */
5794 f_sleep(15.0);
5795
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005796 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005797 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005798 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005799}
5800testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5801 var MSC_ConnHdlr vc_conn;
5802
5803 f_init(1, true);
5804 f_sleep(1.0);
5805
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005806 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005807
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005808 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5809 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005810
5811 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5812 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5813 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5814 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5815 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5816 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5817 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005818 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005819}
5820
5821/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5822 * RR Handover Failure. */
5823private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005824 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005825
5826 var PDU_BSSAP ass_req := f_gen_ass_req();
5827 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5828 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5829 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5830 f_establish_fully(ass_req, exp_compl);
5831
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005832 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005833 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5834
5835 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5836
5837 f_sleep(0.5);
5838 /* The MSC negotiates Handover Request and Handover Request Ack with
5839 * the other BSS and comes back with a BSSMAP Handover Command
5840 * containing an RR Handover Command coming from the target BSS... */
5841
5842 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5843 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5844 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5845 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5846 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5847
5848 /* expect the Handover Command to go out on RR */
5849 var RSL_Message rsl_ho_cmd
5850 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5851 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5852 var RSL_IE_Body rsl_ho_cmd_l3;
5853 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5854 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5855 setverdict(fail);
5856 } else {
5857 log("Found L3 Info: ", rsl_ho_cmd_l3);
5858 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5859 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5860 setverdict(fail);
5861 } else {
5862 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5863 setverdict(pass);
5864 }
5865 }
5866
5867 f_sleep(0.2);
5868 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5869
5870 /* Should tell the MSC about the failure */
5871 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5872
5873 f_sleep(1.0);
5874
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005875 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005876 f_sleep(1.0);
5877
5878 setverdict(pass);
5879 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005880 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005881}
5882testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5883 var MSC_ConnHdlr vc_conn;
5884
5885 f_init(1, true);
5886 f_sleep(1.0);
5887
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005888 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005889
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005890 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5891 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005892
5893 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5894 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5895 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5896 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5897 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5898 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5899 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005900 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005901}
5902
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005903/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5904 * (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 +02005905 * and the lchan is released. */
5906private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005907 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005908
5909 var PDU_BSSAP ass_req := f_gen_ass_req();
5910 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5911 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5912 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5913 f_establish_fully(ass_req, exp_compl);
5914
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005915 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005916 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5917
5918 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5919
5920 f_sleep(0.5);
5921 /* The MSC negotiates Handover Request and Handover Request Ack with
5922 * the other BSS and comes back with a BSSMAP Handover Command
5923 * containing an RR Handover Command coming from the target BSS... */
5924
5925 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5926 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5927 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5928 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5929 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5930
5931 /* expect the Handover Command to go out on RR */
5932 var RSL_Message rsl_ho_cmd
5933 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5934 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5935 var RSL_IE_Body rsl_ho_cmd_l3;
5936 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5937 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5938 setverdict(fail);
5939 } else {
5940 log("Found L3 Info: ", rsl_ho_cmd_l3);
5941 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5942 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5943 setverdict(fail);
5944 } else {
5945 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5946 setverdict(pass);
5947 }
5948 }
5949
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005950 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5951 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5952 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005953
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005954 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005955 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5956 log("Got BSSMAP Clear Request");
5957 /* Instruct BSC to clear channel */
5958 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5959 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5960
5961 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005962 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005963 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5964 log("Got Deact SACCH");
5965 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005966 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005967 log("Got RR Release");
5968 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005969 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005970 log("Got RF Chan Rel");
5971 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005972 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005973 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005974 }
5975
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005976 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005977 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005978 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005979
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005980 setverdict(pass);
5981 f_sleep(1.0);
5982}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005983testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005984 var MSC_ConnHdlr vc_conn;
5985
5986 f_init(1, true);
5987 f_sleep(1.0);
5988
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005989 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005990
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005991 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005992 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005993
5994 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5995 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5996 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5997 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5998 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5999 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6000 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006001 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006002}
6003
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006004private 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 +01006005 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006006 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6007 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6008 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6009 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6010 * before we get started. */
6011 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6012 f_rslem_register(0, new_chan_nr);
6013 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006014 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006015 f_sleep(1.0);
6016
6017 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6018 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6019 activate(as_Media());
6020
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006021 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6022 cell_id_source := g_pars.cell_id_source,
6023 oldToNewBSSIEs := oldToNewBSSIEs,
6024 enc := g_pars.encr);
6025 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6026 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6027 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6028 } else {
6029 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6030 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6031 BSSAP.send(ho_req);
6032 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006033
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006034 alt {
6035 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6036 if (g_pars.expect_ho_fail) {
6037 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6038 "Expected Handover Request to fail, but got Handover Request Ack")
6039 }
6040 }
6041 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6042 if (not g_pars.expect_ho_fail) {
6043 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6044 "Expected Handover Request to succeed, but got Handover Failure")
6045 }
6046 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6047 // For now just accept any cause.
6048 BSSAP.receive(tr_BSSMAP_ClearRequest);
6049 setverdict(pass);
6050 return;
6051 }
6052 }
6053
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006054 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6055
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006056 /* we're sure that the channel activation is done now, verify the parameters in it */
6057 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6058 f_verify_encr_info(chan_act);
6059 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006060
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006061 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6062 if (not g_pars.aoip) {
6063 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6064 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6065 }
6066 /* TODO: check actual codecs? */
6067 } else {
6068 if (g_pars.aoip) {
6069 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6070 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6071 }
6072 }
6073
6074 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6075 if (not g_pars.aoip) {
6076 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6077 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6078 }
6079 /* TODO: check actual codec? */
6080 } else {
6081 if (g_pars.aoip) {
6082 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6083 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6084 }
6085 }
6086
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006087 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006088 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6089 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6090 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6091 log("L3 Info in HO Request Ack is ", ho_command);
6092
6093 var GsmArfcn arfcn;
6094 var RslChannelNr actual_new_chan_nr;
6095 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6096 actual_new_chan_nr, arfcn);
6097
6098 if (actual_new_chan_nr != new_chan_nr) {
6099 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6100 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6101 setverdict(fail);
6102 return;
6103 }
6104 log("Handover Command chan_nr is", actual_new_chan_nr);
6105
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006106 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6107 if (not match(got_tsc, expect_target_tsc)) {
6108 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6109 expect_target_tsc, " got ", got_tsc);
6110 mtc.stop;
6111 } else {
6112 log("handoverCommand: verified TSC = ", got_tsc);
6113 }
6114
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006115 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6116 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6117 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6118 var template (present) CipherModeSetting_TV tr_cms := {
6119 sC := '0'B, /* no ciphering by default */
6120 algorithmIdentifier := '000'B,
6121 elementIdentifier := ?
6122 };
6123 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6124 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6125 tr_cms.sC := '1'B;
6126 }
6127 if (not match(cms, tr_cms)) {
6128 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6129 cms, ", expected: ", tr_cms);
6130 }
6131 } else {
6132 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6133 }
6134
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006135 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6136 * tells the MS to handover to the new lchan. Here comes the new MS on
6137 * the new lchan with a Handover RACH: */
6138
6139 /* send handover detect */
6140
6141 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6142
6143 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6144
6145 /* send handover complete over the new channel */
6146
6147 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6148 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6149 enc_PDU_ML3_MS_NW(l3_tx)));
6150
6151 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006152 setverdict(pass);
6153}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006154
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006155private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006156 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006157 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6158 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6159 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006160 }
6161 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006162 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006163 } else {
6164 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006165 }
6166 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006167 if (g_pars.expect_ho_fail) {
6168 f_perform_clear_no_lchan();
6169 } else {
6170 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6171 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006172 setverdict(pass);
6173}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006174function 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 +01006175 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006176
6177 f_init(1, true);
6178 f_sleep(1.0);
6179
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006180 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006181 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006182
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006183 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6184 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006185
6186 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6187 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006188
6189 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006190 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006191 if (pars.expect_ho_fail) {
6192 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6193 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6194 } else {
6195 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6196 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6197 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006198 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006199
6200 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006201}
6202
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006203testcase TC_ho_into_this_bsc() runs on test_CT {
6204 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6205 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006206 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006207}
6208
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006209function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6210 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006211 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006212 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006213 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006214 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006215 f_shutdown_helper();
6216}
6217
6218testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006219 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006220}
6221
6222testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006223 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006224}
6225
6226testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006227 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006228}
6229
6230testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006231 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006232}
6233
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006234/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6235 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6236 *
6237 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6238 * omitted.
6239 *
6240 * Related: SYS#5839
6241 */
6242testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6243 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6244}
6245
6246testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6247 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6248}
6249
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006250/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6251testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6252 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6253 expect_fail := true); // 0x18 = A5/3 and A5/4
6254}
6255
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006256testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6257 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6258 pars.host_aoip_tla := "::6";
6259 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006260 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006261}
6262
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006263/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006264 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006265 channel is later released (RR CHannel Release), should trigger inclusion of
6266 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6267 neighbors. */
6268testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6269 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6270 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006271 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006272 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006273
6274 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6275 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6276 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006277 f_shutdown_helper();
6278}
6279
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006280/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6281testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6282 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6283 pars.encr := f_encr_params('08'O); /* only A5/3 */
6284 pars.last_used_eutran_plmn := '323454'O;
6285 pars.exp_fast_return := true;
6286 f_tc_ho_into_this_bsc_main(pars);
6287
6288 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6289 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6290 f_ctrs_bsc_and_bts_verify();
6291 f_shutdown_helper();
6292}
6293
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006294/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6295 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6296 list when the channel is released. */
6297testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6298 f_init_vty();
6299 f_vty_allow_srvcc_fast_return(true, 0)
6300
6301 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6302 pars.last_used_eutran_plmn := '323454'O;
6303 pars.exp_fast_return := false;
6304 f_tc_ho_into_this_bsc_main(pars);
6305 f_vty_allow_srvcc_fast_return(false, 0);
6306 f_shutdown_helper();
6307}
6308
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006309/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6310testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6311 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6312 pars.last_used_eutran_plmn := '323454'O;
6313 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6314 f_tc_ho_into_this_bsc_main(pars);
6315
6316 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6317 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6318 f_ctrs_bsc_and_bts_verify();
6319 f_shutdown_helper();
6320}
6321
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006322private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6323 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6324 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6325 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6326 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6327 setverdict(pass);
6328}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006329
6330private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6331 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006332 var MSC_ConnHdlr vc_conn;
6333 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6334
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006335 f_init_vty();
6336 f_bts_0_cfg(BSCVTY,
6337 {"neighbor-list mode automatic",
6338 "handover 1",
6339 "handover algorithm 2",
6340 "handover2 window rxlev averaging 1",
6341 "no neighbors",
6342 "neighbor lac 99 arfcn 123 bsic any"});
6343 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6344
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006345 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006346 if (disable_fast_return) {
6347 f_vty_allow_srvcc_fast_return(true, 0);
6348 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006349 f_sleep(1.0);
6350
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006351 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006352
6353 pars.last_used_eutran_plmn := '323454'O;
6354 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6355 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6356
6357 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6358 vc_conn.done;
6359
6360 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6361 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6362 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6363 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6364 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6365 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006366
6367 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6368 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006369 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006370
6371 if (disable_fast_return) {
6372 f_vty_allow_srvcc_fast_return(false, 0);
6373 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006374 f_shutdown_helper();
6375}
6376
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006377/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6378 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6379 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6380 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6381testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6382 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6383}
6384/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6385 * independently of fast-reture allowed/forbidden in local BTS */
6386testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6387 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6388}
6389
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006390private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6391 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6392 f_rslem_register(0, new_chan_nr);
6393 g_chan_nr := new_chan_nr;
6394 f_sleep(1.0);
6395
6396 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6397 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6398 activate(as_Media());
6399
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006400 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006401 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006402 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006403
6404 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6405
6406 var PDU_BSSAP rx_bssap;
6407 var octetstring ho_command_str;
6408
6409 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6410
6411 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6412 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6413 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6414 log("L3 Info in HO Request Ack is ", ho_command);
6415
6416 var GsmArfcn arfcn;
6417 var RslChannelNr actual_new_chan_nr;
6418 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6419 actual_new_chan_nr, arfcn);
6420
6421 if (actual_new_chan_nr != new_chan_nr) {
6422 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6423 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6424 setverdict(fail);
6425 return;
6426 }
6427 log("Handover Command chan_nr is", actual_new_chan_nr);
6428
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006429 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6430 f_sleep(1.0);
6431
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006432 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6433 * tells the MS to handover to the new lchan. In this case, the MS
6434 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6435 * Handover Failure to the MSC. The procedure according to 3GPP TS
6436 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6437 * BSSMAP Clear Command: */
6438
6439 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6440 var BssmapCause cause := enum2int(cause_val);
6441 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6442
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006443 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006444 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006445 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006446
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006447 setverdict(pass);
6448 f_sleep(1.0);
6449
6450 setverdict(pass);
6451}
6452testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6453 var MSC_ConnHdlr vc_conn;
6454 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6455
6456 f_init(1, true);
6457 f_sleep(1.0);
6458
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006459 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006460
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006461 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6462 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006463
6464 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6465 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006466
6467 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6468 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6469 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6470 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6471 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006472 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006473}
6474
6475private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6476 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6477 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6478 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6479 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6480 * before we get started. */
6481 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6482 f_rslem_register(0, new_chan_nr);
6483 g_chan_nr := new_chan_nr;
6484 f_sleep(1.0);
6485
6486 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6487 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6488 activate(as_Media());
6489
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006490 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006491 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006492 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006493
6494 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6495
6496 var PDU_BSSAP rx_bssap;
6497 var octetstring ho_command_str;
6498
6499 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6500
6501 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6502 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6503 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6504 log("L3 Info in HO Request Ack is ", ho_command);
6505
6506 var GsmArfcn arfcn;
6507 var RslChannelNr actual_new_chan_nr;
6508 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6509 actual_new_chan_nr, arfcn);
6510
6511 if (actual_new_chan_nr != new_chan_nr) {
6512 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6513 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6514 setverdict(fail);
6515 return;
6516 }
6517 log("Handover Command chan_nr is", actual_new_chan_nr);
6518
6519 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6520 * tells the MS to handover to the new lchan. Here comes the new MS on
6521 * the new lchan with a Handover RACH: */
6522
6523 /* send handover detect */
6524
6525 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6526
6527 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6528
6529 /* The MSC chooses to clear the connection now, maybe we got the
6530 * Handover RACH on the new cell but the MS still signaled Handover
6531 * Failure to the old BSS? */
6532
6533 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6534 var BssmapCause cause := enum2int(cause_val);
6535 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6536
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006537 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006538 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006539 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006540
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006541 f_sleep(1.0);
6542}
6543testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6544 var MSC_ConnHdlr vc_conn;
6545 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6546
6547 f_init(1, true);
6548 f_sleep(1.0);
6549
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006550 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006551
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006552 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6553 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006554
6555 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6556 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006557
6558 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6559 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6560 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6561 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6562 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006563 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006564}
6565
6566/* The new BSS's lchan times out before the MSC decides that handover failed. */
6567private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6568 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6569 f_rslem_register(0, new_chan_nr);
6570 g_chan_nr := new_chan_nr;
6571 f_sleep(1.0);
6572
6573 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6574 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6575 activate(as_Media());
6576
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006577 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006578 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006579 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006580
6581 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6582
6583 var PDU_BSSAP rx_bssap;
6584 var octetstring ho_command_str;
6585
6586 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6587
6588 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6589 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6590 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6591 log("L3 Info in HO Request Ack is ", ho_command);
6592
6593 var GsmArfcn arfcn;
6594 var RslChannelNr actual_new_chan_nr;
6595 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6596 actual_new_chan_nr, arfcn);
6597
6598 if (actual_new_chan_nr != new_chan_nr) {
6599 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6600 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6601 setverdict(fail);
6602 return;
6603 }
6604 log("Handover Command chan_nr is", actual_new_chan_nr);
6605
6606 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6607 * tells the MS to handover to the new lchan. But the MS never shows up
6608 * on the new lchan. */
6609
6610 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6611
6612 /* Did osmo-bsc also send a Clear Request? */
6613 timer T := 0.5;
6614 T.start;
6615 alt {
6616 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6617 [] T.timeout { }
6618 }
6619
6620 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6621 * asked for it, this is a Handover Failure after all). */
6622
6623 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6624 var BssmapCause cause := enum2int(cause_val);
6625 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6626
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006627 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006628 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006629 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006630
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006631 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006632}
6633testcase TC_ho_in_fail_no_detect() runs on test_CT {
6634 var MSC_ConnHdlr vc_conn;
6635 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6636
6637 f_init(1, true);
6638 f_sleep(1.0);
6639
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006640 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006641
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006642 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6643 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006644
6645 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6646 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006647
6648 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6649 f_ctrs_bsc_and_bts_add(0, "handover:error");
6650 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6651 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6652 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006653 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006654}
6655
6656/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6657private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6658 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6659 f_rslem_register(0, new_chan_nr);
6660 g_chan_nr := new_chan_nr;
6661 f_sleep(1.0);
6662
6663 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6664 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6665 activate(as_Media());
6666
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006667 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006668 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006669 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006670
6671 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6672
6673 var PDU_BSSAP rx_bssap;
6674 var octetstring ho_command_str;
6675
6676 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6677
6678 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6679 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6680 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6681 log("L3 Info in HO Request Ack is ", ho_command);
6682
6683 var GsmArfcn arfcn;
6684 var RslChannelNr actual_new_chan_nr;
6685 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6686 actual_new_chan_nr, arfcn);
6687
6688 if (actual_new_chan_nr != new_chan_nr) {
6689 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6690 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6691 setverdict(fail);
6692 return;
6693 }
6694 log("Handover Command chan_nr is", actual_new_chan_nr);
6695
6696 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6697 * tells the MS to handover to the new lchan. But the MS never shows up
6698 * on the new lchan. */
6699
6700 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6701
6702 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006703 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006704
6705 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006706 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6707 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6708 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006709 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006710 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006711 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006712
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006713 f_sleep(1.0);
6714}
6715testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6716 var MSC_ConnHdlr vc_conn;
6717 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6718
6719 f_init(1, true);
6720 f_sleep(1.0);
6721
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006722 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006723
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006724 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6725 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006726
6727 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6728 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006729
6730 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6731 f_ctrs_bsc_and_bts_add(0, "handover:error");
6732 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6733 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6734 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006735 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006736}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006737
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006738/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6739 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6740 * empty N-Connect case. */
6741testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6742 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6743 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6744 f_tc_ho_into_this_bsc_main(pars);
6745 f_shutdown_helper();
6746}
6747
Neels Hofmeyr91401012019-07-11 00:42:35 +02006748type record of charstring Commands;
6749
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006750private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006751{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006752 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006753 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006754 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006755 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006756 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006757}
6758
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006759private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6760{
6761 f_vty_enter_cfg_cs7_inst(pt, 0);
6762 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6763 f_vty_transceive(pt, cmds[i]);
6764 }
6765 f_vty_transceive(pt, "end");
6766}
6767
Neels Hofmeyr91401012019-07-11 00:42:35 +02006768private function f_probe_for_handover(charstring log_label,
6769 charstring log_descr,
6770 charstring handover_vty_cmd,
6771 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006772 boolean is_inter_bsc_handover := false,
6773 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006774runs on MSC_ConnHdlr
6775{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006776 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6777 * lchans to be established on bts 1 or bts 2. */
6778 f_rslem_suspend(RSL1_PROC);
6779 f_rslem_suspend(RSL2_PROC);
6780
Neels Hofmeyr91401012019-07-11 00:42:35 +02006781 var RSL_Message rsl;
6782
6783 var charstring log_msg := " (expecting handover)"
6784 if (not expect_handover) {
6785 log_msg := " (expecting NO handover)";
6786 }
6787 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6788 f_vty_transceive(BSCVTY, handover_vty_cmd);
6789
Neels Hofmeyr91401012019-07-11 00:42:35 +02006790 timer T := 2.0;
6791 T.start;
6792
6793 alt {
6794 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6795 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6796 log("Rx L3 from net: ", l3);
6797 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6798 var RslChannelNr new_chan_nr;
6799 var GsmArfcn arfcn;
6800 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6801 new_chan_nr, arfcn);
6802 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6803 log(l3.msgs.rrm.handoverCommand);
6804
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006805 /* Verify correct TSC in handoverCommand */
6806 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6807 if (not match(got_tsc, expect_target_tsc)) {
6808 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6809 expect_target_tsc, " got ", got_tsc);
6810 mtc.stop;
6811 } else {
6812 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6813 expect_target_tsc, ")");
6814 }
6815
Neels Hofmeyr91401012019-07-11 00:42:35 +02006816 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6817 * matter on which BTS it really is, we're not going to follow through an entire handover
6818 * anyway. */
6819 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6820 f_rslem_resume(RSL1_PROC);
6821 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6822 f_rslem_resume(RSL2_PROC);
6823
6824 if (expect_handover and not is_inter_bsc_handover) {
6825 setverdict(pass);
6826 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6827 } else {
6828 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6829 & log_label & ": " & log_descr);
6830 }
6831
6832 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6833 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6834 * Handover Failure. */
6835 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6836
6837 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6838 f_sleep(0.5);
6839 RSL1.clear;
6840 RSL2.clear;
6841 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6842 break;
6843 } else {
6844 repeat;
6845 }
6846 }
6847 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6848 if (expect_handover and is_inter_bsc_handover) {
6849 setverdict(pass);
6850 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6851 } else {
6852 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6853 & log_label & ": " & log_descr);
6854 }
6855
6856 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6857
6858 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6859 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6860 * setting a short timeout and waiting is the only way. */
6861 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6862 f_sleep(1.5);
6863 log("f_probe_for_handover(" & log_label & "): ...done");
6864
6865 break;
6866 }
6867 [] T.timeout {
6868 if (expect_handover) {
6869 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6870 & log_label & ": " & log_descr);
6871 } else {
6872 setverdict(pass);
6873 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6874 }
6875 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6876 break;
6877 }
6878 }
6879
6880 f_rslem_resume(RSL1_PROC);
6881 f_rslem_resume(RSL2_PROC);
6882 f_sleep(3.0);
6883 RSL.clear;
6884
6885 log("f_probe_for_handover(" & log_label & "): done clearing");
6886}
6887
6888/* Test the effect of various neighbor configuration scenarios:
6889 *
6890 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6891 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6892 */
6893private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6894 g_pars := f_gen_test_hdlr_pars();
6895 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6896 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006897
6898 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6899 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6900
6901 /* Establish lchan at bts 0 */
6902 f_establish_fully(ass_cmd, exp_compl);
6903
6904 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6905 f_vty_enter_cfg_network(BSCVTY);
6906 f_vty_transceive(BSCVTY, "timer T7 1");
6907 f_vty_transceive(BSCVTY, "end");
6908}
6909
6910private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6911 f_tc_ho_neighbor_config_start();
6912
6913 /*
6914 * bts 0 ARFCN 871 BSIC 10
6915 * bts 1 ARFCN 871 BSIC 11
6916 * bts 2 ARFCN 871 BSIC 12
6917 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6918 */
6919
6920 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006921 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006922 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6923 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006924 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006925
6926 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6927 "handover any to arfcn 13 bsic 39",
6928 false);
6929
6930 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6931 "handover any to arfcn 871 bsic 12",
6932 false);
6933
6934 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6935 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006936 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006937
6938 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006939}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006940testcase TC_ho_neighbor_config_1() runs on test_CT {
6941 var MSC_ConnHdlr vc_conn;
6942 f_init(3, true, guard_timeout := 60.0);
6943 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006944 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006945 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6946 vc_conn.done;
6947
6948 /* f_tc_ho_neighbor_config_start() */
6949 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6950 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6951
6952 /* 1.a */
6953 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6954 * handover quickly by sending a Handover Failure message. */
6955 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6956 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6957 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6958 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006959 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6960 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006961
6962 /* 1.b */
6963 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6964 f_ctrs_bsc_and_bts_add(0, "handover:error");
6965
6966 /* 1.c */
6967 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6968 f_ctrs_bsc_and_bts_add(0, "handover:error");
6969
6970 /* 1.d */
6971 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6972 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6973 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6974 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006975 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6976 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006977
6978 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006979 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006980}
6981
Neels Hofmeyr91401012019-07-11 00:42:35 +02006982private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6983 f_tc_ho_neighbor_config_start();
6984
6985 /*
6986 * bts 0 ARFCN 871 BSIC 10
6987 * bts 1 ARFCN 871 BSIC 11
6988 * bts 2 ARFCN 871 BSIC 12
6989 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6990 */
6991
6992 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006993 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006994 f_sleep(0.5);
6995
6996 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6997 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006998 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006999
7000 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7001 "handover any to arfcn 871 bsic 12",
7002 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007003 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007004}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007005testcase TC_ho_neighbor_config_2() runs on test_CT {
7006 var MSC_ConnHdlr vc_conn;
7007 f_init(3, true, guard_timeout := 50.0);
7008 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007009 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007010 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7011 vc_conn.done;
7012
7013 /* f_tc_ho_neighbor_config_start() */
7014 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7015 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7016
7017 /* 2.a */
7018 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7019 * handover quickly by sending a Handover Failure message. */
7020 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7021 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7022 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7023 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007024 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7025 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007026
7027 /* 2.b */
7028 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7029 f_ctrs_bsc_and_bts_add(0, "handover:error");
7030
7031 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007032 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007033}
7034
Neels Hofmeyr91401012019-07-11 00:42:35 +02007035private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7036 f_tc_ho_neighbor_config_start();
7037
7038 /*
7039 * bts 0 ARFCN 871 BSIC 10
7040 * bts 1 ARFCN 871 BSIC 11
7041 * bts 2 ARFCN 871 BSIC 12
7042 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7043 */
7044
7045 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007046 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007047 f_sleep(0.5);
7048
7049 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7050 "handover any to arfcn 871 bsic 11",
7051 false);
7052 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",
7053 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007054 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007055 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007056}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007057testcase TC_ho_neighbor_config_3() runs on test_CT {
7058 var MSC_ConnHdlr vc_conn;
7059 f_init(3, true, guard_timeout := 50.0);
7060 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007061 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007062 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7063 vc_conn.done;
7064
7065 /* f_tc_ho_neighbor_config_start() */
7066 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7067 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7068
7069 /* 3.a */
7070 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7071 f_ctrs_bsc_and_bts_add(0, "handover:error");
7072
7073 /* 3.b */
7074 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7075 * handover quickly by sending a Handover Failure message. */
7076 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7077 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7078 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7079 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007080 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7081 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007082
7083 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007084 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007085}
7086
Neels Hofmeyr91401012019-07-11 00:42:35 +02007087private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7088 f_tc_ho_neighbor_config_start();
7089
7090 /*
7091 * bts 0 ARFCN 871 BSIC 10
7092 * bts 1 ARFCN 871 BSIC 11
7093 * bts 2 ARFCN 871 BSIC 12
7094 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7095 */
7096
7097 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007098 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007099 f_sleep(0.5);
7100
7101 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7102 "handover any to arfcn 871 bsic 11",
7103 false);
7104 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7105 "handover any to arfcn 871 bsic 12",
7106 false);
7107 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7108 "handover any to arfcn 123 bsic 45",
7109 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007110 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007111}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007112testcase TC_ho_neighbor_config_4() runs on test_CT {
7113 var MSC_ConnHdlr vc_conn;
7114 f_init(3, true, guard_timeout := 50.0);
7115 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007116 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007117 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7118 vc_conn.done;
7119
7120 /* f_tc_ho_neighbor_config_start() */
7121 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7122 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7123
7124 /* 4.a */
7125 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7126 f_ctrs_bsc_and_bts_add(0, "handover:error");
7127
7128 /* 4.b */
7129 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7130 f_ctrs_bsc_and_bts_add(0, "handover:error");
7131
7132 /* 4.c */
7133 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7134 * handover quickly by timing out after the Handover Required message */
7135 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7136 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7137 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7138 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7139
7140 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007141 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007142}
7143
Neels Hofmeyr91401012019-07-11 00:42:35 +02007144private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7145 f_tc_ho_neighbor_config_start();
7146
7147 /*
7148 * bts 0 ARFCN 871 BSIC 10
7149 * bts 1 ARFCN 871 BSIC 11
7150 * bts 2 ARFCN 871 BSIC 12
7151 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7152 */
7153
7154 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 +02007155 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007156 f_sleep(0.5);
7157
7158 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7159 "handover any to arfcn 871 bsic 12",
7160 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007161 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007162}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007163testcase TC_ho_neighbor_config_5() runs on test_CT {
7164 var MSC_ConnHdlr vc_conn;
7165 f_init(3, true);
7166 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007167 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007168 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7169 vc_conn.done;
7170
7171 /* f_tc_ho_neighbor_config_start() */
7172 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7173 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7174
7175 /* 5 */
7176 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7177 * handover quickly by timing out after the Handover Required message */
7178 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7179 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7180 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7181 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7182
7183 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007184 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007185}
7186
Neels Hofmeyr91401012019-07-11 00:42:35 +02007187private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7188 f_tc_ho_neighbor_config_start();
7189
7190 /*
7191 * bts 0 ARFCN 871 BSIC 10
7192 * bts 1 ARFCN 871 BSIC 11
7193 * bts 2 ARFCN 871 BSIC 12
7194 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7195 */
7196
7197 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7198 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007199 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007200 f_sleep(0.5);
7201
7202 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7203 "handover any to arfcn 871 bsic 12",
7204 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007205 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007206}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007207testcase TC_ho_neighbor_config_6() runs on test_CT {
7208 var MSC_ConnHdlr vc_conn;
7209 f_init(3, true);
7210 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007211 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007212 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7213 vc_conn.done;
7214
7215 /* f_tc_ho_neighbor_config_start() */
7216 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7217 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7218
7219 /* 6.a */
7220 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7221 * handover quickly by timing out after the Handover Required message */
7222 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7223 f_ctrs_bsc_and_bts_add(0, "handover:error");
7224
7225 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007226 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007227}
7228
Neels Hofmeyr91401012019-07-11 00:42:35 +02007229private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7230 f_tc_ho_neighbor_config_start();
7231
7232 /*
7233 * bts 0 ARFCN 871 BSIC 10
7234 * bts 1 ARFCN 871 BSIC 11
7235 * bts 2 ARFCN 871 BSIC 12
7236 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7237 */
7238
7239 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7240 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007241 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007242 f_sleep(0.5);
7243
7244 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7245 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007246 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007247 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7248 "handover any to arfcn 123 bsic 45",
7249 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007250 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007251}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007252testcase TC_ho_neighbor_config_7() runs on test_CT {
7253 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007254 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007255 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007256 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007257 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7258 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007259
7260 /* f_tc_ho_neighbor_config_start() */
7261 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7262 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7263
7264 /* 7.a */
7265 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7266 * handover quickly by sending a Handover Failure message. */
7267 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7268 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7269 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7270 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007271 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7272 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007273
7274 /* 7.b */
7275 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7276 * handover quickly by timing out after the Handover Required message */
7277 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7278 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7279 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7280 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7281
7282 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007283 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007284}
7285
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007286/* OS#3041: Open and close N connections in a normal fashion, and expect no
7287 * BSSMAP Reset just because of that. */
7288testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7289 var default d;
7290 var integer i;
7291 var DchanTuple dt;
7292
7293 f_init();
7294
7295 /* Wait for initial BSSMAP Reset to pass */
7296 f_sleep(4.0);
7297
7298 d := activate(no_bssmap_reset());
7299
7300 /* Setup up a number of connections and RLSD them again from the MSC
7301 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7302 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007303 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007304 /* Since we're doing a lot of runs, give each one a fresh
7305 * T_guard from the top. */
7306 T_guard.start;
7307
7308 /* Setup a BSSAP connection and clear it right away. This is
7309 * the MSC telling the BSC about a planned release, it's not an
7310 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007311 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007312
7313 /* MSC disconnects (RLSD). */
7314 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7315 }
7316
7317 /* In the buggy behavior, a timeout of 2 seconds happens between above
7318 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7319 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7320 f_sleep(4.0);
7321
7322 deactivate(d);
7323 f_shutdown_helper();
7324}
Harald Welte552620d2017-12-16 23:21:36 +01007325
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007326/* OS#3041: Open and close N connections in a normal fashion, and expect no
7327 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7328 * the MSC. */
7329testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7330 var default d;
7331 var integer i;
7332 var DchanTuple dt;
7333 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007334 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7335 var BssmapCause cause := enum2int(cause_val);
7336
7337 f_init();
7338
7339 /* Wait for initial BSSMAP Reset to pass */
7340 f_sleep(4.0);
7341
7342 d := activate(no_bssmap_reset());
7343
7344 /* Setup up a number of connections and RLSD them again from the MSC
7345 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7346 * Let's do it some more times for good measure. */
7347 for (i := 0; i < 8; i := i+1) {
7348 /* Since we're doing a lot of runs, give each one a fresh
7349 * T_guard from the top. */
7350 T_guard.start;
7351
7352 /* Setup a BSSAP connection and clear it right away. This is
7353 * the MSC telling the BSC about a planned release, it's not an
7354 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007355 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007356
7357 /* Instruct BSC to clear channel */
7358 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7359
7360 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007361 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007362 }
7363
7364 /* In the buggy behavior, a timeout of 2 seconds happens between above
7365 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7366 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7367 f_sleep(4.0);
7368
7369 deactivate(d);
7370 f_shutdown_helper();
7371}
7372
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007373/* OS#3041: Open and close N connections in a normal fashion, and expect no
7374 * BSSMAP Reset just because of that. Close connections from the MS side with a
7375 * Release Ind on RSL. */
7376testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7377 var default d;
7378 var integer i;
7379 var DchanTuple dt;
7380 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007381 var integer j;
7382
7383 f_init();
7384
7385 /* Wait for initial BSSMAP Reset to pass */
7386 f_sleep(4.0);
7387
7388 d := activate(no_bssmap_reset());
7389
7390 /* Setup up a number of connections and RLSD them again from the MSC
7391 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7392 * Let's do it some more times for good measure. */
7393 for (i := 0; i < 8; i := i+1) {
7394 /* Since we're doing a lot of runs, give each one a fresh
7395 * T_guard from the top. */
7396 T_guard.start;
7397
7398 /* Setup a BSSAP connection and clear it right away. This is
7399 * the MSC telling the BSC about a planned release, it's not an
7400 * erratic loss of a connection. */
7401 dt := f_est_dchan('23'O, 23, '00010203040506'O);
7402
7403 /* simulate RLL REL IND */
7404 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
7405
7406 /* expect Clear Request on MSC side */
7407 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7408
7409 /* Instruct BSC to clear channel */
7410 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7411 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7412
7413 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007414 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007415 }
7416
7417 /* In the buggy behavior, a timeout of 2 seconds happens between above
7418 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7419 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7420 f_sleep(4.0);
7421
7422 deactivate(d);
7423 f_shutdown_helper();
7424}
7425
Harald Welte94e0c342018-04-07 11:33:23 +02007426/***********************************************************************
7427 * IPA style dynamic PDCH
7428 ***********************************************************************/
7429
7430private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7431 template (omit) RSL_Cause nack := omit)
7432runs on test_CT {
7433 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7434 var RSL_Message rsl_unused;
7435 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7436 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7437 /* expect the BSC to issue the related RSL command */
7438 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7439 if (istemplatekind(nack, "omit")) {
7440 /* respond with a related acknowledgement */
7441 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7442 } else {
7443 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
7444 }
7445}
7446
7447private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7448 template (omit) RSL_Cause nack := omit)
7449runs on test_CT {
7450 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7451 var RSL_Message rsl_unused;
7452 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7453 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7454 /* expect the BSC to issue the related RSL command */
7455 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
7456 if (istemplatekind(nack, "omit")) {
7457 /* respond with a related acknowledgement */
7458 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
7459 } else {
7460 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
7461 }
7462}
7463
7464private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7465runs on test_CT return charstring {
7466 var charstring cmd, resp;
7467 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007468 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007469}
7470
7471private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7472 template charstring exp)
7473runs on test_CT {
7474 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7475 if (not match(mode, exp)) {
7476 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007477 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007478 }
7479}
7480
7481private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7482runs on test_CT {
7483 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7484 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7485 f_vty_transceive(BSCVTY, "end");
7486}
7487
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007488
7489private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7490 var integer i;
7491 for (i := 0; i < 8; i := i + 1) {
7492 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7493 }
7494}
7495
Harald Welte94e0c342018-04-07 11:33:23 +02007496private const charstring TCHF_MODE := "TCH/F mode";
7497private const charstring TCHH_MODE := "TCH/H mode";
7498private const charstring PDCH_MODE := "PDCH mode";
7499private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007500private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007501
7502/* Test IPA PDCH activation / deactivation triggered by VTY */
7503testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7504 var RSL_Message rsl_unused;
7505
7506 /* change Timeslot 6 before f_init() starts RSL */
7507 f_init_vty();
7508 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7509 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7510
7511 f_init(1, false);
7512 f_sleep(1.0);
7513
7514 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7515
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007516 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007517 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7518 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7519 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7520 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7521 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007522 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007523 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7524
7525 /* De-activate it via VTY */
7526 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7527 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007528 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007529 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7530
7531 /* re-activate it via VTY */
7532 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7533 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007534 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007535 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7536
7537 /* and finally de-activate it again */
7538 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7539 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007540 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007541 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7542
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007543 /* clean up config */
7544 f_ts_set_chcomb(0, 0, 6, "PDCH");
7545
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007546 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007547}
7548
7549/* Test IPA PDCH activation NACK */
7550testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7551 var RSL_Message rsl_unused;
7552
7553 /* change Timeslot 6 before f_init() starts RSL */
7554 f_init_vty();
7555 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7556 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7557
7558 f_init(1, false);
7559 f_sleep(1.0);
7560
7561 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7562
7563 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7564 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7565 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7566 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7567 f_sleep(1.0);
7568 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7569
7570 /* De-activate it via VTY */
7571 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7572 f_sleep(1.0);
7573 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7574
7575 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7576 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7577 f_sleep(1.0);
7578 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7579
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007580 /* clean up config */
7581 f_ts_set_chcomb(0, 0, 6, "PDCH");
7582
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007583 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007584}
7585
7586
7587/***********************************************************************
7588 * Osmocom style dynamic PDCH
7589 ***********************************************************************/
7590
7591private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7592 template (omit) RSL_Cause nack := omit)
7593runs on test_CT {
7594 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7595 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007596 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007597 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7598 /* expect the BSC to issue the related RSL command */
7599 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7600 if (istemplatekind(nack, "omit")) {
7601 /* respond with a related acknowledgement */
7602 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7603 } else {
7604 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7605 }
7606}
7607
7608private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7609 template (omit) RSL_Cause nack := omit)
7610runs on test_CT {
7611 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7612 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007613 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007614 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7615 /* expect the BSC to issue the related RSL command */
7616 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7617 if (istemplatekind(nack, "omit")) {
7618 /* respond with a related acknowledgement */
7619 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7620 } else {
7621 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7622 }
7623}
7624
7625/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7626testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7627 var RSL_Message rsl_unused;
7628
7629 /* change Timeslot 6 before f_init() starts RSL */
7630 f_init_vty();
7631 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7632 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7633
7634 f_init(1, false);
7635 f_sleep(1.0);
7636
7637 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7638
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007639 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007640 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7641 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007642 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007643
7644 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7645 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007646 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 +02007647 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7648
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007649 /* clean up config */
7650 f_ts_set_chcomb(0, 0, 6, "PDCH");
7651
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007652 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007653}
7654
7655/* Test Osmocom dyn PDCH activation NACK behavior */
7656testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7657 var RSL_Message rsl_unused;
7658
7659 /* change Timeslot 6 before f_init() starts RSL */
7660 f_init_vty();
7661 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7662 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7663
7664 f_init(1, false);
7665 f_sleep(1.0);
7666
7667 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7668
7669 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7670 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007671 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007672
7673 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7674 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7675 f_sleep(1.0);
7676 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7677
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007678 /* clean up config */
7679 f_ts_set_chcomb(0, 0, 6, "PDCH");
7680
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007681 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007682}
7683
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007684/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7685testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7686 var RSL_Message rsl_unused, rsl_msg;
7687 var DchanTuple dt;
7688 var BSSAP_N_CONNECT_ind rx_c_ind;
7689
7690 /* change Timeslot 6 before f_init() starts RSL */
7691 f_init_vty();
7692 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7693 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7694
7695 f_init(1, false);
7696 f_sleep(1.0);
7697
7698 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7699
7700 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7701 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7702 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007703 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007704
7705 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7706 f_sleep(1.0);
7707 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7708 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7709
7710 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7711 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007712 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007713 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007714 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007715 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007716 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007717 }
7718
7719 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7720 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7721 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7722 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7723
7724 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7725 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7726
7727 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7728 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7729 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7730 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7731
7732 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7733 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7734 dt.sccp_conn_id := rx_c_ind.connectionId;
7735 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7736
7737 /* Instruct BSC to clear channel */
7738 var BssmapCause cause := 0;
7739 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7740 f_exp_chan_rel_and_clear(dt, 0);
7741
7742 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007743 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007744 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7745 f_sleep(1.0);
7746 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7747
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007748 /* Clean up SDCCH lchans */
7749 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
7750 f_perform_clear_test_ct(sdcch_cleanup[i]);
7751 }
7752
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007753 /* clean up config */
7754 f_ts_set_chcomb(0, 0, 6, "PDCH");
7755
7756 f_shutdown_helper();
7757}
7758
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007759/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7760testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7761 var ASP_RSL_Unitdata rsl_ud;
7762 var integer i;
7763 var integer chreq_total, chreq_nochan;
7764
7765 f_init_vty();
7766 for (i := 1; i < 8; i := i + 1) {
7767 if (i == 2) {
7768 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7769 } else {
7770 f_ts_set_chcomb(0, 0, i, "PDCH");
7771 }
7772 }
7773 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7774
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007775 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007776
7777 /* The dyn TS want to activate PDCH mode, ACK that. */
7778 var RslChannelNr chan_nr;
7779 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007780 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007781 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7782
7783 f_sleep(1.0);
7784
7785 /* Exhaust all dedicated SDCCH lchans.
7786 /* GSM 44.018 Table 9.1.8.2:
7787 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7788 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007789 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007790 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007791 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007792 }
7793
7794 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007795 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007796 /* Also occupy the seven other SDCCH of the dyn TS */
7797 for (i := 0; i < 7; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007798 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
7799 }
7800
7801 /* Clean up SDCCH lchans */
7802 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7803 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007804 }
7805
7806 /* clean up config */
7807 f_ts_reset_chcomb(0);
7808
7809 f_shutdown_helper();
7810}
7811
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007812/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7813 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7814 it as TCH directly instead. SYS#5309. */
7815testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7816 var RSL_Message rsl_unused, rsl_msg;
7817 var DchanTuple dt;
7818 var BSSAP_N_CONNECT_ind rx_c_ind;
7819 var integer i;
7820
7821 /* change Timeslot 6 before f_init() starts RSL */
7822 f_init_vty();
7823 for (i := 1; i < 8; i := i + 1) {
7824 if (i == 6) {
7825 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7826 } else {
7827 f_ts_set_chcomb(0, 0, i, "PDCH");
7828 }
7829 }
7830 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7831
7832 f_init(1, false);
7833 f_sleep(1.0);
7834
7835 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7836
7837 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7838 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7839 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007840 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007841
7842 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7843 f_sleep(1.0);
7844 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7845 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7846
7847 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7848 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007849 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007850 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007851 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007852 dt := f_est_dchan(ra, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007853 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007854 }
7855
7856 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007857 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007858 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7859 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7860
7861 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7862 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7863
7864 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7865 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7866 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7867 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7868
7869 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7870 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7871 dt.sccp_conn_id := rx_c_ind.connectionId;
7872 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7873
7874 /* Instruct BSC to clear channel */
7875 var BssmapCause cause := 0;
7876 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7877 f_exp_chan_rel_and_clear(dt, 0);
7878
7879 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007880 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007881 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7882 f_sleep(1.0);
7883 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7884
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007885 /* Clean up SDCCH lchans */
7886 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7887 f_perform_clear_test_ct(chan_cleanup[i]);
7888 }
7889
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007890 /* clean up config */
7891 f_ts_reset_chcomb(0);
7892 /* TODO: clean up other channels? */
7893
7894 f_shutdown_helper();
7895}
7896
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007897/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7898testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7899 var RSL_Message rsl_unused, rsl_msg;
7900 var DchanTuple dt;
7901 var BSSAP_N_CONNECT_ind rx_c_ind;
7902 var GsmRrMessage rr;
7903
7904 /* change Timeslot 6 before f_init() starts RSL */
7905 f_init_vty();
7906 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7907 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7908
7909 f_init(1, false);
7910 f_sleep(1.0);
7911
7912 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7913
7914 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7915 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7916 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007917 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007918
7919 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7920 f_sleep(1.0);
7921 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7922 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7923
7924 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7925 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007926 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007927 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007928 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007929 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007930 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007931 }
7932
7933 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7934 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7935 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7936 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7937
7938 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7939 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7940
7941 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7942 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7943 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7944 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7945 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7946 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7947 }
7948
7949 /* FIXME? Currently the TS stays in state BORKEN: */
7950
7951 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007952 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007953 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7954 * f_sleep(1.0);
7955 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7956 */
7957
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007958 /* Clean up SDCCH lchans */
7959 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7960 f_perform_clear_test_ct(chan_cleanup[i]);
7961 }
7962
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007963 /* clean up config */
7964 f_ts_set_chcomb(0, 0, 6, "PDCH");
7965
7966 f_shutdown_helper();
7967}
7968
Stefan Sperling0796a822018-10-05 13:01:39 +02007969testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007970 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007971 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7972 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7973 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007974 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007975}
7976
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007977testcase TC_chopped_ipa_payload() runs on test_CT {
7978 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7979 /* TODO: mp_bsc_ctrl_port does not work yet */};
7980 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7981 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7982 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007983 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007984}
7985
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007986/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7987 the BTS does autonomous MS power control loop */
7988testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7989 var MSC_ConnHdlr vc_conn;
7990 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7991 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7992 pars.exp_ms_power_params := true;
7993
7994 f_init(1, true);
7995 f_sleep(1.0);
7996 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7997 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007998 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007999}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008000
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008001/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8002testcase TC_c0_power_red_mode() runs on test_CT {
8003 f_init(1);
8004
8005 for (var integer red := 6; red >= 0; red := red - 2) {
8006 /* Configure BCCH carrier power reduction mode via the VTY */
8007 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8008
8009 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008010 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008011 chan_nr := t_RslChanNr_BCCH(0),
8012 bs_power := tr_RSL_IE_BS_Power(red / 2));
8013 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
8014 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
8015
8016 /* Additionally verify the applied value over the CTRL interface */
8017 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8018 if (cred != int2str(red)) {
8019 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8020 cred, " (expected ", red, ")");
8021 }
8022 }
8023
8024 f_shutdown_helper();
8025}
8026
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008027/***********************************************************************
8028 * MSC Pooling
8029 ***********************************************************************/
8030
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008031template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008032 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 +02008033
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008034private 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 +02008035runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008036 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008037 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008038 f_logp(BSCVTY, "Got RSL RR Release");
8039 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008040 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008041 f_logp(BSCVTY, "Got RSL Deact SACCH");
8042 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008043 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008044 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008045 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8046 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008047 break;
8048 }
8049 }
8050}
8051
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008052private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8053 var MgcpCommand mgcp_cmd;
8054 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8055 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8056 repeat;
8057 }
8058}
8059
8060private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8061 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8062 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8063 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8064 repeat;
8065 }
8066}
8067
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008068friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8069 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008070runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008071 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8072 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008073 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008074 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8075 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008076 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008077 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008078 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008079 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008080 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008081 }
8082 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008083 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008084 /* Also drop the SCCP connection */
8085 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8086 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008087 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008088 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008089 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8090 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008091 }
8092 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008093 deactivate(ack_dlcx);
8094 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008095}
8096
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008097friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8098runs on MSC_ConnHdlr {
8099 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8100 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8101 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8102 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8103 interleave {
8104 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8105 f_logp(BSCVTY, "Got RSL Deact SACCH");
8106 }
8107 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8108 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8109 /* Also drop the SCCP connection */
8110 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8111 }
8112 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8113 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8114 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8115 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8116 }
8117 }
8118 deactivate(ack_dlcx);
8119 deactivate(ack_rel_req);
8120}
8121
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008122friend function f_perform_clear_no_lchan()
8123runs on MSC_ConnHdlr {
8124 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8125 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8126 BSSAP.receive(tr_BSSMAP_ClearComplete);
8127 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8128 /* Also drop the SCCP connection */
8129 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8130}
8131
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008132private function f_perform_clear_test_ct(DchanTuple dt)
8133 runs on test_CT
8134{
8135 /* Instruct BSC to clear channel */
8136 var BssmapCause cause := 0;
8137 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
8138 f_exp_chan_rel_and_clear(dt, 0);
8139}
8140
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008141private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8142 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008143runs on MSC_ConnHdlr {
8144 timer T := 10.0;
8145 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8146
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008147 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008148 f_create_bssmap_exp(l3_enc);
8149
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008150 /* RSL_Emulation.f_chan_est() on rsl_pt:
8151 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008152 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8153 */
8154 var RSL_Message rx_rsl;
8155 var GsmRrMessage rr;
8156
8157 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008158 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008159 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008160 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008161 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8162 */
8163 timer Tt := 10.0;
8164
8165 /* request a channel to be established */
8166 Tt.start;
8167 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008168 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008169 Tt.stop;
8170 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008171 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008172 setverdict(fail, "Unexpected RSL message on DCHAN");
8173 mtc.stop;
8174 }
8175 [] Tt.timeout {
8176 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8177 mtc.stop;
8178 }
8179 }
8180 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8181 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008182 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008183
8184
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008185 if (expect_bssmap_l3) {
8186 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8187 var template PDU_BSSAP exp_l3_compl;
8188 exp_l3_compl := tr_BSSMAP_ComplL3()
8189 if (g_pars.aoip == false) {
8190 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8191 } else {
8192 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8193 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008194
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008195 var PDU_BSSAP bssap;
8196 T.start;
8197 alt {
8198 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8199 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8200 log("rx exp_l3_compl = ", bssap);
8201 }
8202 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8203 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8204 }
8205 [] T.timeout {
8206 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8207 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008208 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008209
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008210 /* start ciphering, if requested */
8211 if (ispresent(g_pars.encr)) {
8212 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008213 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008214 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008215 }
8216
8217 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008218 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008219 }
8220 setverdict(pass);
8221 f_sleep(1.0);
8222}
8223
8224private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8225 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8226 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008227 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008228 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008229 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008230 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008231 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008232 }
8233}
8234
8235/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8236private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8237 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008238 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8239 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8240 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8241 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 +02008242}
8243testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8244
8245 f_init(1, true);
8246 f_sleep(1.0);
8247 var MSC_ConnHdlr vc_conn;
8248 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008249
8250 f_ctrs_msc_init();
8251
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008252 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8253 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008254
8255 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008256 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008257}
8258
8259/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8260/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8261 * just as well using only RSL. */
8262testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8263
8264 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8265 f_sleep(1.0);
8266
8267 /* Control which MSC gets chosen next by the round-robin, otherwise
8268 * would be randomly affected by which other tests ran before this. */
8269 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8270
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008271 f_ctrs_msc_init();
8272
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008273 var MSC_ConnHdlr vc_conn1;
8274 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8275 pars1.mscpool.rsl_idx := 0;
8276 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8277 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8278 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008279 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008280
8281 var MSC_ConnHdlr vc_conn2;
8282 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8283 pars2.mscpool.rsl_idx := 1;
8284 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8285 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8286 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008287 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008288
8289 /* Test round-robin wrap to the first MSC */
8290 var MSC_ConnHdlr vc_conn3;
8291 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8292 pars3.mscpool.rsl_idx := 2;
8293 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8294 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8295 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008296 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008297 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008298}
8299
8300/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8301 * (configured in osmo-bsc.cfg). */
8302/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8303 * just as well using only RSL. */
8304testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8305
8306 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8307 f_sleep(1.0);
8308
8309 /* Control which MSC gets chosen next by the round-robin, otherwise
8310 * would be randomly affected by which other tests ran before this. */
8311 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8312
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008313 f_ctrs_msc_init();
8314
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008315 var MSC_ConnHdlr vc_conn1;
8316 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8317 pars1.mscpool.rsl_idx := 0;
8318 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8319 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8320 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008321 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008322
8323 var MSC_ConnHdlr vc_conn2;
8324 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8325 pars2.mscpool.rsl_idx := 1;
8326 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8327 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8328 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008329 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008330
8331 /* Test round-robin wrap to the first MSC */
8332 var MSC_ConnHdlr vc_conn3;
8333 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8334 pars3.mscpool.rsl_idx := 2;
8335 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8336 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8337 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008338 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008339 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008340}
8341
8342/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8343 * (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
8344 * NULL-NRI setting is stronger than that. */
8345/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8346 * just as well using only RSL. */
8347testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8348
8349 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8350 f_sleep(1.0);
8351
8352 /* Control which MSC gets chosen next by the round-robin, otherwise
8353 * would be randomly affected by which other tests ran before this. */
8354 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8355
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008356 f_ctrs_msc_init();
8357
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008358 var MSC_ConnHdlr vc_conn1;
8359 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8360 pars1.mscpool.rsl_idx := 0;
8361 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8362 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8363 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008364 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008365
8366 var MSC_ConnHdlr vc_conn2;
8367 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8368 pars2.mscpool.rsl_idx := 1;
8369 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8370 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8371 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008372 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008373
8374 /* Test round-robin wrap to the first MSC */
8375 var MSC_ConnHdlr vc_conn3;
8376 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8377 pars3.mscpool.rsl_idx := 2;
8378 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8379 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8380 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008381 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008382 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008383}
8384
8385/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8386 * assigned to any MSC (configured in osmo-bsc.cfg). */
8387/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8388 * just as well using only RSL. */
8389testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8390
8391 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8392 f_sleep(1.0);
8393
8394 /* Control which MSC gets chosen next by the round-robin, otherwise
8395 * would be randomly affected by which other tests ran before this. */
8396 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8397
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008398 f_ctrs_msc_init();
8399
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008400 var MSC_ConnHdlr vc_conn1;
8401 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8402 pars1.mscpool.rsl_idx := 0;
8403 /* An NRI that is not assigned to any MSC */
8404 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8405 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8406 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008407 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008408
8409 var MSC_ConnHdlr vc_conn2;
8410 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8411 pars2.mscpool.rsl_idx := 1;
8412 /* An NRI that is not assigned to any MSC */
8413 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8414 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8415 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008416 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008417
8418 /* Test round-robin wrap to the first MSC */
8419 var MSC_ConnHdlr vc_conn3;
8420 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8421 pars3.mscpool.rsl_idx := 2;
8422 /* An NRI that is not assigned to any MSC */
8423 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8424 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8425 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008426 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008427 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008428}
8429
8430/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8431 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8432/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8433 * just as well using only RSL. */
8434testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8435
8436 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8437 f_sleep(1.0);
8438
8439 /* Control which MSC gets chosen next by the round-robin, otherwise
8440 * would be randomly affected by which other tests ran before this. */
8441 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8442
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008443 f_ctrs_msc_init();
8444
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008445 var MSC_ConnHdlr vc_conn1;
8446 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8447 pars1.mscpool.rsl_idx := 0;
8448 /* An NRI that is assigned to an unconnected MSC */
8449 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8450 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8451 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008452 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8453 f_ctrs_msc_add(0, "mscpool:subscr:new");
8454 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008455
8456 var MSC_ConnHdlr vc_conn2;
8457 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8458 pars2.mscpool.rsl_idx := 1;
8459 /* An NRI that is assigned to an unconnected MSC */
8460 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8461 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8462 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008463 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8464 f_ctrs_msc_add(1, "mscpool:subscr:new");
8465 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008466
8467 /* Test round-robin wrap to the first MSC */
8468 var MSC_ConnHdlr vc_conn3;
8469 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8470 pars3.mscpool.rsl_idx := 2;
8471 /* An NRI that is assigned to an unconnected MSC */
8472 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8473 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8474 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008475 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8476 f_ctrs_msc_add(0, "mscpool:subscr:new");
8477 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008478 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008479}
8480
8481/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8482 * osmo-bsc.cfg). */
8483/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8484 * just as well using only RSL. */
8485testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8486
8487 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8488 f_sleep(1.0);
8489
8490 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8491 * this is not using round-robin. */
8492 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8493
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008494 f_ctrs_msc_init();
8495
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008496 var MSC_ConnHdlr vc_conn1;
8497 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8498 pars1.mscpool.rsl_idx := 0;
8499 /* An NRI of the second MSC's range (256-511) */
8500 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8501 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8502 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008503 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008504
8505 var MSC_ConnHdlr vc_conn2;
8506 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8507 pars2.mscpool.rsl_idx := 1;
8508 /* An NRI of the second MSC's range (256-511) */
8509 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8510 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8511 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008512 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008513
8514 var MSC_ConnHdlr vc_conn3;
8515 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8516 pars3.mscpool.rsl_idx := 2;
8517 /* An NRI of the second MSC's range (256-511) */
8518 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8519 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8520 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008521 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008522 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008523}
8524
8525/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8526 * while a round-robin remains unaffected by that. */
8527/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8528 * just as well using only RSL. */
8529testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8530
8531 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8532 f_sleep(1.0);
8533
8534 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8535 * this is not using round-robin. */
8536 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8537
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008538 f_ctrs_msc_init();
8539
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008540 var MSC_ConnHdlr vc_conn1;
8541 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8542 pars1.mscpool.rsl_idx := 0;
8543 /* An NRI of the third MSC's range (512-767) */
8544 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8545 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8546 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008547 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008548
8549 var MSC_ConnHdlr vc_conn2;
8550 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8551 pars2.mscpool.rsl_idx := 1;
8552 /* An NRI of the third MSC's range (512-767) */
8553 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8554 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8555 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008556 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008557
8558 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8559 var MSC_ConnHdlr vc_conn3;
8560 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8561 pars3.mscpool.rsl_idx := 2;
8562 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8563 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8564 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008565 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008566 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008567}
8568
8569/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8570/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8571 * just as well using only RSL. */
8572testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8573
8574 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8575 f_sleep(1.0);
8576
8577 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8578 * instead, and hits msc 0. */
8579 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8580
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008581 f_ctrs_msc_init();
8582
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008583 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8584 var MSC_ConnHdlr vc_conn1;
8585 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8586 pars1.mscpool.rsl_idx := 0;
8587 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8588 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8589 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008590 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008591
8592 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8593 var MSC_ConnHdlr vc_conn2;
8594 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8595 pars2.mscpool.rsl_idx := 1;
8596 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8597 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8598 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008599 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008600 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008601}
8602
8603/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8604 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8605private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8606 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8607 //cid_list := { cIl_allInBSS := ''O };
8608 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8609 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8610 var BSSAP_N_UNITDATA_req paging;
8611 var hexstring imsi := '001010000000123'H;
8612
8613 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8614
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008615 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008616 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8617 BSSAP.send(paging);
8618
8619 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8620 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8621 * channel number is picked here. */
8622 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8623 f_rslem_register(0, new_chan_nr);
8624 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8625 f_rslem_unregister(0, new_chan_nr);
8626
8627 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8628 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008629 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008630 f_sleep(1.0);
8631}
8632testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8633 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8634 f_sleep(1.0);
8635
8636 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8637 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8638 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8639
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008640 f_ctrs_msc_init();
8641
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008642 var MSC_ConnHdlr vc_conn1;
8643 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8644 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008645 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8646 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008647 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8648 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008649 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008650 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008651}
8652
8653/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8654 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8655private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8656 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8657 //cid_list := { cIl_allInBSS := ''O };
8658 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8659 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8660 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008661 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008662 var BSSAP_N_UNITDATA_req paging;
8663
8664 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8665
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008666 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008667 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8668 BSSAP.send(paging);
8669
8670 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8671 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8672 * channel number is picked here. */
8673 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8674 f_rslem_register(0, new_chan_nr);
8675 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8676 f_rslem_unregister(0, new_chan_nr);
8677
8678 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8679 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8680 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008681 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 +02008682 f_sleep(1.0);
8683}
8684testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8685 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8686 f_sleep(1.0);
8687
8688 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8689 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8690 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8691
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008692 f_ctrs_msc_init();
8693
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008694 var MSC_ConnHdlr vc_conn1;
8695 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8696 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008697 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8698 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008699 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8700 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008701 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008702 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008703}
8704
8705/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8706/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8707 * just as well using only RSL. */
8708testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8709
8710 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8711 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008712 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8713 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008714
8715 /* Control which MSC gets chosen next by the round-robin, otherwise
8716 * would be randomly affected by which other tests ran before this. */
8717 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8718
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008719 f_ctrs_msc_init();
8720
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008721 var MSC_ConnHdlr vc_conn1;
8722 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8723 pars1.mscpool.rsl_idx := 0;
8724 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8725 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8726 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008727 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008728
8729 var MSC_ConnHdlr vc_conn2;
8730 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8731 pars2.mscpool.rsl_idx := 1;
8732 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8733 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8734 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008735 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008736
8737 var MSC_ConnHdlr vc_conn3;
8738 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8739 pars3.mscpool.rsl_idx := 2;
8740 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8741 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8742 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008743 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008744 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008745}
8746
8747/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8748 * TMSI NRI. */
8749testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8750
8751 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8752 f_sleep(1.0);
8753
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008754 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8755 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8756
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008757 /* Control which MSC gets chosen next by the round-robin, otherwise
8758 * would be randomly affected by which other tests ran before this. */
8759 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8760
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008761 f_ctrs_msc_init();
8762
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008763 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8764 var MSC_ConnHdlr vc_conn1;
8765 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8766 pars1.mscpool.rsl_idx := 0;
8767 /* An NRI of the second MSC's range (256-511) */
8768 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8769 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8770 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008771 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008772
8773 var MSC_ConnHdlr vc_conn2;
8774 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8775 pars2.mscpool.rsl_idx := 1;
8776 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8777 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8778 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008779 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008780
8781 var MSC_ConnHdlr vc_conn3;
8782 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8783 pars3.mscpool.rsl_idx := 2;
8784 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8785 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8786 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008787 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008788 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008789}
8790
Philipp Maier783681c2020-07-16 16:47:06 +02008791/* Allow/Deny emergency calls globally via VTY */
8792private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8793 f_vty_enter_cfg_msc(BSCVTY, 0);
8794 if (allow) {
8795 f_vty_transceive(BSCVTY, "allow-emergency allow");
8796 } else {
8797 f_vty_transceive(BSCVTY, "allow-emergency deny");
8798 }
8799 f_vty_transceive(BSCVTY, "exit");
8800 f_vty_transceive(BSCVTY, "exit");
8801}
8802
8803/* Allow/Deny emergency calls per BTS via VTY */
8804private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8805 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8806 if (allow) {
8807 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8808 } else {
8809 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8810 }
8811 f_vty_transceive(BSCVTY, "exit");
8812 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008813 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008814}
8815
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008816/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8817private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8818 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8819 if (allow) {
8820 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8821 } else {
8822 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8823 }
8824 f_vty_transceive(BSCVTY, "exit");
8825 f_vty_transceive(BSCVTY, "exit");
8826 f_vty_transceive(BSCVTY, "exit");
8827}
8828
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008829/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8830private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8831 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8832 if (allow) {
8833 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8834 } else {
8835 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8836 }
8837 f_vty_transceive(BSCVTY, "exit");
8838 f_vty_transceive(BSCVTY, "exit");
8839 f_vty_transceive(BSCVTY, "exit");
8840}
8841
Philipp Maier783681c2020-07-16 16:47:06 +02008842/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8843private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8844 var PDU_ML3_MS_NW emerg_setup;
8845 var octetstring emerg_setup_enc;
8846 var RSL_Message emerg_setup_data_ind;
8847
8848 f_establish_fully(omit, omit);
8849
8850 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8851 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8852 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8853
8854 RSL.send(emerg_setup_data_ind);
8855}
8856
8857/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8858 * CALLS are permitted by the BSC config. */
8859private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8860 var PDU_BSSAP emerg_setup_data_ind_bssap;
8861 var PDU_ML3_MS_NW emerg_setup;
8862 timer T := 3.0;
8863
8864 f_assignment_emerg_setup()
8865
8866 T.start;
8867 alt {
8868 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8869 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8870 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8871 setverdict(fail, "no emergency setup");
8872 }
8873 }
8874 [] BSSAP.receive {
8875 setverdict(fail, "unexpected BSSAP message!");
8876 }
8877 [] T.timeout {
8878 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8879 }
8880 }
8881
8882 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008883 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02008884}
8885
8886/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8887 * forbidden by the BSC config. */
8888private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8889 var PDU_BSSAP emerg_setup_data_ind_bssap;
8890 timer T := 3.0;
8891
8892 f_assignment_emerg_setup()
8893
8894 T.start;
8895 alt {
8896 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8897 setverdict(pass);
8898 }
8899 [] RSL.receive {
8900 setverdict(fail, "unexpected RSL message!");
8901 }
8902 [] T.timeout {
8903 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8904 }
8905 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008906 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008907 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02008908}
8909
8910/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8911testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8912 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8913 var MSC_ConnHdlr vc_conn;
8914
8915 f_init(1, true);
8916 f_sleep(1.0);
8917
8918 f_vty_allow_emerg_msc(true);
8919 f_vty_allow_emerg_bts(true, 0);
8920 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8921 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008922 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008923}
8924
8925/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8926testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8927 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8928 var MSC_ConnHdlr vc_conn;
8929
8930 f_init(1, true);
8931 f_sleep(1.0);
8932
8933 f_vty_allow_emerg_msc(false);
8934 f_vty_allow_emerg_bts(true, 0);
8935 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8936 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008937 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008938}
8939
8940/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8941testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8942 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8943 var MSC_ConnHdlr vc_conn;
8944
8945 /* Note: This simulates a spec violation by the MS, correct MS
8946 * implementations would not try to establish an emergency call because
8947 * the system information tells in advance that emergency calls are
8948 * not forbidden */
8949
8950 f_init(1, true);
8951 f_sleep(1.0);
8952
8953 f_vty_allow_emerg_msc(true);
8954 f_vty_allow_emerg_bts(false, 0);
8955 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8956 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008957 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008958}
8959
Philipp Maier82812002020-08-13 18:48:27 +02008960/* Test what happens when an emergency call arrives while all TCH channels are
8961 * busy, the BSC is expected to terminate one call in favor of the incoming
8962 * emergency call */
8963testcase TC_emerg_premption() runs on test_CT {
8964 var ASP_RSL_Unitdata rsl_ud;
8965 var integer i;
8966 var integer chreq_total, chreq_nochan;
8967 var RSL_Message rx_rsl;
8968 var RslChannelNr chan_nr;
8969
8970 f_init(1);
8971 f_sleep(1.0);
8972
8973 f_vty_allow_emerg_msc(true);
8974 f_vty_allow_emerg_bts(true, 0);
8975
8976 /* Fill up all channels on the BTS */
8977 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8978 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8979 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8980 chan_nr := f_chreq_act_ack('33'O, i);
8981 }
8982 IPA_RSL[0].clear;
8983 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8984 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8985
8986 /* Send Channel request for emegergency call */
8987 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8988
8989 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8990 chan_nr := valueof(t_RslChanNr_Bm(1));
8991 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8992
8993 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8994 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8995 chan_nr := rx_rsl.ies[0].body.chan_nr;
8996 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8997 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008998
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008999 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009000}
9001
9002/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009003private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009004private type record FHParamsTs {
9005 boolean enabled,
9006 uint6_t hsn,
9007 uint6_t maio,
9008 ArfcnList ma
9009};
9010
9011/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009012private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009013 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009014 FHParamsTs ts[8]
9015};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009016
9017/* Randomly generate the hopping parameters for the given timeslot numbers */
9018private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9019runs on test_CT return FHParamsTrx {
9020 var FHParamsTrx fhp;
9021
Philipp Maier798d8952021-10-19 14:43:19 +02009022 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9023 * fall in the GSM900 band. */
9024 fhp.arfcn.arfcn := f_rnd_int(3);
9025 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009026
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009027 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9028 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009029 fhp.ts[tn].enabled := false;
9030 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009031 continue;
9032 }
9033
9034 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009035 fhp.ts[tn].hsn := f_rnd_int(64);
9036 fhp.ts[tn].maio := f_rnd_int(64);
9037 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009038
9039 /* Random Mobile Allocation (hopping channels) */
9040 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9041 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9042 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009043 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009044 }
9045
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009046 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009047 }
9048
9049 log("f_TC_fh_params_gen(): ", fhp);
9050 return fhp;
9051}
9052
9053/* Make sure that the given Channel Description IE matches the hopping configuration */
9054private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9055{
9056 var template (present) ChannelDescription tr_cd;
9057 var template (present) MaioHsn tr_maio_hsn;
9058 var uint3_t tn := cd.chan_nr.tn;
9059
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009060 if (fhp.ts[tn].enabled) {
9061 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009062 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9063 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009064 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009065 }
9066
9067 if (not match(cd, tr_cd)) {
9068 setverdict(fail, "Channel Description IE does not match: ",
9069 cd, " vs expected ", tr_cd);
9070 }
9071}
9072
9073/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9074private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9075 in MobileAllocationLV ma)
9076{
9077 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9078
9079 if (not match(ma, tr_ma)) {
9080 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9081 tn, "): ", ma, " vs expected: ", tr_ma);
9082 } else {
9083 setverdict(pass);
9084 }
9085}
9086
9087private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9088 in MobileAllocationLV ma)
9089return template MobileAllocationLV {
9090 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009091 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009092 return { len := 0, ma := ''B };
9093 }
9094
9095 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9096 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9097 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009098
9099 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009100 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9101 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9102 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009103 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009104 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009105 }
9106 }
9107
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009108 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009109 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009110
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009111 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009112 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9113 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009114 }
9115
9116 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009117 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009118 if (full_mask[i] != '1'B)
9119 { continue; }
9120
9121 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9122 if (slot_mask[i] == '1'B) {
9123 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009124 } else {
9125 ma_mask := ma_mask & '0'B;
9126 }
9127 }
9128
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009129 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9130 if (full_mask[0] == '1'B) {
9131 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9132 if (slot_mask[0] == '1'B) {
9133 ma_mask := ma_mask & '1'B;
9134 } else {
9135 ma_mask := ma_mask & '0'B;
9136 }
9137 }
9138
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009139 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009140 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009141 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9142
9143 return { len := ma_mask_len, ma := ma_mask };
9144}
9145
Philipp Maier798d8952021-10-19 14:43:19 +02009146/* Configure the appropriate band for a given arfcn, exc */
9147private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9148{
9149 var charstring band;
9150 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9151
9152 select (arfcn_) {
9153 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9154 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9155 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9156 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9157 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9158 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9159 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9160 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9161 case else { return; }
9162 }
9163
9164 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9165 f_vty_transceive(BSCVTY, "band " & band);
9166 f_vty_transceive(BSCVTY, "end");
9167}
9168
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009169/* Configure the hopping parameters in accordance with the given record */
9170private function f_TC_fh_params_set(in FHParamsTrx fhp,
9171 uint8_t bts_nr := 0,
9172 uint8_t trx_nr := 0)
9173runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009174
9175 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9176
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009177 /* Enter the configuration node for the given BTS/TRX numbers */
9178 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9179
Philipp Maier798d8952021-10-19 14:43:19 +02009180 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009181
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009182 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009183 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9184
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009185 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009186 f_vty_transceive(BSCVTY, "hopping enabled 0");
9187 f_vty_transceive(BSCVTY, "exit"); /* go back */
9188 continue;
9189 }
9190
9191 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009192 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9193 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009194
9195 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009196 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9197 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009198 }
9199
9200 f_vty_transceive(BSCVTY, "hopping enabled 1");
9201 f_vty_transceive(BSCVTY, "exit"); /* go back */
9202 }
9203
9204 f_vty_transceive(BSCVTY, "end");
9205}
9206
9207/* Disable frequency hopping on all timeslots */
9208private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9209 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009210 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009211 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009212runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009213
9214 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9215
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009216 /* Enter the configuration node for the given BTS/TRX numbers */
9217 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9218
Philipp Maier798d8952021-10-19 14:43:19 +02009219 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009220
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009221 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009222 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9223
9224 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009225 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9226 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009227 }
9228
9229 f_vty_transceive(BSCVTY, "hopping enabled 0");
9230 f_vty_transceive(BSCVTY, "exit"); /* go back */
9231 }
9232
9233 f_vty_transceive(BSCVTY, "end");
9234 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9235}
9236
9237/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9238 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9239testcase TC_fh_params_chan_activ() runs on test_CT {
9240 var FHParamsTrx fhp := f_TC_fh_params_gen();
9241 var RSL_Message rsl_msg;
9242 var RSL_IE_Body ie;
9243
9244 f_init_vty();
9245
9246 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9247 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9248
9249 f_init(1);
9250
9251 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9252 for (var integer i := 0; i < 9; i := i + 1) {
9253 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9254 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9255
9256 /* Make sure that Channel Identification IE is present */
9257 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9258 setverdict(fail, "RSL Channel Identification IE is absent");
9259 continue;
9260 }
9261
9262 /* Make sure that hopping parameters (HSN/MAIO) match */
9263 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9264
9265 /* "Mobile Allocation shall be included but empty" - let's check this */
9266 if (ie.chan_ident.ma.v.len != 0) {
9267 setverdict(fail, "Mobile Allocation IE is not empty: ",
9268 ie.chan_ident.ma, ", despite it shall be");
9269 continue;
9270 }
9271 }
9272
9273 /* Disable frequency hopping */
9274 f_TC_fh_params_unset(fhp);
9275
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009276 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009277}
9278
9279/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9280testcase TC_fh_params_imm_ass() runs on test_CT {
9281 var FHParamsTrx fhp := f_TC_fh_params_gen();
9282 var RSL_Message rsl_msg;
9283 var RSL_IE_Body ie;
9284
9285 f_init_vty();
9286
9287 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9288 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9289
9290 f_init(1);
9291
9292 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9293 for (var integer i := 0; i < 9; i := i + 1) {
9294 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9295 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9296
9297 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9298 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
9299
9300 /* Make sure that Full Immediate Assign Info IE is present */
9301 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9302 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9303 continue;
9304 }
9305
9306 /* Decode the actual Immediate Assignment message */
9307 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9308 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9309 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9310 continue;
9311 }
9312
9313 /* Make sure that hopping parameters (HSN/MAIO) match */
9314 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9315
9316 /* Make sure that the Mobile Allocation IE matches */
9317 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9318 rr_msg.payload.imm_ass.mobile_allocation);
9319 }
9320
9321 /* Disable frequency hopping */
9322 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009323
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009324 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009325}
9326
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009327/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9328testcase TC_fh_params_assignment_cmd() runs on test_CT {
9329 var FHParamsTrx fhp := f_TC_fh_params_gen();
9330 var RSL_Message rsl_msg;
9331 var RSL_IE_Body ie;
9332
9333 f_init_vty();
9334
9335 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9336 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9337
9338 f_init(1);
9339
9340 /* HACK: work around "Couldn't find Expect for CRCX" */
9341 vc_MGCP.stop;
9342
9343 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9344 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9345
9346 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9347 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9348 for (var integer i := 0; i < 3; i := i + 1) {
9349 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
9350 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
9351
9352 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9353 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
9354 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9355
9356 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
9357 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9358 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9359
9360 /* Make sure that L3 Information IE is present */
9361 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9362 setverdict(fail, "RSL L3 Information IE is absent");
9363 continue;
9364 }
9365
9366 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9367 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9368 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9369 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9370 continue;
9371 }
9372
9373 /* Make sure that hopping parameters (HSN/MAIO) match */
9374 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9375 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9376
9377 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9378 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009379 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009380 continue;
9381 }
9382
9383 /* Make sure that the Mobile Allocation IE matches (if present) */
9384 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9385 if (chan_desc.h and ma_present) {
9386 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9387 l3_msg.payload.ass_cmd.mobile_allocation.v);
9388 } else if (chan_desc.h and not ma_present) {
9389 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9390 continue;
9391 } else if (not chan_desc.h and ma_present) {
9392 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9393 continue;
9394 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009395
9396 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009397 }
9398
9399 /* Give the IUT some time to release all channels */
9400 f_sleep(3.0);
9401
9402 /* Disable frequency hopping */
9403 f_TC_fh_params_unset(fhp);
9404
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009405 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009406}
9407
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009408/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9409private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9410runs on test_CT {
9411 var RSL_Message rsl_msg;
9412 var RSL_IE_Body ie;
9413 var DchanTuple dt;
9414
9415 /* Establish a dedicated channel, so we can trigger handover */
9416 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009417 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009418
9419 /* Trigger handover from BTS0 to BTS1 */
9420 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9421 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9422
9423 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
9424 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9425
9426 /* ACKnowledge channel activation and expect (RR) Handover Command */
9427 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9428 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9429
9430 /* Make sure that L3 Information IE is present */
9431 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9432 setverdict(fail, "RSL L3 Information IE is absent");
9433 return;
9434 }
9435
9436 /* Decode the L3 message and make sure it is (RR) Handover Command */
9437 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9438 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9439 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9440 return;
9441 }
9442
9443 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9444 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9445 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9446 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9447 return;
9448 }
9449
9450 /* Make sure that hopping parameters (HSN/MAIO) match */
9451 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9452
9453 /* Make sure that Cell Channel Description IE is present */
9454 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9455 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9456 return;
9457 }
9458
9459 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9460 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9461 if (ma_present) {
9462 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9463 l3_msg.payload.ho_cmd.mobile_allocation.v);
9464 } else {
9465 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9466 return;
9467 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009468
9469 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009470}
9471testcase TC_fh_params_handover_cmd() runs on test_CT {
9472 var FHParamsTrx fhp := f_TC_fh_params_gen();
9473
9474 f_init_vty();
9475
9476 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9477 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9478
9479 f_vty_transceive(BSCVTY, "timeslot 0");
9480 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9481 f_vty_transceive(BSCVTY, "exit"); /* go back */
9482
9483 f_vty_transceive(BSCVTY, "timeslot 1");
9484 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9485 f_vty_transceive(BSCVTY, "end"); /* we're done */
9486
9487 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9488 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9489
9490 f_init(2);
9491
9492 f_TC_fh_params_handover_cmd(fhp);
9493
9494 /* Disable frequency hopping on BTS1 */
9495 f_TC_fh_params_unset(fhp, 1);
9496
9497 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9498 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9499
9500 f_vty_transceive(BSCVTY, "timeslot 0");
9501 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9502 f_vty_transceive(BSCVTY, "exit"); /* go back */
9503
9504 f_vty_transceive(BSCVTY, "timeslot 1");
9505 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9506 f_vty_transceive(BSCVTY, "end"); /* we're done */
9507
9508 f_shutdown_helper();
9509}
9510
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009511/* Verify the hopping parameters in System Information Type 4 */
9512testcase TC_fh_params_si4_cbch() runs on test_CT {
9513 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9514 var ASP_RSL_Unitdata rx_rsl_ud;
9515 timer T := 5.0;
9516
9517 f_init_vty();
9518
9519 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9520 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9521
9522 f_vty_transceive(BSCVTY, "timeslot 0");
9523 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9524 f_vty_transceive(BSCVTY, "exit"); /* go back */
9525
9526 f_vty_transceive(BSCVTY, "timeslot 1");
9527 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9528 f_vty_transceive(BSCVTY, "end"); /* we're done */
9529
9530 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9531 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9532
9533 f_init(1);
9534
9535 T.start;
9536 alt {
9537 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
9538 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9539 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9540
9541 /* Make sure that what we decoded is System Information Type 4 */
9542 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9543 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9544 repeat;
9545 }
9546
9547 /* Make sure that CBCH Channel Description IE is present */
9548 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9549 setverdict(fail, "CBCH Channel Description IE is absent");
9550 break;
9551 }
9552
9553 /* Finally, check the hopping parameters (HSN, MAIO) */
9554 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9555 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9556
9557 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9558 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9559 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9560 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9561 break;
9562 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9563 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9564 si.payload.si4.cbch_mobile_alloc.v);
9565 }
9566 }
9567 [] IPA_RSL[0].receive { repeat; }
9568 [] T.timeout {
9569 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9570 }
9571 }
9572
9573 /* Disable frequency hopping */
9574 f_TC_fh_params_unset(fhp);
9575
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009576 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009577 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9578
9579 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009580 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009581 f_vty_transceive(BSCVTY, "exit"); /* go back */
9582
9583 f_vty_transceive(BSCVTY, "timeslot 1");
9584 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9585 f_vty_transceive(BSCVTY, "end"); /* we're done */
9586
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009587 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009588}
9589
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009590template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9591 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9592
9593private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9594 template (present) BSSLAP_PDU expect_bsslap)
9595{
9596 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9597 if (not match(bsslap, expect_bsslap)) {
9598 log("EXPECTING BSSLAP: ", expect_bsslap);
9599 log("GOT BSSLAP: ", bsslap);
9600 setverdict(fail, "BSSLAP is not as expected");
9601 mtc.stop;
9602 }
9603 setverdict(pass);
9604}
9605
9606/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9607const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9608
9609private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9610 var PDU_BSSAP_LE rx_bsslap;
9611 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9612 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9613}
9614
9615/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9616 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9617private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9618 f_sleep(1.0);
9619
9620 f_establish_fully(omit, omit);
9621 f_bssap_le_register_imsi(g_pars.imsi, omit);
9622
9623 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9624 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9625
9626 var PDU_BSSAP_LE plr;
9627 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9628
9629 if (not do_ta_request) {
9630 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9631 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9632 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9633 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9634 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9635 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9636 mtc.stop;
9637 }
9638 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9639 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9640 if (not match(bsslap, expect_ta_layer3)) {
9641 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9642 log("GOT BSSLAP: ", bsslap);
9643 setverdict(fail, "BSSLAP is not as expected");
9644 mtc.stop;
9645 }
9646 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9647 * has no need to request the TA from the BSC and directly responds. */
9648 } else {
9649 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9650 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9651 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9652 }
9653
9654 /* SMLC got the TA from the BSC, now responds with geo information data. */
9655 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9656 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9657 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9658
9659 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9660 f_mo_l3_transceive();
9661
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009662 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009663
9664 f_sleep(2.0);
9665 setverdict(pass);
9666}
9667
9668/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9669 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9670private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9671 f_lcs_loc_req_for_active_ms(false);
9672}
9673testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9674 var MSC_ConnHdlr vc_conn;
9675 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9676
9677 f_init(1, true);
9678 f_sleep(1.0);
9679 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9680 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009681 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009682}
9683
9684/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9685 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9686private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9687 f_lcs_loc_req_for_active_ms(true);
9688}
9689testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9690 var MSC_ConnHdlr vc_conn;
9691 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9692
9693 f_init(1, true);
9694 f_sleep(1.0);
9695 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9696 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009697 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009698}
9699
9700/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9701 * conn without an active lchan. */
9702private function f_clear_A_conn() runs on MSC_ConnHdlr
9703{
9704 var BssmapCause cause := 0;
9705 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9706 BSSAP.receive(tr_BSSMAP_ClearComplete);
9707 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9708
9709 timer no_more_bssap := 5.0;
9710 no_more_bssap.start;
9711 alt {
9712 [] no_more_bssap.timeout { break; }
9713 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9714 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9715 mtc.stop;
9716 }
9717 }
9718 setverdict(pass);
9719}
9720
9721/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9722 * for LCS, for cases where there is only an A conn without an active lchan. */
9723private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9724{
9725 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9726
9727 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9728 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9729 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9730 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9731 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9732 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9733
9734 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9735 f_clear_A_conn();
9736 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9737 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9738}
9739
9740/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9741 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9742 */
9743private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9744 f_sleep(1.0);
9745
9746 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9747 f_bssap_le_register_imsi(g_pars.imsi, omit);
9748
9749 /* Register to receive the Paging Command */
9750 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9751 g_chan_nr := new_chan_nr;
9752 f_rslem_register(0, g_chan_nr);
9753
9754 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9755 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9756 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9757 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9758
9759 var PDU_BSSAP_LE plr;
9760 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9761
9762 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9763 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9764
9765 /* OsmoBSC needs to Page */
9766 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9767 f_logp(BSCVTY, "got Paging Command");
9768
9769 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9770 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009771 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);
9772 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009773
9774 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9775
9776 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9777
9778 /* SMLC got the TA from the BSC, now responds with geo information data. */
9779 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9780 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9781
9782 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9783
9784 /* The lchan is gone, the A-interface conn was created for the LCS only.
9785 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9786 f_verify_active_A_conn_and_clear();
9787
9788 f_sleep(2.0);
9789 setverdict(pass);
9790}
9791testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9792 var MSC_ConnHdlr vc_conn;
9793 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9794
9795 f_init(1, true);
9796 f_sleep(1.0);
9797
9798 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9799 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9800
9801 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9802 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009803 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009804}
9805
9806/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9807 */
9808private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9809 f_sleep(1.0);
9810
9811 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9812 f_bssap_le_register_imsi(g_pars.imsi, omit);
9813
9814 /* provoke an abort by omitting both IMSI and IMEI */
9815 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9816 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9817 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9818 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9819
9820 /* BSC tells MSC about failure */
9821 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9822 locationEstimate := omit, positioningData := omit,
9823 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9824
9825 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9826 f_verify_active_A_conn_and_clear();
9827
9828 f_sleep(2.0);
9829 setverdict(pass);
9830}
9831testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9832 var MSC_ConnHdlr vc_conn;
9833 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9834
9835 f_init(1, true);
9836 f_sleep(1.0);
9837
9838 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9839 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9840
9841 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9842 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009843 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009844}
9845
9846/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9847 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9848private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9849 f_sleep(1.0);
9850
9851 f_establish_fully(omit, omit);
9852 f_bssap_le_register_imsi(g_pars.imsi, omit);
9853
9854 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9855 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9856
9857 var PDU_BSSAP_LE plr;
9858 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9859
9860 if (do_ta) {
9861 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9862 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9863 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9864 }
9865
9866 /* SMLC fails to respond, BSC runs into timeout */
9867 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9868 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9869
9870 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9871 locationEstimate := omit, positioningData := omit,
9872 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9873
9874 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9875 f_verify_active_A_conn_and_clear();
9876
9877 f_sleep(2.0);
9878 setverdict(pass);
9879}
9880
9881/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9882 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9883private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9884 f_lcs_loc_req_for_active_ms_le_timeout(false);
9885}
9886
9887testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9888 var MSC_ConnHdlr vc_conn;
9889 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9890
9891 f_init(1, true);
9892 f_sleep(1.0);
9893 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9894 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009895 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009896}
9897
9898/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9899 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9900private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9901 f_lcs_loc_req_for_active_ms_le_timeout(true);
9902}
9903
9904testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9905 var MSC_ConnHdlr vc_conn;
9906 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9907
9908 f_init(1, true);
9909 f_sleep(1.0);
9910 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9911 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009912 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009913}
9914
9915/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9916private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9917 f_sleep(1.0);
9918
9919 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9920 f_bssap_le_register_imsi(g_pars.imsi, omit);
9921
9922 /* Register to receive the Paging Command */
9923 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9924 g_chan_nr := new_chan_nr;
9925 f_rslem_register(0, g_chan_nr);
9926
9927 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9928 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9929 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9930 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9931
9932 var PDU_BSSAP_LE plr;
9933 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9934
9935 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9936 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9937
9938 /* OsmoBSC needs to Page */
9939 var PDU_BSSAP_LE rx_bsslap;
9940 alt {
9941 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9942 f_logp(BSCVTY, "got Paging Command");
9943 repeat;
9944 }
9945 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9946 /* MS does not respond to Paging, TA Req runs into timeout. */
9947 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9948 }
9949 }
9950
9951 /* SMLC responds with failure */
9952 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9953 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9954
9955 /* BSC tells MSC about failure */
9956 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9957 locationEstimate := omit, positioningData := omit,
9958 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9959
9960 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9961 f_verify_active_A_conn_and_clear();
9962
9963 f_sleep(2.0);
9964 setverdict(pass);
9965}
9966testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9967 var MSC_ConnHdlr vc_conn;
9968 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9969
9970 f_init(1, true);
9971 f_sleep(1.0);
9972
9973 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9974 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9975
9976 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9977 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009978 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009979}
9980
9981/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9982 * over. */
9983private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9984 f_sleep(1.0);
9985
9986 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9987 f_bssap_le_register_imsi(g_pars.imsi, omit);
9988
9989 /* Register to receive the Paging Command */
9990 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9991 g_chan_nr := new_chan_nr;
9992 f_rslem_register(0, g_chan_nr);
9993
9994 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9995 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9996 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9997 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9998
9999 var PDU_BSSAP_LE plr;
10000 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10001
10002 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10003 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010004 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 +020010005 do_clear := false, expect_bssmap_l3 := true);
10006
10007 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10008 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10009
10010 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10011 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10012
10013 /* SMLC got the TA from the BSC, now responds with geo information data. */
10014 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10015 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10016 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10017
10018 /* The lchan should still exist, it was from a CM Service Request. */
10019 f_mo_l3_transceive();
10020
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010021 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010022
10023 f_sleep(2.0);
10024 setverdict(pass);
10025}
10026testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10027 var MSC_ConnHdlr vc_conn;
10028 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10029
10030 f_init(1, true);
10031 f_sleep(1.0);
10032
10033 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10034 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10035
10036 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10037 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010038 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010039}
10040
10041/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10042 * the new lchan after handover. */
10043private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10044 f_sleep(1.0);
10045
10046 f_establish_fully(omit, omit);
10047 f_bssap_le_register_imsi(g_pars.imsi, omit);
10048
10049 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10050 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10051
10052 var PDU_BSSAP_LE plr;
10053 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10054
10055 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10056 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10057
10058 var HandoverState hs := {
10059 rr_ho_cmpl_seen := false,
10060 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010061 old_chan_nr := -,
10062 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010063 };
10064 /* issue hand-over command on VTY */
10065 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10066 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10067 f_rslem_suspend(RSL1_PROC);
10068
10069 /* From the MGW perspective, a handover is is characterized by
10070 * performing one MDCX operation with the MGW. So we expect to see
10071 * one more MDCX during handover. */
10072 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10073
10074 alt {
10075 [] as_handover(hs);
10076 }
10077
10078 var PDU_BSSAP_LE rx_bsslap;
10079
10080 interleave {
10081 /* Expect the BSC to inform the MSC about the handover */
10082 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10083
10084 /* Expect the BSC to inform the SMLC about the handover */
10085 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10086 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10087 }
10088 }
10089
10090 /* SMLC now responds with geo information data. */
10091 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10092 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10093 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10094
10095 /* lchan still active */
10096 f_mo_l3_transceive(RSL1);
10097
10098 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010099 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010100
10101 f_sleep(2.0);
10102 setverdict(pass);
10103}
10104testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10105 var MSC_ConnHdlr vc_conn;
10106 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10107
10108 f_init(2, true);
10109 f_sleep(1.0);
10110 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10111 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010112 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010113}
10114
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010115/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10116private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10117 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10118
10119 /* Also disable attach for the single connected MSC */
10120 f_vty_msc_allow_attach(BSCVTY, { false });
10121
10122 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) ));
10123 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10124
10125 /* No MSC is found, expecting a proper release on RSL */
10126 interleave {
10127 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10128 f_logp(BSCVTY, "Got RSL RR Release");
10129 }
10130 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10131 f_logp(BSCVTY, "Got RSL Deact SACCH");
10132 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010133 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010134 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10135 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010136 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010137 }
10138 }
10139 setverdict(pass);
10140}
10141testcase TC_no_msc() runs on test_CT {
10142
10143 f_init(1, true);
10144 f_sleep(1.0);
10145 var MSC_ConnHdlr vc_conn;
10146 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10147
10148 f_ctrs_bsc_init(counternames_bsc_mscpool);
10149
10150 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10151 vc_conn.done;
10152
10153 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10154 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010155 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010156}
10157
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010158/* Dyn PDCH todo:
10159 * activate OSMO as TCH/F
10160 * activate OSMO as TCH/H
10161 * does the BSC-located PCU socket get the updated INFO?
10162 * what if no PCU is connected at the time?
10163 * is the info correct on delayed PCU (re)connect?
10164 */
Harald Welte94e0c342018-04-07 11:33:23 +020010165
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010166private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
10167 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
10168 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
10169
10170 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10171 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10172 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10173 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10174 g_pars.ass_codec_list.codecElements[0];
10175 if (isvalue(g_pars.expect_mr_s0_s7)) {
10176 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10177 g_pars.expect_mr_s0_s7;
10178 }
10179 }
10180 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10181 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10182 log("expecting ASS COMPL like this: ", exp_compl);
10183
10184 f_establish_fully(ass_cmd, exp_compl);
10185
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010186 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 +000010187
10188 var RSL_Message rsl;
10189
10190 timer T := 5.0;
10191 T.start;
10192 alt {
10193 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10194 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10195 log("Rx L3 from net: ", l3);
10196 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10197 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10198 mtc.stop;
10199 }
10200 }
10201 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10202 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10203 mtc.stop;
10204 }
10205 [] T.timeout {
10206 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10207 setverdict(pass);
10208 }
10209 }
10210 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010211
10212 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010213}
10214
10215/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10216 * osmo-bsc. */
10217testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10218 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10219 var MSC_ConnHdlr vc_conn;
10220
10221 f_init(1, true);
10222 f_sleep(1.0);
10223
10224 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10225 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10226 vc_conn.done;
10227 f_shutdown_helper();
10228}
10229
10230/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10231 */
10232testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10233 f_init_vty();
10234
10235 f_init(1, false);
10236 f_sleep(1.0);
10237
10238 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10239
10240 var ASP_RSL_Unitdata rx_rsl_ud;
10241 timer T := 5.0;
10242
10243 T.start;
10244 alt {
10245 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
10246 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10247 T.stop;
10248 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10249 mtc.stop;
10250 }
10251 repeat;
10252 }
10253 [] T.timeout {
10254 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10255 setverdict(pass);
10256 }
10257 }
10258}
10259
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010260private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10261 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010262 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010263
10264 /* Trigger re-assignment to another lchan */
10265 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10266
10267 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10268 * one MDCX on MGCP. */
10269 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10270
10271 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10272 * as the old lchan used. */
10273 g_media.bts.ipa_crcx_seen := false;
10274 g_media.bts.ipa_mdcx_seen := false;
10275
10276 /* Send different BTS side RTP port number for the new lchan */
10277 g_media.bts.bts.port_nr := 4223;
10278
10279 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10280
10281 /* Trigger re-assignment. */
10282 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10283
10284 timer T := 5.0;
10285 T.start;
10286 alt {
10287 [] as_assignment(assignment_st);
10288 [] as_Media();
10289 [] T.timeout {
10290 break;
10291 }
10292 }
10293
10294 if (not assignment_st.assignment_done) {
10295 setverdict(fail, "Assignment did not complete");
10296 mtc.stop;
10297 }
10298
10299 f_check_mgcp_expectations()
10300 setverdict(pass);
10301
10302 f_sleep(2.0);
10303 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10304
10305 /* Instruct BSC to clear channel */
10306 var BssmapCause cause := 0;
10307 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10308 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010309 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10310 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010311 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010312 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010313 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010314 }
10315 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10316 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10317 }
10318 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010319 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010320
10321 f_sleep(0.5);
10322}
10323
10324testcase TC_reassignment_fr() runs on test_CT {
10325 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10326 var MSC_ConnHdlr vc_conn;
10327
10328 f_init(1, true);
10329 f_sleep(1.0);
10330
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010331 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010332
10333 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10334 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10335 vc_conn.done;
10336
10337 /* from f_establish_fully() */
10338 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10339 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10340 /* from re-assignment */
10341 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10342 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10343 f_ctrs_bsc_and_bts_verify();
10344 f_shutdown_helper();
10345}
10346
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010347const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10348const charstring REEST_CLEAR := "REEST_CLEAR";
10349const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10350
10351/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10352 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10353 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10354 * the MSC as the CM Re-Establishment is handled.
10355 *
10356 * MS bts0 bts1 bsc msc test-component
10357 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10358 * | | _1 wait a bit, to settle down
10359 * |<-x x--| | _1 "lose connection"
10360 * | | REEST_LOST_CONNECTION
10361 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10362 * | | REEST_CLEAR
10363 * | |<-0---| _1 Clear Command on first A-conn
10364 * | |--0-->| _1 Clear Complete
10365 * | |<----------------->| | _1 Release first channel
10366 * | | REEST_CLEAR_DONE
10367 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10368 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10369 *
10370 */
10371private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10372 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10373 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10374
10375 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10376 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10377
10378 f_establish_fully(ass_cmd, exp_compl);
10379
10380 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10381 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10382 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10383 f_sleep(2.0);
10384 COORD.send(REEST_LOST_CONNECTION);
10385
10386 alt {
10387 [] COORD.receive(REEST_CLEAR);
10388 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10389 setverdict(fail, "Unexpected channel release");
10390 mtc.stop;
10391 }
10392 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10393 setverdict(fail, "Unexpected channel release");
10394 mtc.stop;
10395 }
10396 }
10397 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010398 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010399 COORD.send(REEST_CLEAR_DONE);
10400}
10401
10402private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10403 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10404
10405 /* The MS lost the connection on the first channel, now establishes another one */
10406 COORD.receive(REEST_LOST_CONNECTION);
10407
10408 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10409 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10410 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10411
10412 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010413 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 +020010414 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10415
10416 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10417 COORD.send(REEST_CLEAR);
10418 COORD.receive(REEST_CLEAR_DONE);
10419
10420 f_sleep(2.0);
10421
10422 /* Answer the CM Re-Establishment with an Assignment Command. */
10423 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10424 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10425 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10426 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10427
10428 var AssignmentState st := valueof(ts_AssignmentStateInit);
10429 st.voice_call := true;
10430 st.is_assignment := true;
10431
10432 var ExpectCriteria mgcpcrit := {
10433 connid := omit,
10434 endpoint := omit,
10435 transid := omit
10436 };
10437 f_create_mgcp_expect(mgcpcrit);
10438
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010439 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010440
10441 BSSAP.send(ass_cmd);
10442
10443 var PDU_BSSAP bssap;
10444
10445 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010446 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10447 [] as_Media_ipacc(RSL1, RSL2);
10448 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010449 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10450 break;
10451 }
10452 }
10453
10454 f_sleep(3.0);
10455
10456 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010457 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010458}
10459
10460testcase TC_cm_reestablishment() runs on test_CT {
10461 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10462 var MSC_ConnHdlr vc_conn1;
10463
10464 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10465 var MSC_ConnHdlr vc_conn2;
10466 pars2.imsi := pars1.imsi;
10467 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +020010468 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010469
10470 f_init(2, true, guard_timeout := 40.0);
10471 f_sleep(1.0);
10472
10473 vc_conn1 := f_start_handler_create(pars1);
10474 vc_conn2 := f_start_handler_create(pars2);
10475 connect(vc_conn1:COORD, vc_conn2:COORD);
10476 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10477 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10478 vc_conn1.done;
10479 vc_conn2.done;
10480
10481 f_shutdown_helper();
10482}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010483
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010484function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
10485 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
10486runs on test_CT return template (omit) RSL_Message {
10487 var ASP_RSL_Unitdata rx_rsl_ud;
10488 timer T := t_secs;
10489
10490 T.start;
10491 alt {
10492 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
10493 T.stop;
10494 }
10495 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
10496 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
10497 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10498 T.stop;
10499 return omit;
10500 }
10501 [] T.timeout {
10502 return omit;
10503 }
10504 }
10505 return rx_rsl_ud.rsl;
10506}
10507
10508private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
10509 f_vty_enter_cfg_bts(pt, bts_nr);
10510 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
10511 f_vty_transceive(pt, "exit");
10512 f_vty_transceive(pt, "exit");
10513 f_vty_transceive(pt, "exit");
10514}
10515
10516private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030010517 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010518 template (present) uint12_t arfcn := ?,
10519 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010520{
10521 var RSL_IE_Body full_imm_ass_info;
10522 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10523 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10524 mtc.stop;
10525 }
10526
10527 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10528 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10529 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010530 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010531 page_mode := ?);
10532 if (not match(rr_imm_ass, expect_imm_ass)) {
10533 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10534 setverdict(fail, "Failed to match Immediate Assignment");
10535 mtc.stop;
10536 }
10537}
10538
10539testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10540 var RSL_Message chan_act;
10541 var RSL_Message imm_ass;
10542
10543 f_init(1, false);
10544 f_sleep(1.0);
10545
10546 /* (should be the default anyway, just to make things clear) */
10547 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10548
10549 /* RA containing reason=LU */
10550 var GsmFrameNumber fn := 2342;
10551 var uint8_t ra := 2;
10552 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10553
10554 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10555
10556 /* First send the Chan Act ACK */
10557 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010558 var DchanTuple dt;
10559 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010560 var RSL_IE_Body chan_ident_ie;
10561 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10562 setverdict(fail, "RSL Channel Identification IE is absent");
10563 mtc.stop;
10564 }
10565
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010566 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
10567
10568 /* Then expect the Immediate Assignment, after we ACKed the chan act */
10569 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10570
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010571 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10572 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010573
10574 /* Check that the lchan is working */
10575 var octetstring l3 := '00010203040506'O;
10576 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10577
10578 var BSSAP_N_CONNECT_ind rx_c_ind;
10579 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010580 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010581 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10582
10583 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010584 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010585 f_shutdown_helper();
10586}
10587
10588testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10589 var RSL_Message chan_act;
10590 var RSL_Message imm_ass;
10591
10592 f_init(1, false);
10593 f_sleep(1.0);
10594
10595 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10596
10597 /* RA containing reason=LU */
10598 var GsmFrameNumber fn := 2342;
10599 var uint8_t ra := 2;
10600 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10601
10602 /* (set bts 0 cfg back to default) */
10603 f_vty_set_imm_ass(BSCVTY);
10604
10605 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10606 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010607 var DchanTuple dt;
10608 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010609 var RSL_IE_Body chan_ident_ie;
10610 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10611 setverdict(fail, "RSL Channel Identification IE is absent");
10612 mtc.stop;
10613 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010614
10615 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10616 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010617 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10618 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010619
10620 /* Only now send the Chan Act ACK */
10621 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10622
10623 /* Check that the lchan is working */
10624 var octetstring l3 := '00010203040506'O;
10625 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10626
10627 var BSSAP_N_CONNECT_ind rx_c_ind;
10628 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010629 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010630 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10631
10632 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010633 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010634 f_shutdown_helper();
10635}
10636
Neels Hofmeyr23158742021-09-07 19:08:07 +020010637testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10638 var RSL_Message chan_act;
10639 var RSL_Message imm_ass;
10640
10641 f_init(1, false);
10642 f_sleep(1.0);
10643
10644 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10645
10646 /* RA containing reason=LU */
10647 var GsmFrameNumber fn := 2342;
10648 var uint8_t ra := 2;
10649 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10650
10651 /* (set bts 0 cfg back to default) */
10652 f_vty_set_imm_ass(BSCVTY);
10653
10654 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10655 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010656 var DchanTuple dt;
10657 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010658 var RSL_IE_Body chan_ident_ie;
10659 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10660 setverdict(fail, "RSL Channel Identification IE is absent");
10661 mtc.stop;
10662 }
10663
10664 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10665 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10666 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10667 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10668
10669 /* Only now send the Chan Act ACK */
10670 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10671
10672 /* Check that the lchan is working */
10673 var octetstring l3 := '00010203040506'O;
10674 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10675
10676 var BSSAP_N_CONNECT_ind rx_c_ind;
10677 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010678 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010679 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10680
10681 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010682 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020010683 f_shutdown_helper();
10684}
10685
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010686testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10687 /* change Timeslot 6 before f_init() starts RSL */
10688 f_init_vty();
10689 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10690 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10691
10692 f_init(1, false);
10693 f_sleep(1.0);
10694
10695 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10696 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010697 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010698 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10699
10700 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10701 f_ts_set_chcomb(0, 0, 6, "PDCH");
10702
10703 /* block all static timeslots so that the dyn TS will be used */
10704 f_disable_all_tch_f();
10705 f_disable_all_tch_h();
10706 f_disable_all_sdcch();
10707
10708 var RSL_Message chan_act;
10709 var RSL_Message imm_ass;
10710
10711 f_init(1, false);
10712 f_sleep(1.0);
10713
10714 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10715
10716 /* RA containing reason=LU */
10717 var GsmFrameNumber fn := 2342;
10718 var uint8_t ra := 2;
10719 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10720
10721 /* (set bts 0 cfg back to default) */
10722 f_vty_set_imm_ass(BSCVTY);
10723
10724 /* Expect the dyn TS to deactivate PDCH first */
10725 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10726 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10727
10728 /* Now activation as SDCCH8 */
10729 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010730 var DchanTuple dt;
10731 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010732
10733 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010734 var RSL_IE_Body chan_ident_ie;
10735 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10736 setverdict(fail, "RSL Channel Identification IE is absent");
10737 mtc.stop;
10738 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010739
10740 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10741 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010742 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10743 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010744
10745 /* Only now send the Chan Act ACK */
10746 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10747
10748 /* Check that the lchan is working */
10749 var octetstring l3 := '00010203040506'O;
10750 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10751
10752 var BSSAP_N_CONNECT_ind rx_c_ind;
10753 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010754 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010755 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10756
10757 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010758 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010759 f_shutdown_helper();
10760}
10761
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010762testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10763 /* change Timeslot 6 before f_init() starts RSL */
10764 f_init_vty();
10765 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10766 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10767
10768 f_init(1, false);
10769 f_sleep(1.0);
10770
10771 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10772 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010773 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010774 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10775
10776 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10777 f_ts_set_chcomb(0, 0, 6, "PDCH");
10778
10779 /* block all static timeslots so that the dyn TS will be used */
10780 f_disable_all_tch_f();
10781 f_disable_all_tch_h();
10782 f_disable_all_sdcch();
10783
10784 var RSL_Message chan_act;
10785 var RSL_Message imm_ass;
10786
10787 f_init(1, false);
10788 f_sleep(1.0);
10789
10790 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10791
10792 /* RA containing reason=LU */
10793 var GsmFrameNumber fn := 2342;
10794 var uint8_t ra := 2;
10795 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10796
10797 /* (set bts 0 cfg back to default) */
10798 f_vty_set_imm_ass(BSCVTY);
10799
10800 /* Expect the dyn TS to deactivate PDCH first */
10801 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10802
10803 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10804 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10805
10806 /* continue the Osmo style PDCH Deact (usual chan rel) */
10807 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10808
10809 /* Now activation as SDCCH8 */
10810 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010811 var DchanTuple dt;
10812 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010813
10814 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010815 var RSL_IE_Body chan_ident_ie;
10816 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10817 setverdict(fail, "RSL Channel Identification IE is absent");
10818 mtc.stop;
10819 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010820 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10821
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010822 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10823 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010824
10825 /* Check that the lchan is working */
10826 var octetstring l3 := '00010203040506'O;
10827 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10828
10829 var BSSAP_N_CONNECT_ind rx_c_ind;
10830 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010831 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010832 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10833
10834 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010835 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010836 f_shutdown_helper();
10837}
10838
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010839/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10840testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10841 var MSC_ConnHdlr vc_conn;
10842
10843 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10844 f_sleep(1.0);
10845
10846 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10847 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10848 "0,0,operational,unlocked,on,rsl-up;" &
10849 "1,0,operational,unlocked,on,rsl-up;" &
10850 "2,0,operational,unlocked,on,rsl-down;" &
10851 "3,0,inoperational,locked,on,rsl-down;");
10852
10853 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10854 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10855 /* give it a moment to settle the FSM status */
10856 f_sleep(1.0);
10857
10858 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10859 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10860 * of "off"? But that's for a future patch if at all. */
10861 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10862 "0,0,operational,unlocked,on,rsl-up;" &
10863 "1,0,operational,locked,on,rsl-up;" &
10864 "2,0,operational,unlocked,on,rsl-down;" &
10865 "3,0,inoperational,locked,on,rsl-down;");
10866
10867 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10868 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10869 f_sleep(1.0);
10870 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10871 "0,0,operational,unlocked,on,rsl-up;" &
10872 "1,0,operational,locked,on,rsl-up;" &
10873 "2,0,operational,unlocked,on,rsl-down;" &
10874 "3,0,inoperational,locked,on,rsl-down;");
10875
10876 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10877 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10878 f_sleep(1.0);
10879 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10880 "0,0,operational,unlocked,on,rsl-up;" &
10881 "1,0,operational,unlocked,on,rsl-up;" &
10882 "2,0,operational,unlocked,on,rsl-down;" &
10883 "3,0,inoperational,locked,on,rsl-down;");
10884
10885 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10886 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10887 f_sleep(1.0);
10888 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10889 "0,0,operational,unlocked,on,rsl-up;" &
10890 "1,0,operational,unlocked,on,rsl-up;" &
10891 "2,0,operational,unlocked,on,rsl-down;" &
10892 "3,0,inoperational,locked,on,rsl-down;");
10893
10894 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10895 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10896 f_sleep(1.0);
10897 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10898 "0,0,operational,unlocked,on,rsl-up;" &
10899 "1,0,operational,unlocked,on,rsl-up;" &
10900 "2,0,operational,unlocked,on,rsl-down;" &
10901 "3,0,inoperational,locked,on,rsl-down;");
10902
10903 f_shutdown_helper();
10904}
10905
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010906const CounterNameVals counternames_cm_serv_rej := {
10907 { "cm_serv_rej", 0 },
10908 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
10909 { "cm_serv_rej:illegal_ms", 0 },
10910 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
10911 { "cm_serv_rej:imei_not_accepted", 0 },
10912 { "cm_serv_rej:illegal_me", 0 },
10913 { "cm_serv_rej:plmn_not_allowed", 0 },
10914 { "cm_serv_rej:loc_not_allowed", 0 },
10915 { "cm_serv_rej:roaming_not_allowed", 0 },
10916 { "cm_serv_rej:network_failure", 0 },
10917 { "cm_serv_rej:synch_failure", 0 },
10918 { "cm_serv_rej:congestion", 0 },
10919 { "cm_serv_rej:srv_opt_not_supported", 0 },
10920 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
10921 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
10922 { "cm_serv_rej:call_can_not_be_identified", 0 },
10923 { "cm_serv_rej:incorrect_message", 0 },
10924 { "cm_serv_rej:invalid_mandantory_inf", 0 },
10925 { "cm_serv_rej:msg_type_not_implemented", 0 },
10926 { "cm_serv_rej:msg_type_not_compatible", 0 },
10927 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
10928 { "cm_serv_rej:condtional_ie_error", 0 },
10929 { "cm_serv_rej:msg_not_compatible", 0 },
10930 { "cm_serv_rej:protocol_error", 0 },
10931 { "cm_serv_rej:retry_in_new_cell", 0 }
10932};
10933
10934private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
10935{
10936 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030010937 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010938 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010939 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
10940 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010941 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010942}
10943testcase TC_cm_serv_rej() runs on test_CT {
10944 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10945 var MSC_ConnHdlr vc_conn;
10946
10947 f_init(1, true);
10948 f_sleep(1.0);
10949
10950 f_ctrs_bts_init(1, counternames_cm_serv_rej);
10951
10952 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
10953 vc_conn.done;
10954
10955 f_ctrs_bts_add(0, "cm_serv_rej", 1);
10956 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
10957 f_ctrs_bts_verify();
10958
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010959 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010960 f_shutdown_helper();
10961}
10962
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010963/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10964 * Activ Ack (SYS#5627). */
10965private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10966 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030010967
10968 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10969 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010970
10971 var BSSMAP_FIELD_CodecType codecType;
10972 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
10973
10974 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
10975
10976 /* First establish a signalling lchan */
10977 f_create_chan_and_exp();
10978 f_rslem_dchan_queue_enable();
10979
10980 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010981
10982 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
10983 activate(as_Media_mgw());
10984
10985 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
10986 f_rslem_register(0, chan_nr);
10987
10988 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
10989 BSSAP.send(ass_cmd);
10990
10991
10992 /* Wait for the Channel Activ for the TCH channel */
10993 var ASP_RSL_Unitdata rx_rsl_ud;
10994 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
10995
10996 /* make the original SDCCH disappear */
10997 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10998
10999 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11000 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11001
11002 interleave {
11003 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11004 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11005 }
11006
11007 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11008 BSSAP.receive(tr_BSSMAP_ClearComplete);
11009 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11010
11011 var MgcpCommand mgcp;
11012 MGCP.receive(tr_DLCX()) -> value mgcp {
11013 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11014 };
11015
11016 f_sleep(0.5);
11017}
11018testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11019 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11020 var MSC_ConnHdlr vc_conn;
11021
11022 f_init(1, true);
11023 f_sleep(1.0);
11024
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011025 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11026 vc_conn.done;
11027
11028 f_shutdown_helper();
11029}
11030
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011031const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11032 { "all_allocated:sdcch", 0 },
11033 { "all_allocated:static_sdcch", 0 },
11034 { "all_allocated:tch", 0 },
11035 { "all_allocated:static_tch", 0 }
11036}
11037
11038private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11039{
11040 /* Make sure counters settle first */
11041 f_sleep(1.0);
11042
11043 /* Take a baseline of counters */
11044 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11045
11046 /* Elapse some time so that we see changes in counters, hopefully where expected */
11047 f_sleep(2.0);
11048
11049 /* Get new counters */
11050 var charstring_list all_changed := {};
11051 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11052 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11053
11054 /* Compare with expectations */
11055 var charstring_list all_expect_changed := {};
11056 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11057 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11058 }
11059 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11060}
11061
11062testcase TC_ratectr_all_available_allocated() runs on test_CT {
11063 var ASP_RSL_Unitdata rsl_ud;
11064 var integer i;
11065 var integer chreq_total, chreq_nochan;
11066
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011067 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011068 f_sleep(1.0);
11069
11070 /* Exhaust all dedicated SDCCH lchans.
11071 /* GSM 44.018 Table 9.1.8.2:
11072 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11073 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011074 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011075 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011076 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011077 }
11078
11079 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11080 * level.
11081 * All SDCCH are now occupied. */
11082 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11083
11084 /* Also fill up all remaining (TCH) channels */
11085 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011086 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011087 }
11088
11089 /* All TCH are now also occupied */
11090 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11091 "all_allocated:tch", "all_allocated:static_tch"});
11092
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011093 /* Clean up SDCCH lchans */
11094 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11095 f_perform_clear_test_ct(chan_cleanup[i]);
11096 }
11097
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011098 f_shutdown_helper();
11099}
11100
11101testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11102 var ASP_RSL_Unitdata rsl_ud;
11103 var integer i;
11104 var integer chreq_total, chreq_nochan;
11105
11106 f_init_vty();
11107 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11108 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11109 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11110
11111 f_init(1, guard_timeout := 60.0);
11112 f_sleep(1.0);
11113
11114 /* The dyn TS wants to activate PDCH mode, ACK that. */
11115 var RslChannelNr chan_nr;
11116 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011117 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011118 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11119
11120 /* Exhaust all dedicated SDCCH lchans.
11121 /* GSM 44.018 Table 9.1.8.2:
11122 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11123 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011124 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011125 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011126 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011127 }
11128
11129 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11130 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11131 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11132
11133 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11134 * Will release them later, so remember all the DchanTuples. */
11135 var DchanTuples dyn_sddch := {};
11136 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11137
11138 /* Also occupy the seven other SDCCH of the dyn TS */
11139 for (i := 0; i < 7; i := i+1) {
11140 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11141 }
11142
11143 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11144 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11145
11146 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11147 for (i := 0; i < 5; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011148 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011149 }
11150
11151 /* All TCH lchans are now also occupied, both static and dynamic */
11152 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11153 "all_allocated:tch", "all_allocated:static_tch"});
11154
11155 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11156 * incrementing. */
11157 var BssmapCause cause := 0;
11158 var DchanTuple dt := dyn_sddch[0];
11159 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11160 f_exp_chan_rel_and_clear(dt, 0);
11161
11162 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11163 * count as occupied, so those still both increment. */
11164 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11165 "all_allocated:tch", "all_allocated:static_tch"});
11166
11167 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11168 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11169 dt := dyn_sddch[i];
11170 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11171 f_exp_chan_rel_and_clear(dt, 0);
11172 }
11173
11174 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11175 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011176 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011177 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11178
11179 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11180 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11181
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011182 /* Clean up SDCCH lchans */
11183 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11184 f_perform_clear_test_ct(chan_cleanup[i]);
11185 }
11186
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011187 /* clean up config */
11188 f_ts_reset_chcomb(0);
11189
11190 f_shutdown_helper();
11191}
11192
Harald Welte28d943e2017-11-25 15:00:50 +010011193control {
Harald Welte898113b2018-01-31 18:32:21 +010011194 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010011195 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010011196 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020011197 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
11198 * these in the AoIP test suite. */
11199 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11200 execute( TC_stat_num_msc_connected_1() );
11201 execute( TC_stat_num_msc_connected_2() );
11202 execute( TC_stat_num_msc_connected_3() );
11203 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020011204 execute( TC_stat_num_bts_connected_1() );
11205 execute( TC_stat_num_bts_connected_2() );
11206 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010011207 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011208 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020011209 execute( TC_ctrl_location() );
11210 }
Harald Welte898113b2018-01-31 18:32:21 +010011211
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011212 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020011213 execute( TC_si2quater_2_earfcns() );
11214 execute( TC_si2quater_3_earfcns() );
11215 execute( TC_si2quater_4_earfcns() );
11216 execute( TC_si2quater_5_earfcns() );
11217 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020011218 execute( TC_si2quater_12_earfcns() );
11219 execute( TC_si2quater_23_earfcns() );
11220 execute( TC_si2quater_32_earfcns() );
11221 execute( TC_si2quater_33_earfcns() );
11222 execute( TC_si2quater_42_earfcns() );
11223 execute( TC_si2quater_48_earfcns() );
11224 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020011225 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020011226 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011227
Harald Welte898113b2018-01-31 18:32:21 +010011228 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010011229 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010011230 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010011231 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020011232 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020011233 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010011234 execute( TC_chan_act_ack_est_ind_noreply() );
11235 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010011236 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010011237 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070011238 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010011239 execute( TC_chan_rel_rll_rel_ind() );
11240 execute( TC_chan_rel_conn_fail() );
11241 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020011242 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
11243 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010011244 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010011245 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020011246 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010011247 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010011248 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020011249 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010011250
Harald Weltecfe2c962017-12-15 12:09:32 +010011251 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010011252
11253 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010011254 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010011255 execute( TC_assignment_csd() );
11256 execute( TC_assignment_ctm() );
11257 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011258 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11259 execute( TC_assignment_aoip_tla_v6() );
11260 }
Harald Welte235ebf12017-12-15 14:18:16 +010011261 execute( TC_assignment_fr_a5_0() );
11262 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011263 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020011264 execute( TC_assignment_fr_a5_1_codec_missing() );
11265 }
Harald Welte235ebf12017-12-15 14:18:16 +010011266 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020011267 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020011268 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020011269 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011270 execute( TC_ciph_mode_a5_0() );
11271 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020011272 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020011273 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011274 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020011275 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010011276
Harald Welte60aa5762018-03-21 19:33:13 +010011277 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020011278 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010011279 execute( TC_assignment_codec_hr() );
11280 execute( TC_assignment_codec_efr() );
11281 execute( TC_assignment_codec_amr_f() );
11282 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011283
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011284 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010011285 execute( TC_assignment_codec_amr_f_S1() );
11286 execute( TC_assignment_codec_amr_h_S1() );
11287 execute( TC_assignment_codec_amr_f_S124() );
11288 execute( TC_assignment_codec_amr_h_S124() );
11289 execute( TC_assignment_codec_amr_f_S0() );
11290 execute( TC_assignment_codec_amr_f_S02() );
11291 execute( TC_assignment_codec_amr_f_S024() );
11292 execute( TC_assignment_codec_amr_f_S0247() );
11293 execute( TC_assignment_codec_amr_h_S0() );
11294 execute( TC_assignment_codec_amr_h_S02() );
11295 execute( TC_assignment_codec_amr_h_S024() );
11296 execute( TC_assignment_codec_amr_h_S0247() );
11297 execute( TC_assignment_codec_amr_f_S01234567() );
11298 execute( TC_assignment_codec_amr_f_S0234567() );
11299 execute( TC_assignment_codec_amr_f_zero() );
11300 execute( TC_assignment_codec_amr_f_unsupp() );
11301 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000011302 execute( TC_assignment_codec_amr_f_start_mode_auto() );
11303 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000011304 execute( TC_assignment_codec_amr_f_start_mode_4() );
11305 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000011306 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011307 }
Harald Welte60aa5762018-03-21 19:33:13 +010011308
Philipp Maierac09bfc2019-01-08 13:41:39 +010011309 execute( TC_assignment_codec_fr_exhausted_req_hr() );
11310 execute( TC_assignment_codec_fr_exhausted_req_fr() );
11311 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
11312 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
11313 execute( TC_assignment_codec_hr_exhausted_req_fr() );
11314 execute( TC_assignment_codec_hr_exhausted_req_hr() );
11315 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
11316 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
11317 execute( TC_assignment_codec_req_hr_fr() );
11318 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020011319 execute( TC_assignment_sdcch_exhausted_req_signalling() );
11320 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
11321 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010011322
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020011323 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020011324
Harald Welte898113b2018-01-31 18:32:21 +010011325 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010011326 execute( TC_rll_est_ind_inact_lchan() );
11327 execute( TC_rll_est_ind_inval_sapi1() );
11328 execute( TC_rll_est_ind_inval_sapi3() );
11329 execute( TC_rll_est_ind_inval_sacch() );
11330
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070011331 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
11332 execute( TC_tch_dlci_link_id_sapi() );
11333
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011334 /* SAPI N Reject triggered by RLL establishment failures */
11335 execute( TC_rll_rel_ind_sapi_n_reject() );
11336 execute( TC_rll_err_ind_sapi_n_reject() );
11337 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070011338 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011339
Harald Welte898113b2018-01-31 18:32:21 +010011340 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010011341 execute( TC_paging_imsi_nochan() );
11342 execute( TC_paging_tmsi_nochan() );
11343 execute( TC_paging_tmsi_any() );
11344 execute( TC_paging_tmsi_sdcch() );
11345 execute( TC_paging_tmsi_tch_f() );
11346 execute( TC_paging_tmsi_tch_hf() );
11347 execute( TC_paging_imsi_nochan_cgi() );
11348 execute( TC_paging_imsi_nochan_lac_ci() );
11349 execute( TC_paging_imsi_nochan_ci() );
11350 execute( TC_paging_imsi_nochan_lai() );
11351 execute( TC_paging_imsi_nochan_lac() );
11352 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010011353 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
11354 execute( TC_paging_imsi_nochan_rnc() );
11355 execute( TC_paging_imsi_nochan_lac_rnc() );
11356 execute( TC_paging_imsi_nochan_lacs() );
11357 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010011358 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010011359 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010011360 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010011361 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010011362 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010011363
11364 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010011365 execute( TC_rsl_unknown_unit_id() );
11366
11367 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011368
11369 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020011370 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011371 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010011372 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010011373 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010011374 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010011375 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011376
Harald Welte261af4b2018-02-12 21:20:39 +010011377 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020011378 execute( TC_ho_int_a5_0() );
11379 execute( TC_ho_int_a5_1() );
11380 execute( TC_ho_int_a5_3() );
11381 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000011382 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011383
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011384 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020011385 execute( TC_ho_out_fail_no_msc_response() );
11386 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020011387 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011388
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011389 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020011390 execute( TC_ho_into_this_bsc_a5_0() );
11391 execute( TC_ho_into_this_bsc_a5_1() );
11392 execute( TC_ho_into_this_bsc_a5_3() );
11393 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010011394 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
11395 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010011396 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011397 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11398 execute( TC_ho_into_this_bsc_tla_v6() );
11399 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020011400 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030011401 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010011402 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020011403 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020011404 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
11405 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011406 execute( TC_ho_in_fail_msc_clears() );
11407 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
11408 execute( TC_ho_in_fail_no_detect() );
11409 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010011410 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011411
Neels Hofmeyr91401012019-07-11 00:42:35 +020011412 execute( TC_ho_neighbor_config_1() );
11413 execute( TC_ho_neighbor_config_2() );
11414 execute( TC_ho_neighbor_config_3() );
11415 execute( TC_ho_neighbor_config_4() );
11416 execute( TC_ho_neighbor_config_5() );
11417 execute( TC_ho_neighbor_config_6() );
11418 execute( TC_ho_neighbor_config_7() );
11419
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011420 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010011421 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010011422 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020011423
11424 execute( TC_dyn_pdch_ipa_act_deact() );
11425 execute( TC_dyn_pdch_ipa_act_nack() );
11426 execute( TC_dyn_pdch_osmo_act_deact() );
11427 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010011428 execute( TC_dyn_ts_sdcch8_act_deact() );
11429 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
11430 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
11431 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011432
Stefan Sperling0796a822018-10-05 13:01:39 +020011433 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020011434 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020011435
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010011436 /* Power control related */
11437 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020011438 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020011439
11440 /* MSC pooling */
11441 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
11442 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
11443 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
11444 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
11445 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11446 execute( TC_mscpool_L3Compl_on_1_msc() );
11447 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
11448 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
11449 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
11450 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
11451 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
11452 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
11453 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
11454 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
11455 execute( TC_mscpool_paging_and_response_imsi() );
11456 execute( TC_mscpool_paging_and_response_tmsi() );
11457 execute( TC_mscpool_no_allow_attach_round_robin() );
11458 execute( TC_mscpool_no_allow_attach_valid_nri() );
11459 }
11460
Harald Welte99f3ca02018-06-14 13:40:29 +020011461 execute( TC_early_conn_fail() );
11462 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020011463 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011464
Philipp Maier783681c2020-07-16 16:47:06 +020011465 /* Emergency call handling (deny / allow) */
11466 execute( TC_assignment_emerg_setup_allow() );
11467 execute( TC_assignment_emerg_setup_deny_msc() );
11468 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020011469 execute( TC_emerg_premption() );
11470
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070011471 /* Frequency hopping parameters handling */
11472 execute( TC_fh_params_chan_activ() );
11473 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070011474 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070011475 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070011476 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020011477
11478 if (mp_enable_lcs_tests) {
11479 execute( TC_lcs_loc_req_for_active_ms() );
11480 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
11481 execute( TC_lcs_loc_req_for_idle_ms() );
11482 execute( TC_lcs_loc_req_no_subscriber() );
11483 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
11484 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
11485 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
11486 execute( TC_cm_service_during_lcs_loc_req() );
11487 execute( TC_ho_during_lcs_loc_req() );
11488 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000011489
11490 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011491
11492 execute( TC_refuse_chan_act_to_vamos() );
11493 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011494
11495 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011496
11497 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011498
11499 execute( TC_imm_ass_post_chan_ack() );
11500 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020011501 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011502 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011503 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011504
11505 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011506
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011507 execute( TC_ratectr_all_available_allocated() );
11508 execute( TC_ratectr_all_available_allocated_dyn() );
11509
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011510 execute( TC_cm_serv_rej() );
11511
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011512 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011513
11514 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
11515 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
11516 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010011517}
11518
11519}