blob: 0da2916033e04988c651c1705c65dfd496ef3480 [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,
458 rest_octets := ?
459 }
460 };
461
462
463/* List of all the System Information received on all RSL ports */
464type record of SystemInformationConfig SystemInformationConfig_list;
465
466function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
467{
468 var RSL_IE_Body sysinfo_type_ie;
469 var RSL_IE_SysinfoType si_type;
470 var octetstring data;
471
472 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
473 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
474 mtc.stop;
475 }
476 si_type := sysinfo_type_ie.sysinfo_type;
477
478 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
479 var RSL_IE_Body bcch_ie;
480 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
481 data := bcch_ie.other.payload;
482 }
483 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
484 var RSL_IE_Body l3_ie;
485 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
486 data := l3_ie.l3_info.payload;
487 }
488 } else {
489 setverdict(fail, "Don't understand this System Information message");
490 mtc.stop;
491 }
492
493 var boolean handled := false;
494
495 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
496 handled := true;
497
498 if (si_type == RSL_SYSTEM_INFO_1) {
499 if (not isbound(data)) {
500 si.si1 := omit;
501 } else {
502 si.si1 := dec_SystemInformation(data).payload.si1;
503 }
504 } else if (si_type == RSL_SYSTEM_INFO_2) {
505 if (not isbound(data)) {
506 si.si2 := omit;
507 } else {
508 si.si2 := dec_SystemInformation(data).payload.si2;
509 }
510 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
511 if (not isbound(data)) {
512 si.si2bis := omit;
513 } else {
514 si.si2bis := dec_SystemInformation(data).payload.si2bis;
515 }
516 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
517 if (not isbound(data)) {
518 si.si2ter := omit;
519 } else {
520 si.si2ter := dec_SystemInformation(data).payload.si2ter;
521 }
522 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
523 if (not isbound(data)) {
524 si.si2quater := {};
525 } else {
526 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
527 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
528 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
529 }
530 } else if (si_type == RSL_SYSTEM_INFO_3) {
531 if (not isbound(data)) {
532 si.si3 := omit;
533 } else {
534 si.si3 := dec_SystemInformation(data).payload.si3;
535 }
536 } else if (si_type == RSL_SYSTEM_INFO_4) {
537 if (not isbound(data)) {
538 si.si4 := omit;
539 } else {
540 si.si4 := dec_SystemInformation(data).payload.si4;
541 }
542 } else if (si_type == RSL_SYSTEM_INFO_13) {
543 if (not isbound(data)) {
544 si.si13 := omit;
545 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100546 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200547 }
548 } else {
549 handled := false;
550 }
551 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
552 handled := true;
553
554 if (si_type == RSL_SYSTEM_INFO_5) {
555 if (not isbound(data)) {
556 si.si5 := omit;
557 } else {
558 si.si5 := dec_SystemInformation(data).payload.si5;
559 }
560 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
561 if (not isbound(data)) {
562 si.si5bis := omit;
563 } else {
564 si.si5bis := dec_SystemInformation(data).payload.si5bis;
565 }
566 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
567 if (not isbound(data)) {
568 si.si5ter := omit;
569 } else {
570 si.si5ter := dec_SystemInformation(data).payload.si5ter;
571 }
572 } else if (si_type == RSL_SYSTEM_INFO_6) {
573 if (not isbound(data)) {
574 si.si6 := omit;
575 } else {
576 si.si6 := dec_SystemInformation(data).payload.si6;
577 }
578 } else {
579 handled := false;
580 }
581 }
582
583 if (not handled) {
584 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
585 }
586}
587
Harald Weltea4ca4462018-02-09 00:17:14 +0100588type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100589 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100590 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100591 /* RSL common Channel Port (for RSL_Emulation) */
592 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100593 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100594 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100595 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200596 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
597 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100598 /* Configure/manage IPA_Emulation: */
599 port IPA_CFG_PT IPA_CFG_PORT;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100600
Daniel Willmann191e0d92018-01-17 12:44:35 +0100601 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100602 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100603
Daniel Willmannebdecc02020-08-12 15:30:17 +0200604 /* StatsD */
605 var StatsD_Checker_CT vc_STATSD;
606
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200607 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200608 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100609 /* for old legacy-tests only */
610 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200611 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100612
Harald Welte21b46bd2017-12-17 19:46:32 +0100613 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100614 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100615
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200616 /* Osmux is enabled through VTY */
617 var boolean g_osmux_enabled := false;
618
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100619 /*Configure T(tias) over VTY, seconds */
620 var integer g_bsc_sccp_timer_ias := 7 * 60;
621 /*Configure T(tiar) over VTY, seconds */
622 var integer g_bsc_sccp_timer_iar := 15 * 60;
623
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200624 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100625 timer T_guard := 30.0;
626
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200627 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000628 var CounterNameValsList g_ctr_bsc;
629 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200630
631 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
632 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100633}
634
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200635type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100636modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100637 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100638 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100639 /* port number to which to establish the IPA OML connections */
640 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100641 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100642 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100643 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100644 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200645 /* port number to which to listen for STATSD metrics */
646 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100647 /* IP address at which the test binds */
648 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100649
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200650 RAN_Configurations mp_bssap_cfg := {
651 {
652 transport := BSSAP_TRANSPORT_AoIP,
653 sccp_service_type := "mtp3_itu",
654 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
655 own_pc := 185, /* 0.23.1 first MSC emulation */
656 own_ssn := 254,
657 peer_pc := 187, /* 0.23.3 osmo-bsc */
658 peer_ssn := 254,
659 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200660 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200661 },
662 {
663 transport := BSSAP_TRANSPORT_AoIP,
664 sccp_service_type := "mtp3_itu",
665 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
666 own_pc := 2, /* 0.0.2 second MSC emulation */
667 own_ssn := 254,
668 peer_pc := 187, /* 0.23.3 osmo-bsc */
669 peer_ssn := 254,
670 sio := '83'O,
671 rctx := 2
672 },
673 {
674 transport := BSSAP_TRANSPORT_AoIP,
675 sccp_service_type := "mtp3_itu",
676 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
677 own_pc := 3, /* 0.0.3 third MSC emulation */
678 own_ssn := 254,
679 peer_pc := 187, /* 0.23.3 osmo-bsc */
680 peer_ssn := 254,
681 sio := '83'O,
682 rctx := 3
683 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100684 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200685
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200686 /* Must match per BTS config in osmo-bsc.cfg */
687 phys_chan_configs phys_chan_config := {
688 "CCCH+SDCCH4+CBCH",
689 "TCH/F",
690 "TCH/F",
691 "TCH/F",
692 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600693 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200694 "PDCH",
695 "PDCH"
696 };
697
Harald Welte47cd0e32020-08-21 12:39:11 +0200698 BSSAP_LE_Configuration mp_bssap_le_cfg := {
699 sccp_service_type := "mtp3_itu",
700 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200701 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200702 own_ssn := 252, /* SMLC side SSN */
703 peer_pc := 187, /* 0.23.3 osmo-bsc */
704 peer_ssn := 250, /* BSC side SSN */
705 sio := '83'O,
706 rctx := 6
707 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200708 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200709
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100710 /* Value set in osmo-bsc.cfg "ms max power" */
711 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600712
713 /* Whether to check for memory leaks */
714 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100715}
716
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200717friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200718
719 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200720 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200721 pars.aoip := true;
722 } else {
723 pars.aoip := false;
724 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100725 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200726 pars.mscpool.bssap_idx := bssap_idx;
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200727 pars.expect_tsc := BTS_TSC[0];
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300728 pars.imsi := f_rnd_imsi('00101'H);
729
730 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200731
Philipp Maier48604732018-10-09 15:00:37 +0200732 return pars;
733}
734
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200735/* Convenience functions for rate counters using g_ctr_msc. */
736
737private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
738 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
739 log("initial msc rate counters: ", g_ctr_msc);
740}
741
742private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200743 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200744}
745
746/* f_ctrs_msc_init();
747 * f_do_thing(on_msc := 0);
748 * f_do_thing(on_msc := 0);
749 * f_do_other(on_msc := 1);
750 * f_ctrs_msc_add(0, "thing", 2);
751 * f_ctrs_msc_add(1, "other");
752 * f_ctrs_msc_verify();
753 */
754private function f_ctrs_msc_verify() runs on test_CT {
755 log("verifying msc rate counters: ", g_ctr_msc);
756 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
757}
758
759/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
760 * f_ctrs_msc_init();
761 * f_do_thing(on_msc := 0);
762 * f_do_thing(on_msc := 0);
763 * f_do_thing(on_msc := 0);
764 * f_ctrs_msc_expect(0, "thing", 3);
765 */
766private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
767 f_ctrs_msc_add(msc_nr, countername, val);
768 f_ctrs_msc_verify();
769}
770
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000771/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
772
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100773private 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 +0000774 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100775 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100776}
777
778function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
779 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000780 f_ctrs_bsc_init(counternames);
781}
782
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100783private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
784 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100785 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100786 f_ctrs_bsc_init(counternames_bsc_bts_handover);
787}
788
789private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000790 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100791}
792
793private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
794 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000795 f_ctrs_bsc_add(countername, val);
796}
797
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100798function f_ctrs_bts_verify() runs on test_CT {
799 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
800}
801
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000802/* f_ctrs_bsc_and_bts_init();
803 * f_do_thing(on_bts := 0);
804 * f_do_thing(on_bts := 0);
805 * f_do_other(on_bts := 1);
806 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
807 * f_ctrs_bsc_and_bts_add(1, "other");
808 * f_ctrs_bsc_and_bts_verify();
809 */
810private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100811 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000812 f_ctrs_bsc_verify();
813}
814
815/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
816 * f_ctrs_bsc_and_bts_init();
817 * f_do_thing(on_bts := 0);
818 * f_do_thing(on_bts := 0);
819 * f_do_thing(on_bts := 0);
820 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
821 */
822private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
823 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
824 f_ctrs_bsc_and_bts_verify();
825}
826
827
828/* Convenience functions for rate counters using g_ctr_bsc. */
829
830private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
831 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
832 log("initial bsc rate counters: ", g_ctr_bsc);
833}
834
835private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
836 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
837}
838
839/* f_ctrs_bsc_init();
840 * f_do_thing();
841 * f_do_thing();
842 * f_do_other();
843 * f_ctrs_bsc_add("thing", 2);
844 * f_ctrs_bsc_add("other");
845 * f_ctrs_bsc_verify();
846 */
847private function f_ctrs_bsc_verify() runs on test_CT {
848 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
849}
850
851/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
852 * f_ctrs_bsc_init();
853 * f_do_thing();
854 * f_ctrs_bsc_expect("thing", 1);
855 */
856private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
857 f_ctrs_bsc_add(countername, val);
858 f_ctrs_bsc_verify();
859}
860
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200861
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200862friend function f_shutdown_helper() runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100863 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600864 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100865 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
866 }
867
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200868 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100869 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200870 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100871}
872
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200873private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100874 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200875 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100876 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200877 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
878 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100879 T.start;
880 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200881 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
882 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200883 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100884 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200885 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200886 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100887 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200888 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200889 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100890 repeat;
891 }
892 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200893 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200894 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200895 /* If we received a RESET after ours was sent, it
896 may be a race condition where the other peer beacame
897 available after we sent it, but we are in a desired
898 state anyway, so go forward. */
899 if (not reset_received) {
900 setverdict(fail);
901 }
902 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100903 }
Harald Welte28d943e2017-11-25 15:00:50 +0100904}
905
Harald Welteae026692017-12-09 01:03:01 +0100906type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100907 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100908 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100909 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100910 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100911 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100912 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100913 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100914 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100915}
916
Harald Welte21b46bd2017-12-17 19:46:32 +0100917/*! Start the IPA/RSL related bits for one IPA_Client.
918 * \param clnt IPA_Client for which to establish
919 * \param bsc_host IP address / hostname of the BSC
920 * \param bsc_port TCP port number of the BSC
921 * \param i number identifying this BTS
922 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100923function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
924 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100925runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100926 timer T := 10.0;
927
Harald Welte96c94412017-12-09 03:12:45 +0100928 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100929 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100930 clnt.ccm_pars := c_IPA_default_ccm_pars;
931 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
932 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100933 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100934 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Harald Welte89ab1912018-02-23 18:56:29 +0100935 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100936 }
Harald Welteae026692017-12-09 01:03:01 +0100937
938 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100939 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT);
Harald Welte624f9632017-12-16 19:26:04 +0100940 if (handler_mode) {
941 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
942 } else {
943 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
944 }
Harald Welteae026692017-12-09 01:03:01 +0100945
Harald Welte5d1a2202017-12-13 19:51:29 +0100946 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100947 if (handler_mode) {
948 clnt.vc_RSL.start(RSL_Emulation.main());
949 return;
950 }
Harald Welteae026692017-12-09 01:03:01 +0100951
952 /* wait for IPA RSL link to connect and send ID ACK */
953 T.start;
954 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700955 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100956 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700957 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100958 }
Harald Welte60e823a2017-12-10 14:10:59 +0100959 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100960 [] IPA_RSL[i].receive { repeat }
961 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100962 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200963 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100964 }
965 }
966}
967
Harald Welte12055472018-03-17 20:10:08 +0100968function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100969 var IPL4asp_Types.Result res := {
970 errorCode := omit,
971 connId := omit,
972 os_error_code := omit,
973 os_error_text := omit
974 };
975
Harald Welte12055472018-03-17 20:10:08 +0100976 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
977 return;
978 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100979
980 /* Alive components don't finish sockets (TCP FIN) when they are
981 * stopped. Hence, we need to manually call close() on them to make sure
982 * the IUT knows about it. */
983 f_ipa_cfg_disconnect(IPA_CFG_PORT, res);
984
Harald Welte12055472018-03-17 20:10:08 +0100985 clnt.vc_IPA.stop;
986 if (isbound(clnt.vc_RSL)) {
987 clnt.vc_RSL.stop;
988 }
989}
990
Harald Welte21b46bd2017-12-17 19:46:32 +0100991/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100992function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
993 timer T := secs_max;
994 T.start;
995 while (true) {
996 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
997 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100998 /* the 'degraded' state exists from OML connection time, and we have to wait
999 * until all MO's are initialized */
1000 T.start(1.0);
1001 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001002 return;
1003 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001004 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001005 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001006 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001007 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001008 }
1009 }
1010}
1011
Harald Welte21b46bd2017-12-17 19:46:32 +01001012/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001013altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001014 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001015 [] T_guard.timeout {
1016 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001017 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001018 }
Harald Welte60e823a2017-12-10 14:10:59 +01001019 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001020 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001021 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001022 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +01001023 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001024 }
Harald Welte28d943e2017-11-25 15:00:50 +01001025}
1026
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001027altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001028 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001029 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001030 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001031 }
1032}
1033
Daniel Willmann191e0d92018-01-17 12:44:35 +01001034function f_init_mgcp(charstring id) runs on test_CT {
1035 id := id & "-MGCP";
1036
1037 var MGCPOps ops := {
1038 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1039 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1040 };
1041 var MGCP_conn_parameters mgcp_pars := {
1042 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001043 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001044 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001045 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001046 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1047 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001048 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001049 };
1050
Harald Welte71389132021-12-09 21:58:18 +01001051 vc_MGCP := MGCP_Emulation_CT.create(id) alive;
Daniel Willmann191e0d92018-01-17 12:44:35 +01001052 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1053}
1054
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001055/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1056 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1057 * OsmuxCID IE.
1058 */
1059private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1060 f_vty_enter_cfg_msc(BSCVTY, 0);
1061 if (allow) {
1062 f_vty_transceive(BSCVTY, "osmux on");
1063 } else {
1064 f_vty_transceive(BSCVTY, "osmux off");
1065 }
1066 f_vty_transceive(BSCVTY, "exit");
1067 f_vty_transceive(BSCVTY, "exit");
1068 g_osmux_enabled := allow;
1069}
1070
Max2253c0b2018-11-06 19:28:05 +01001071function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001072 if (BSCVTY.checkstate("Mapped")) {
1073 /* skip initialization if already executed once */
1074 return;
1075 }
Harald Weltebc03c762018-02-12 18:09:38 +01001076 map(self:BSCVTY, system:BSCVTY);
1077 f_vty_set_prompts(BSCVTY);
1078 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001079 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1080 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001081}
1082
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001083friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001084{
1085 // log on TTCN3 log output
1086 log(log_msg);
1087 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001088 if (pt.checkstate("Mapped")) {
1089 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1090 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001091}
1092
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001093private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1094{
1095 if (rsl_idx >= lengthof(g_system_information)) {
1096 g_system_information[rsl_idx] := SystemInformationConfig_omit
1097 }
1098 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1099}
1100
1101altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1102 var ASP_RSL_Unitdata rx_rsl_ud;
1103
1104 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1105 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1106 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1107 repeat;
1108 }
1109 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1110 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1111 repeat;
1112 }
1113 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1114 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1115 repeat;
1116 }
1117 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1118 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1119 repeat;
1120 }
1121
1122 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1123 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1124 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1125 repeat;
1126 }
1127 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1128 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1129 repeat;
1130 }
1131 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1132 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1133 repeat;
1134 }
1135 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1136 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1137 repeat;
1138 }
1139}
1140
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001141/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1142private type record of boolean my_BooleanList;
1143
1144private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1145{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001146 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1147
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001148 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001149 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1150 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1151 * stepping into that config node. */
1152 log("msc ", msc_nr, " is not configured, skipping");
1153 continue;
1154 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001155 f_vty_enter_cfg_msc(pt, msc_nr);
1156 if (allow_attach_list[msc_nr]) {
1157 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1158 f_vty_transceive(pt, "allow-attach", strict := false);
1159 } else {
1160 f_vty_transceive(pt, "no allow-attach", strict := false);
1161 }
1162 f_vty_transceive(pt, "exit");
1163 f_vty_transceive(pt, "exit");
1164 }
1165}
1166
Harald Welte21b46bd2017-12-17 19:46:32 +01001167/* global initialization function
1168 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001169 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1170 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1171 */
1172function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001173 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001174 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001175
Harald Welteae026692017-12-09 01:03:01 +01001176 if (g_initialized) {
1177 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001178 }
Harald Welteae026692017-12-09 01:03:01 +01001179 g_initialized := true;
1180
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001181 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001182 activate(as_Tguard());
1183
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001184 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001185 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001186
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001187 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001188 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1189
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001190 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1191 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1192 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1193 }
1194
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001195 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001196 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001197 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1198 * MSC-side BSSAP emulation */
1199 if (handler_mode) {
1200 var RanOps ranops := MSC_RanOps;
1201 ranops.use_osmux := g_osmux_enabled;
1202 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1203 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1204 f_ran_adapter_start(g_bssap[bssap_idx]);
1205 } else {
1206 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1207 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1208 f_ran_adapter_start(g_bssap[bssap_idx]);
1209 f_legacy_bssap_reset();
1210 }
Harald Welte67089ee2018-01-17 22:19:03 +01001211 }
Harald Welted5833a82018-05-27 16:52:56 +02001212
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001213 if (mp_enable_lcs_tests) {
1214 if (handler_mode) {
1215 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1216 } else {
1217 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1218 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1219 }
1220 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001221 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001222
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001223 /* start the test with exactly all enabled MSCs allowed to attach */
1224 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1225
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001226 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001227
Daniel Willmann191e0d92018-01-17 12:44:35 +01001228 f_init_mgcp("VirtMSC");
1229
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001230 for (var integer i := 0; i < nr_bts; i := i+1) {
1231 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001232 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001233
1234 /* Emit a marker to appear in the SUT's own logging output */
1235 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001236}
Harald Welte696ddb62017-12-08 14:01:43 +01001237
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001238function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1239runs on test_CT {
1240 /* wait until osmo-bts-omldummy has respawned */
1241 f_wait_oml(bts_idx, "degraded", 5.0);
1242
1243 /* start RSL connection */
1244 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1245 /* wait until BSC tells us "connected" */
1246 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001247}
1248
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001249function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1250 template SystemInformationConfig expect_si)
1251runs on test_CT {
1252 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1253
1254 f_init_bts(bts_idx, handler_mode);
1255
1256 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1257 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1258 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1259 */
1260 f_sleep(5.0);
1261 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1262
1263 deactivate(sysinfo);
1264
1265 if (match(g_system_information[bts_idx], expect_si)) {
1266 setverdict(pass);
1267 } else {
1268 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1269 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1270 setverdict(fail, "received SI does not match expectations");
1271 return;
1272 }
1273}
1274
Maxd4e56962018-10-31 19:08:25 +01001275/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001276function 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 +01001277runs on test_CT return RSL_Message {
1278 var ASP_RSL_Unitdata rx_rsl_ud;
1279 timer T := t_secs;
1280
1281 T.start;
1282 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001283 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001284 T.stop;
1285 }
1286 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001287 [] T.timeout {
1288 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001289 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001290 }
Harald Welteae026692017-12-09 01:03:01 +01001291 }
1292 return rx_rsl_ud.rsl;
1293}
1294
Harald Welte21b46bd2017-12-17 19:46:32 +01001295/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001296function 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 +01001297runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001298 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001299}
1300
1301
Harald Welte4003d112017-12-09 22:35:39 +01001302/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001303testcase TC_chan_act_noreply() runs on test_CT {
1304 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001305 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001306
Harald Welte89d42e82017-12-17 16:42:41 +01001307 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001308
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001309 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001310 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001311 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001312}
1313
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001314const CounterNameVals counternames_bts_chreq := {
1315 { "chreq:total", 0 },
1316 { "chreq:attempted_emerg", 0 },
1317 { "chreq:attempted_call", 0 },
1318 { "chreq:attempted_location_upd", 0 },
1319 { "chreq:attempted_pag", 0 },
1320 { "chreq:attempted_pdch", 0 },
1321 { "chreq:attempted_other", 0 },
1322 { "chreq:attempted_unknown", 0 },
1323 { "chreq:successful", 0 },
1324 { "chreq:successful_emerg", 0 },
1325 { "chreq:successful_call", 0 },
1326 { "chreq:successful_location_upd", 0 },
1327 { "chreq:successful_pag", 0 },
1328 { "chreq:successful_pdch", 0 },
1329 { "chreq:successful_other", 0 },
1330 { "chreq:successful_unknown", 0 },
1331 { "chreq:no_channel", 0 },
1332 { "chreq:max_delay_exceeded", 0 }
1333};
1334
1335/* verify the "chreq:*" counters */
1336private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1337{
1338 var GsmFrameNumber fn := 23;
1339
1340 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1341
1342 var RSL_Message rx_rsl;
1343 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1344 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1345 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1346
1347 f_ctrs_bts_add(0, "chreq:total");
1348 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1349 f_ctrs_bts_verify();
1350
1351 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1352 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1353
1354 f_ctrs_bts_add(0, "chreq:successful");
1355 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1356 f_ctrs_bts_verify();
1357
1358 /* test is done, release RSL Conn Fail Ind to clean up */
1359 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1360 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1361 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
1362 f_sleep(1.0);
1363}
1364
Harald Welte4003d112017-12-09 22:35:39 +01001365testcase TC_chan_act_counter() runs on test_CT {
1366 var BSSAP_N_UNITDATA_ind ud_ind;
1367 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001368 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001369
Harald Welte89d42e82017-12-17 16:42:41 +01001370 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001371
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001372 f_vty_allow_emerg_bts(true, 0);
1373
1374 f_ctrs_bts_init(1, counternames_bts_chreq);
1375
1376 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1377 f_chan_act_counter('a3'O, "emerg");
1378
1379 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1380 f_chan_act_counter('43'O, "call");
1381
1382 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1383 f_chan_act_counter('03'O, "location_upd");
1384
1385 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1386 f_chan_act_counter('23'O, "pag");
1387 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1388 f_chan_act_counter('33'O, "pag");
1389
1390 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1391 /* no PCU, so PDCH not allowed. Skip this test for now. */
1392 /* f_chan_act_counter('7b'O, "pdch"); */
1393
1394 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1395 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001396
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001397 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001398}
1399
Harald Welteae026692017-12-09 01:03:01 +01001400/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001401private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001402 var RSL_Message rx_rsl;
1403
Harald Welteae026692017-12-09 01:03:01 +01001404 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001405 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001406
1407 /* expect BSC to disable the channel again if there's no RLL EST IND */
1408 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1409
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001410 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001411}
1412
Philipp Maier9c60a622020-07-09 15:08:46 +02001413/* Normal variant */
1414testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001415 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001416 f_TC_chan_act_ack_noest();
1417}
1418
1419/* Emergency call variant */
1420testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1421 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001422 f_init(1);
1423 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001424 f_TC_chan_act_ack_noest(ra := 'A5'O);
1425}
1426
Philipp Maier606f07d2020-08-12 17:21:58 +02001427/* Emergency call variant, but emergency calls are not allowed */
1428testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1429 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1430
1431 var RSL_Message rx_rsl;
1432 var GsmRrMessage rr;
1433
1434 f_init(1);
1435 f_vty_allow_emerg_bts(false, 0);
1436
1437 IPA_RSL[0].clear;
1438 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1439
1440 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1441 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1442 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1443 setverdict(pass);
1444 } else {
1445 setverdict(fail, "immediate assignment not rejected");
1446 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001447
1448 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001449}
1450
Harald Welteae026692017-12-09 01:03:01 +01001451/* Test behavior if MSC never answers to CR */
1452testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001453 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1454 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001455 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001456 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001457
Harald Welte89d42e82017-12-17 16:42:41 +01001458 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001459
1460 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001461 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001462
1463 var octetstring l3 := '00010203040506'O
1464 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1465
1466 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1467
1468 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001469 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001470 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001471 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001472}
1473
1474/* Test behavior if MSC answers with CREF to CR */
1475testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1476 var BSSAP_N_CONNECT_ind rx_c_ind;
1477 var RSL_Message rx_rsl;
1478
Harald Welte89d42e82017-12-17 16:42:41 +01001479 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001480
1481 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001482 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001483
1484 var octetstring l3 := '00010203040506'O
1485 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1486
1487 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1488 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1489
1490 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001491 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001492 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001493}
1494
Harald Welte618ef642017-12-14 14:58:20 +01001495/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1496testcase TC_chan_act_nack() runs on test_CT {
1497 var RSL_Message rx_rsl;
1498 var integer chact_nack;
1499
Harald Welte89d42e82017-12-17 16:42:41 +01001500 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001501
1502 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1503
1504 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1505 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1506 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1507
1508 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1509
1510 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1511 f_sleep(0.5);
1512
1513 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1514
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001515 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001516}
1517
Harald Welte799c97b2017-12-14 17:50:30 +01001518/* Test for channel exhaustion due to RACH overload */
1519testcase TC_chan_exhaustion() runs on test_CT {
1520 var ASP_RSL_Unitdata rsl_ud;
1521 var integer i;
1522 var integer chreq_total, chreq_nochan;
1523
Harald Welte89d42e82017-12-17 16:42:41 +01001524 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001525
1526 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1527 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1528
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001529 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001530 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1531 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001532 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 +01001533 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001534 }
1535
1536 IPA_RSL[0].clear;
1537
Harald Weltedd8cbf32018-01-28 12:07:52 +01001538 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001539 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001540
1541 /* now expect additional channel activations to fail */
1542 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1543
1544 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001545 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001546 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1547 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001548 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001549 var GsmRrMessage rr;
1550 /* match on IMM ASS REJ */
1551 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1552 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1553 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001554 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001555 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1556 chreq_nochan+1);
1557 setverdict(pass);
1558 } else {
1559 repeat;
1560 }
1561 }
1562 [] IPA_RSL[0].receive { repeat; }
1563 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001564 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001565}
1566
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001567/* Test channel deactivation due to silence from MS */
1568testcase TC_chan_deact_silence() runs on test_CT {
1569 var RslChannelNr chan_nr;
1570
1571 f_init(1);
1572
1573 /* Request for a dedicated channel */
1574 chan_nr := f_chreq_act_ack('23'O);
1575
1576 /* Wait some time until the channel is released */
1577 f_sleep(2.0);
1578
1579 /* Expect CHANnel RELease */
1580 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001581 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001582 log("Received CHANnel RELease");
1583 setverdict(pass);
1584 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001585 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001586 /* See OS#3709, OsmoBSC should not send Immediate
1587 * Assignment Reject since a dedicated channel was
1588 * already allocated, and Immediate Assignment was
1589 * already sent. */
1590 setverdict(fail, "Unexpected Immediate Assignment!");
1591 }
1592 [] IPA_RSL[0].receive {
1593 setverdict(fail, "Unexpected RSL message!");
1594 }
1595 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001596 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001597}
1598
Harald Weltecfe2c962017-12-15 12:09:32 +01001599/***********************************************************************
1600 * Assignment Testing
1601 ***********************************************************************/
1602
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001603/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1604 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001605testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001606 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001607
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001608 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1609 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001610 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001611 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001612}
1613
Harald Welte16a4adf2017-12-14 18:54:01 +01001614/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001615testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001616 var BSSAP_N_CONNECT_ind rx_c_ind;
1617 var RSL_Message rx_rsl;
1618 var DchanTuple dt;
1619
Harald Welte89d42e82017-12-17 16:42:41 +01001620 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001621
1622 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001623 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001624 /* send assignment without AoIP IEs */
1625 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1626 } else {
1627 /* Send assignmetn without CIC in IPA case */
1628 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1629 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1630 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1631 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001632 alt {
1633 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1634 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1635 }
Harald Welte235ebf12017-12-15 14:18:16 +01001636 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001637 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1638 setverdict(pass);
1639 }
1640 [] BSSAP.receive { repeat; }
1641 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001642 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001643 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001644}
1645
Harald Welteed848512018-05-24 22:27:58 +02001646/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001647function 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 +02001648 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001649 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001650 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001651 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001652 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001653 if (osmux_enabled) {
1654 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1655 } else {
1656 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1657 }
Harald Welteed848512018-05-24 22:27:58 +02001658 } else {
1659 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001660 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001661 }
1662 return ass_cmd;
1663}
1664
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001665function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001666 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001667 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1668 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001669 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001670
1671 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1672 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1673 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1674 var template BSSMAP_IE_KC128 kc128 := omit;
1675 if (ispresent(enc)) {
1676 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001677 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1678 if (ispresent(v_enc.enc_alg_chosen)) {
1679 chosenEncryptionAlgorithm := valueof(
1680 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1681 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1682 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001683 if (ispresent(v_enc.enc_kc128)) {
1684 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1685 }
1686 }
1687
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001688 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001689 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001690 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001691 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1692 cell_id_source := cell_id_source,
1693 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001694 encryptionInformation := encryptionInformation,
1695 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001696 kC128 := kc128,
1697 /* on AoIP, allow "all" codecs (until we add more concise
1698 * tests) */
1699 codecList := ts_BSSMAP_IE_CodecList(
1700 {ts_CodecAMR_F, ts_CodecAMR_H,
1701 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001702 } else {
1703 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001704 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1705 cell_id_source := cell_id_source,
1706 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001707 encryptionInformation := encryptionInformation,
1708 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1709 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001710 }
1711 return ho_req;
1712}
1713
Harald Welteed848512018-05-24 22:27:58 +02001714/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001715function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001716 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001717 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001718 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001719 if (expect_osmux) {
1720 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1721 } else {
1722 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1723 }
Harald Welteed848512018-05-24 22:27:58 +02001724 } else {
1725 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001726 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001727 }
1728 return exp_compl;
1729}
1730
Harald Welte235ebf12017-12-15 14:18:16 +01001731/* Run everything required up to sending a caller-specified assignment command and expect response */
1732function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001733runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001734 var BSSAP_N_CONNECT_ind rx_c_ind;
1735 var RSL_Message rx_rsl;
1736 var DchanTuple dt;
1737
Harald Welte89d42e82017-12-17 16:42:41 +01001738 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001739
1740 dt := f_est_dchan('23'O, 23, '00000000'O);
1741 /* send assignment without AoIP IEs */
1742 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1743 alt {
1744 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1745 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1746 setverdict(pass);
1747 } else {
1748 setverdict(fail, fail_text);
1749 }
1750 }
1751 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1752 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1753 setverdict(pass);
1754 } else {
1755 setverdict(fail, fail_text);
1756 }
1757 }
1758 [] BSSAP.receive { repeat; }
1759 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001760 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001761}
1762testcase TC_assignment_csd() runs on test_CT {
1763 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001764 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001765 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1766 //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 +01001767 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1768 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001769 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001770}
1771
1772testcase TC_assignment_ctm() runs on test_CT {
1773 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001774 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001775 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1776 //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 +01001777 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1778 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001779 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001780}
1781
Harald Welte4003d112017-12-09 22:35:39 +01001782type record DchanTuple {
1783 integer sccp_conn_id,
1784 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001785}
1786
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001787type record of DchanTuple DchanTuples;
1788
Harald Welted6939652017-12-13 21:02:46 +01001789/* Send CHAN RQD and wait for allocation; acknowledge it */
1790private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1791runs on test_CT return RslChannelNr {
1792 var RSL_Message rx_rsl;
1793 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1794 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1795 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1796 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001797 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001798 return chan_nr;
1799}
1800
Harald Welte4003d112017-12-09 22:35:39 +01001801/* helper function to establish a dedicated channel via BTS and MSC */
1802function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1803runs on test_CT return DchanTuple {
1804 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001805 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001806
Harald Welte4003d112017-12-09 22:35:39 +01001807 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001808 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001809
1810 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1811
1812 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1813 dt.sccp_conn_id := rx_c_ind.connectionId;
1814 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1815
1816 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001817}
1818
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001819/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1820function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1821runs on test_CT return DchanTuple {
1822 var BSSAP_N_CONNECT_ind rx_c_ind;
1823 var DchanTuple dt;
1824
1825 /* Send CHAN RQD */
1826 var RSL_Message rx_rsl;
1827 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1828
1829 /* The dyn TS first deactivates PDCH */
1830 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1831 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1832 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1833
1834 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1835 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1836
1837 /* Now activates the signalling channel */
1838 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1839 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1840
1841 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1842
1843 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1844 dt.sccp_conn_id := rx_c_ind.connectionId;
1845 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1846
1847 return dt;
1848}
1849
Harald Welte641fcbe2018-06-14 10:58:35 +02001850/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1851private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1852 var RSL_Message rx_rsl;
1853 /* expect BSC to disable the channel */
1854 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1855 /* respond with CHAN REL ACK */
1856 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1857
1858 /* expect Clear Complete from BSC */
1859 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1860
1861 /* MSC disconnects as instructed. */
1862 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1863}
1864
Harald Welte4003d112017-12-09 22:35:39 +01001865/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1866testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001867 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001868 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001869
Harald Welte89d42e82017-12-17 16:42:41 +01001870 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001871
Harald Welte4003d112017-12-09 22:35:39 +01001872 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1873
1874 /* simulate RLL REL IND */
1875 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1876
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001877 /* expect Clear Request on MSC side */
1878 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1879
1880 /* Instruct BSC to clear channel */
1881 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1882 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1883
Harald Welte4003d112017-12-09 22:35:39 +01001884 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001885 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001886
1887 /* wait for SCCP emulation to do its job */
1888 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001889
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001890 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001891}
1892
1893/* Test behavior of channel release after CONN FAIL IND from BTS */
1894testcase TC_chan_rel_conn_fail() runs on test_CT {
1895 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001896 var DchanTuple dt;
1897
Harald Welte89d42e82017-12-17 16:42:41 +01001898 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001899
1900 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1901
1902 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001903 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 +01001904 /* TODO: different cause values? */
1905
Harald Welte4003d112017-12-09 22:35:39 +01001906 /* expect Clear Request from BSC */
1907 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1908
1909 /* Instruct BSC to clear channel */
1910 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1911 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1912
Harald Welte6ff76ea2018-01-28 13:08:01 +01001913 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001914 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001915
1916 /* wait for SCCP emulation to do its job */
1917 f_sleep(1.0);
1918
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001919 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001920}
1921
Harald Welte99f3ca02018-06-14 13:40:29 +02001922/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1923/* See also https://www.osmocom.org/issues/3182 */
1924testcase TC_early_conn_fail() runs on test_CT {
1925 var RSL_Message rx_rsl;
1926 var DchanTuple dt;
1927
1928 f_init(1);
1929
1930 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001931 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001932
1933 /* BTS->BSC: simulate CONN FAIL IND */
1934 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1935
1936 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1937 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1938
1939 /* BTS<-BSC: respond with CHAN REL ACK */
1940 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1941
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001942 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001943}
1944
1945/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1946/* See also https://www.osmocom.org/issues/3182 */
1947testcase TC_late_conn_fail() runs on test_CT {
1948 var RSL_Message rx_rsl;
1949 var DchanTuple dt;
1950
1951 f_init(1);
1952
1953 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1954
1955 /* BSC<-MSC: Instruct BSC to clear connection */
1956 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1957
1958 /* BTS->BSC: expect BSC to deactivate SACCH */
1959 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1960
1961 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1962 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1963
1964 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1965 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1966 /* BTS->BSC: respond with CHAN REL ACK */
1967 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1968
1969 /* BSC->MSC: expect Clear Complete from BSC */
1970 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1971
1972 /* BSC<-MSC: MSC disconnects as requested. */
1973 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1974
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001975 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001976}
1977
Oliver Smithaf03bef2021-08-24 15:34:51 +02001978private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1979 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1980 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1981
1982 f_statsd_reset();
1983
1984 /* Establish SDCCH */
1985 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1986 f_establish_fully(ass_cmd, exp_fail);
1987
1988 /* Expect stats to be 0 */
1989 var StatsDExpects expect := {
1990 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1991 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1992 };
1993 f_statsd_expect(expect);
1994
1995 /* Simulate CONN FAIL IND on SDCCH */
1996 RSL.send(ts_ASP_RSL_UD(
1997 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1998 IPAC_PROTO_RSL_TRX0));
1999
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002000 f_sleep(1.0);
2001
Oliver Smithaf03bef2021-08-24 15:34:51 +02002002 /* Expect stats to be 1 */
2003 expect := {
2004 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2005 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2006 };
2007 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002008 BSSAP.receive(tr_BSSMAP_ClearRequest);
2009 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002010}
2011testcase TC_stats_conn_fail() runs on test_CT {
2012 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2013 var MSC_ConnHdlr vc_conn;
2014
2015 f_init(1, true);
2016 f_sleep(1.0);
2017
2018 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2019 vc_conn.done;
2020
2021 f_shutdown_helper();
2022}
2023
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01002024function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002025 boolean expect_deact_sacch := true,
2026 boolean expect_rr_chan_rel := true,
2027 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002028 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002029 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002030 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002031 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002032
2033 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002034 var boolean got_deact_sacch := false;
2035 var boolean got_rr_chan_rel := false;
2036 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002037 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002038 var RSL_IE_Body l3_ie;
2039 var PDU_ML3_NW_MS l3;
2040 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002041 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2042 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002043 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002044 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002045 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002046 repeat;
2047 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002048 [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 +01002049 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002050
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002051 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2052 setverdict(fail, "cannot find L3");
2053 mtc.stop;
2054 }
2055 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2056
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002057 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002058 var CellSelIndValue cells := dec_CellSelIndValue(
2059 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2060
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002061 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2062 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002063 setverdict(pass);
2064 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002065 log("EXPECTED CELLS: ", expect_cells);
2066 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002067 }
2068 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002069
2070 if (not istemplatekind(expect_rr_cause, "omit")) {
2071 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2072 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2073 if (match(got_cause, expect_rr_cause)) {
2074 setverdict(pass);
2075 } else {
2076 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2077 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
2078 }
2079 }
Harald Welte99787102019-02-04 10:41:36 +01002080 repeat;
2081 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002082 [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 +01002083 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002084
2085 if (not istemplatekind(expect_rr_cause, "omit")) {
2086 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2087 setverdict(fail, "cannot find L3");
2088 mtc.stop;
2089 }
2090 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2091
2092 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2093 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2094 if (match(got_cause, expect_rr_cause)) {
2095 setverdict(pass);
2096 } else {
2097 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2098 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
2099 }
2100 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01002101 repeat;
2102 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002103 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002104 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002105 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002106 if (handle_rll_rel) {
2107 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
2108 }
Harald Welte91d54a52018-01-28 15:35:07 +01002109 repeat;
2110 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002111 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002112 /* respond with CHAN REL ACK */
2113 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
2114 }
2115 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002116 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002117 repeat;
2118 }
2119 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002120
2121 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2122 " got_rll_rel_req=", got_rll_rel_req);
2123
2124 if (expect_deact_sacch != got_deact_sacch) {
2125 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2126 }
2127 if (expect_rr_chan_rel != got_rr_chan_rel) {
2128 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2129 }
2130 if (expect_rll_rel_req != got_rll_rel_req) {
2131 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2132 }
Harald Welte91d54a52018-01-28 15:35:07 +01002133}
2134
Harald Welte4003d112017-12-09 22:35:39 +01002135/* Test behavior of channel release after hard Clear Command from MSC */
2136testcase TC_chan_rel_hard_clear() runs on test_CT {
2137 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002138 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002139
Harald Welte89d42e82017-12-17 16:42:41 +01002140 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002141
2142 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2143
2144 /* Instruct BSC to clear channel */
2145 var BssmapCause cause := 0;
2146 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2147
2148 /* expect Clear Complete from BSC on A */
2149 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2150 /* release the SCCP connection */
2151 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2152 }
2153
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002154 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002155 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002156}
2157
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002158function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2159 var BSSAP_N_DATA_ind rx_di;
2160 var DchanTuple dt;
2161
2162 f_init(1);
2163
2164 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2165 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2166 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2167 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2168
2169 /* Instruct BSC to clear channel */
2170 var BssmapCause cause := 0;
2171 if (tx_csfb_ind) {
2172 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2173 } else {
2174 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2175 }
2176
2177 /* expect Clear Complete from BSC on A */
2178 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2179 /* release the SCCP connection */
2180 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2181 }
2182
2183 /* 1 neighbor is added by default in osmo-bts.cfg and
2184 SystemInformationConfig_default, use that: */
2185 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2186
2187 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2188 f_shutdown_helper();
2189}
2190
2191/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2192 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2193 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2194 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2195 Indicator or not shouldn't matter at all. */
2196testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2197 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2198}
2199
2200/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2201 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2202 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2203 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2204testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2205 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2206}
2207
2208/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2209 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2210 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2211 CSFB Indicator should not be used anymore, and hence, there should be no
2212 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2213 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002214testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2215 var BSSAP_N_DATA_ind rx_di;
2216 var DchanTuple dt;
2217
2218 f_init(1);
2219
2220 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2221
2222 /* Instruct BSC to clear channel */
2223 var BssmapCause cause := 0;
2224 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2225
2226 /* expect Clear Complete from BSC on A */
2227 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2228 /* release the SCCP connection */
2229 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2230 }
2231
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002232 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002233 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002234}
2235
Harald Welted8c36cd2017-12-09 23:05:31 +01002236/* Test behavior of channel release after hard RLSD from MSC */
2237testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002238 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002239
Harald Welte89d42e82017-12-17 16:42:41 +01002240 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002241
2242 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2243
2244 /* release the SCCP connection */
2245 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2246
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002247 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002248 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002249}
2250
Harald Welte550daf92018-06-11 19:22:13 +02002251/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2252testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2253 var DchanTuple dt;
2254
2255 f_init(1);
2256
2257 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2258
2259 /* release the SCCP connection */
2260 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2261
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002262 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002263 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002264}
2265
Harald Welte85804d42017-12-10 14:11:58 +01002266/* Test behavior of channel release after BSSMAP RESET from MSC */
2267testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002268 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002269
Harald Welte89d42e82017-12-17 16:42:41 +01002270 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002271
2272 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2273
2274 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2275 IPA_RSL[0].clear;
2276
2277 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002278 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 +01002279 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002280 [] 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 +01002281 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2282 }
2283
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002284 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002285 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002286}
2287
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002288/* Verify T(iar) triggers and releases the channel */
2289testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2290 var DchanTuple dt;
2291
2292 /* Set T(iar) in BSC low enough that it will trigger before other side
2293 has time to keep alive with a T(ias). Keep recommended ratio of
2294 T(iar) >= T(ias)*2 */
2295 g_bsc_sccp_timer_ias := 2;
2296 g_bsc_sccp_timer_iar := 5;
2297
2298 f_init(1);
2299
2300 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2301 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002302 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002303}
2304
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002305private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2306runs on test_CT
2307{
2308 var DchanTuple dt;
2309
2310 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2311 var BssmapCause cause := 0;
2312 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2313 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2314 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2315 }
2316
2317 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 +02002318}
2319
2320/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2321testcase TC_chan_rel_rr_cause() runs on test_CT {
2322 f_init(1);
2323
2324 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2325 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2326 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2327 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2328 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2329 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002330
2331 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002332}
2333
Harald Welte5cd20ed2017-12-13 21:03:20 +01002334/* Test behavior if RSL EST IND for non-active channel */
2335testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2336 timer T := 2.0;
2337
Harald Welte89d42e82017-12-17 16:42:41 +01002338 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002339
2340 var octetstring l3 := '00010203040506'O;
2341 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2342 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2343
2344 T.start;
2345 alt {
2346 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2347 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2348 }
2349 [] BSSAP.receive {}
2350 [] IPA_RSL[0].receive {}
2351 [] T.timeout {}
2352 }
2353
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002354 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002355}
2356
2357/* Test behavior if RSL EST IND for invalid SAPI */
2358testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2359 var RslChannelNr chan_nr;
2360
Harald Welte89d42e82017-12-17 16:42:41 +01002361 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002362
2363 chan_nr := f_chreq_act_ack()
2364
2365 var octetstring l3 := '00010203040506'O;
2366 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2367
2368 timer T := 2.0;
2369 T.start;
2370 alt {
2371 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2372 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2373 }
2374 [] BSSAP.receive { repeat; }
2375 [] IPA_RSL[0].receive { repeat; }
2376 [] T.timeout {}
2377 }
2378
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002379 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002380}
2381
2382/* Test behavior if RSL EST IND for invalid SAPI */
2383testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2384 timer T := 2.0;
2385
Harald Welte89d42e82017-12-17 16:42:41 +01002386 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002387
2388 var RslChannelNr chan_nr := f_chreq_act_ack();
2389
2390 var octetstring l3 := '00010203040506'O;
2391 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2392
2393 T.start;
2394 alt {
2395 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2396 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2397 }
2398 [] BSSAP.receive { repeat; }
2399 [] IPA_RSL[0].receive { repeat; }
2400 [] T.timeout {}
2401 }
2402
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002403 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002404}
2405
2406/* Test behavior if RSL EST IND for invalid SACCH */
2407testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2408 timer T := 2.0;
2409
Harald Welte89d42e82017-12-17 16:42:41 +01002410 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002411
2412 var RslChannelNr chan_nr := f_chreq_act_ack();
2413
2414 var octetstring l3 := '00010203040506'O;
2415 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2416
2417 T.start;
2418 alt {
2419 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2420 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2421 }
2422 [] BSSAP.receive { repeat; }
2423 [] IPA_RSL[0].receive { repeat; }
2424 [] T.timeout {}
2425 }
2426
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002427 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002428}
2429
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002430/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2431private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2432 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2433 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2434
2435 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2436 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2437
2438 f_establish_fully(ass_cmd, exp_compl);
2439
2440 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2441 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2442 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2443 BSSAP.receive(PDU_BSSAP:{
2444 discriminator := '1'B,
2445 spare := '0000000'B,
2446 dlci := 'C3'O,
2447 lengthIndicator := ?,
2448 pdu := { dtap := '0904'O }
2449 });
2450
2451 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2452 for (var integer i := 0; i < 32; i := i + 1) {
2453 var octetstring l3 := '09'O & f_rnd_octstring(14);
2454 var template (value) RslLinkId link_id;
2455 var template (value) OCT1 dlci;
2456
2457 if (i mod 2 == 0) {
2458 /* SAPI0 on FACCH or SDCCH */
2459 link_id := ts_RslLinkID_DCCH(0);
2460 dlci := '80'O;
2461 } else {
2462 /* SAPI3 on SACCH */
2463 link_id := ts_RslLinkID_SACCH(3);
2464 dlci := 'C3'O;
2465 }
2466
2467 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002468 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002469 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002470 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002471 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002472 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002473}
2474testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2475 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2476 var MSC_ConnHdlr vc_conn;
2477
2478 f_init(1, true);
2479 f_sleep(1.0);
2480
2481 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2482 vc_conn.done;
2483
2484 f_shutdown_helper();
2485}
2486
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002487private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2488 template myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002489 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002490 float T_val := 2.0)
2491runs on test_CT {
2492 var BSSAP_N_DATA_ind rx_di;
2493 timer T;
2494
2495 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2496 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2497
2498 T.start(T_val);
2499 alt {
2500 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2501 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2502 if (not match(rx_cause, tr_cause)) {
2503 setverdict(fail, "Rx unexpected Cause IE: ",
2504 rx_cause, " vs expected ", tr_cause);
2505 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002506
2507 /* Who ever on the earth decided to define this field as two separate bits?!? */
2508 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2509 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2510 if (not match(rx_cc, cc)) {
2511 setverdict(fail, "Rx unexpected Control Channel type: ",
2512 rx_cc, " vs expected ", cc);
2513 }
2514
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002515 setverdict(pass);
2516 }
2517 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2518 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2519 }
2520 [] T.timeout {
2521 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2522 }
2523 }
2524}
2525
2526/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2527testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2528 var octetstring rnd_data := f_rnd_octstring(16);
2529 var RSL_Message rx_rsl;
2530 var DchanTuple dt;
2531
2532 f_init(1);
2533
2534 /* MS establishes a SAPI=0 link on DCCH */
2535 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2536
2537 /* MSC sends some data on (not yet established) SAPI=3 link */
2538 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2539 /* BSC attempts to establish a SAPI=3 link on DCCH */
2540 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2541
2542 /* MS sends unexpected RELease INDication on SAPI=3 */
2543 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2544 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2545 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2546
2547 /* Clean up the connection */
2548 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2549 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2550
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002551 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002552}
2553
2554/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2555testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2556 var octetstring rnd_data := f_rnd_octstring(16);
2557 var RSL_Message rx_rsl;
2558 var DchanTuple dt;
2559
2560 f_init(1);
2561
2562 /* MS establishes a SAPI=0 link on DCCH */
2563 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2564
2565 /* MSC sends some data on (not yet established) SAPI=3 link */
2566 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2567 /* BSC attempts to establish a SAPI=3 link on DCCH */
2568 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2569
2570 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2571 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2572 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2573 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2574
2575 /* Clean up the connection */
2576 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2577 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2578
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002579 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002580}
2581
2582/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2583testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2584 var octetstring rnd_data := f_rnd_octstring(16);
2585 var RSL_Message rx_rsl;
2586 var DchanTuple dt;
2587
2588 f_init(1);
2589
2590 /* MS establishes a SAPI=0 link on DCCH */
2591 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2592
2593 /* MSC sends some data on (not yet established) SAPI=3 link */
2594 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2595 /* BSC attempts to establish a SAPI=3 link on DCCH */
2596 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2597
2598 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2599 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2600
2601 /* Clean up the connection */
2602 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2603 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2604
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002605 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002606}
2607
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002608/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2609testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
2610 var octetstring rnd_data := f_rnd_octstring(16);
2611 var RSL_Message rx_rsl;
2612 var DchanTuple dt;
2613
2614 f_init(1);
2615
2616 /* MS establishes a SAPI=0 link on DCCH */
2617 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2618
2619 /* MSC sends some data on (not yet established) SAPI=3 link */
2620 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2621 /* BSC attempts to establish a SAPI=3 link on DCCH */
2622 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2623
2624 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
2625 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 +01002626 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002627
2628 /* Clean up the connection */
2629 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2630 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2631
2632 f_shutdown_helper();
2633}
2634
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002635testcase TC_si_default() runs on test_CT {
2636 f_init(0);
2637 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002638 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002639}
Harald Welte4003d112017-12-09 22:35:39 +01002640
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002641/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2642 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2643private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2644{
2645 select (earfcn_index) {
2646 case (0) {
2647 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2648 return 111;
2649 }
2650 case (1) {
2651 return 1;
2652 }
2653 case (2) {
2654 return 0;
2655 }
2656 case (3) {
2657 return 65535;
2658 }
2659 case else {
2660 return 23 * (earfcn_index - 3);
2661 }
2662 }
2663}
2664
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002665function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2666 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002667
2668 f_init(0);
2669
2670 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2671 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002672 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2673 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002674 }
2675
2676 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2677
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002678 if (not istemplatekind(expect_cells, "omit")) {
2679 /* Also check that RR Channel Release contains these EARFCNs.
2680 * (copied code from TC_chan_rel_hard_clear_csfb) */
2681 var BSSAP_N_DATA_ind rx_di;
2682 var DchanTuple dt;
2683
2684 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002685 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2686 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2687 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002688
2689 /* Instruct BSC to clear channel */
2690 var BssmapCause cause := 0;
2691 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2692
2693 /* expect Clear Complete from BSC on A */
2694 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2695 /* release the SCCP connection */
2696 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2697 }
2698
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002699 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 +02002700 }
2701
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002702 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002703 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 +02002704 }
2705}
2706
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002707private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2708{
2709 var template SI2quaterRestOctetsList si2quater := {};
2710 var integer si2quater_count := (count + 2) / 3;
2711
2712 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002713 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002714 var integer index := i / 3;
2715 var integer earfcn_index := i mod 3;
2716 if (index >= lengthof(si2quater)) {
2717 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2718 }
2719 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);
2720 }
2721
2722 return si2quater;
2723}
2724
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002725private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2726{
2727 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2728
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002729 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002730 for (var integer i := 0; i < count; i := i + 1) {
2731 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002732 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002733 }
2734
2735 return tr_CellSelIndValue_EUTRAN(cells);
2736}
2737
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002738private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2739{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002740 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002741 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002742 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2743 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002744}
2745
2746testcase TC_si2quater_2_earfcns() runs on test_CT {
2747 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002748 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002749}
2750
2751testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002752 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002753 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002754}
2755
2756testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002757 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002758 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002759}
2760
2761testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002762 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002763 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002764}
2765
2766testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002767 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002768 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002769}
2770
2771testcase TC_si2quater_12_earfcns() runs on test_CT {
2772 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002773 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002774}
2775
2776testcase TC_si2quater_23_earfcns() runs on test_CT {
2777 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002778 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002779}
2780
2781testcase TC_si2quater_32_earfcns() runs on test_CT {
2782 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002783 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002784}
2785
2786testcase TC_si2quater_33_earfcns() runs on test_CT {
2787 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002788 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002789}
2790
2791testcase TC_si2quater_42_earfcns() runs on test_CT {
2792 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002793 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002794}
2795
2796testcase TC_si2quater_48_earfcns() runs on test_CT {
2797 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002798 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002799}
2800
2801/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2802 * 48 EARFCNs. */
2803testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002804 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002805 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2806 f_init(0);
2807
2808 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002809 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2810 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002811 }
2812
2813 /* The 49th EARFCN no longer fits, expect VTY error */
2814 f_vty_enter_cfg_bts(BSCVTY, 0);
2815 var charstring vty_error;
2816 vty_error := f_vty_transceive_ret(BSCVTY,
2817 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2818 f_vty_transceive(BSCVTY, "end");
2819
2820 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2821 log("Got expected VTY error: ", vty_error);
2822 setverdict(pass);
2823 } else {
2824 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2825 }
2826
2827 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2828
2829 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002830 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 +02002831 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002832 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002833}
2834
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002835private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2836{
2837 var uint8_t count := 0;
2838 for (var integer i := 5; i < 16; i := i + 1) {
2839 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2840 count := count + 1;
2841 }
2842 }
2843 return count;
2844}
2845
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002846private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2847{
2848 var ASP_RSL_Unitdata rx_rsl_ud;
2849 var SystemInformationType1 last_si1;
2850
2851 timer T := 30.0;
2852 T.start;
2853 alt {
2854 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2855 tr_RSL_BCCH_INFO,
2856 tr_RSL_NO_SACCH_FILL,
2857 tr_RSL_SACCH_FILL))
2858 ) -> value rx_rsl_ud {
2859 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2860 if (g_system_information[rsl_idx].si1 == omit) {
2861 repeat;
2862 }
2863 last_si1 := g_system_information[rsl_idx].si1;
2864 g_system_information[rsl_idx].si1 := omit;
2865 T.stop;
2866 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002867 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002868 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2869 }
2870 return last_si1;
2871}
2872
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002873/* verify ACC rotate feature */
2874testcase TC_si_acc_rotate() runs on test_CT {
2875 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002876 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002877 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002878 var uint8_t count;
2879 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2880
2881 f_init(0, guard_timeout := 60.0);
2882
2883 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2884 "access-control-class-rotate 3",
2885 "access-control-class-rotate-quantum 1"});
2886
2887 /* Init and get first sysinfo */
2888 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2889
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002890 for (var integer i:= 0; i < 20; i := i + 1) {
2891 last_si1 := f_recv_next_si1(0);
2892 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002893 count := f_acc09_count_allowed(acc);
2894 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2895
2896 if (count != 3) {
2897 log("RSL: EXPECTED SI ACC len=3");
2898 setverdict(fail, "received SI does not match expectations");
2899 break;
2900 }
2901
2902 for (var integer j := 0; j < 10; j := j + 1) {
2903 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2904 times_allowed[j] := times_allowed[j] + 1;
2905 }
2906 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002907 }
2908
2909 for (var integer j := 0; j < 10; j := j + 1) {
2910 log("ACC", j, " allowed ", times_allowed[j], " times" );
2911 if (j != 5 and times_allowed[j] < 3) {
2912 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2913 } else if (j == 5 and times_allowed[j] > 0) {
2914 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2915 }
2916 }
2917
2918 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2919 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002920 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002921}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002922
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002923/* verify ACC startup ramp+rotate feature */
2924testcase TC_si_acc_ramp_rotate() runs on test_CT {
2925 var template SystemInformationConfig sic := SystemInformationConfig_default;
2926 var SystemInformationType1 last_si1;
2927 var AccessControlClass acc;
2928 var ASP_RSL_Unitdata rx_rsl_ud;
2929 var uint8_t count;
2930 var uint8_t prev_count;
2931 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2932
2933 f_init(0, guard_timeout := 80.0);
2934
2935 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2936 "access-control-class-rotate 0",
2937 "access-control-class-rotate-quantum 1",
2938 "access-control-class-ramping",
2939 "access-control-class-ramping-step-interval 5",
2940 "access-control-class-ramping-step-size 5"});
2941
2942 /* Init and get first sysinfo */
2943 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2944 last_si1 := g_system_information[0].si1;
2945 acc := last_si1.rach_control.acc;
2946 count := f_acc09_count_allowed(acc);
2947 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2948 while (count > 0) {
2949 last_si1 := f_recv_next_si1(0);
2950 acc := last_si1.rach_control.acc;
2951 count := f_acc09_count_allowed(acc);
2952 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2953 }
2954
2955 /* Increase adm subset size, we should see ramping start up */
2956 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2957 prev_count := 0;
2958 while (true) {
2959 last_si1 := f_recv_next_si1(0);
2960 acc := last_si1.rach_control.acc;
2961 count := f_acc09_count_allowed(acc);
2962 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2963
2964 if (prev_count > count) {
2965 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2966 break;
2967 }
2968
2969 if (count == 9) {
2970 break; /* Maximum reached (10 - 1 perm barred), done here */
2971 }
2972
2973 prev_count := count;
2974 }
2975
2976 setverdict(pass);
2977
2978 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2979 "rach access-control-class 4 allowed",
2980 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002981 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002982}
2983
Harald Welte4003d112017-12-09 22:35:39 +01002984testcase TC_ctrl_msc_connection_status() runs on test_CT {
2985 var charstring ctrl_resp;
2986
Harald Welte89d42e82017-12-17 16:42:41 +01002987 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002988
2989 /* See https://osmocom.org/issues/2729 */
2990 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002991 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002992}
2993
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002994testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2995 var charstring ctrl_resp;
2996
2997 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002998
2999 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003000 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003001}
3002
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003003/* Verify correct stats on the number of configured and connected MSCs */
3004private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3005 g_pars := f_gen_test_hdlr_pars();
3006 var StatsDExpects expect := {
3007 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3008 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3009 };
3010 f_statsd_expect(expect);
3011}
3012
3013private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3014{
3015 var MSC_ConnHdlr vc_conn;
3016
3017 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3018 f_sleep(1.0);
3019 vc_conn := f_start_handler(tc_fn);
3020 vc_conn.done;
3021
3022 /* Also verify stat exposed on CTRL interface */
3023 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3024 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3025
3026 f_shutdown_helper();
3027}
3028
3029/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3030private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3031 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3032}
3033testcase TC_stat_num_msc_connected_1() runs on test_CT {
3034 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3035}
3036
3037/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3038private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3039 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3040}
3041testcase TC_stat_num_msc_connected_2() runs on test_CT {
3042 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3043}
3044
3045/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3046private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3047 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3048}
3049testcase TC_stat_num_msc_connected_3() runs on test_CT {
3050 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3051}
3052
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003053/* Verify correct stats on the number of configured and connected MSCs */
3054private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
3055 g_pars := f_gen_test_hdlr_pars();
3056 var StatsDExpects expect := {
3057 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3058 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3059 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
3060 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3061 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
3062 };
3063 f_statsd_expect(expect);
3064}
3065
3066private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
3067 var MSC_ConnHdlr vc_conn;
3068
3069 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3070 f_sleep(1.0);
3071 vc_conn := f_start_handler(tc_fn);
3072 vc_conn.done;
3073
3074 /* Also verify stat exposed on CTRL interface */
3075 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3076 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
3077 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
3078 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
3079
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003080 /* Verify rf_states exposed on CTRL interface */
3081 var charstring expect_net_rf_states := "";
3082 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
3083 var charstring expect_bts_rf_states := int2str(i) & ",0,";
3084 if (i < NUM_BTS) {
3085 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3086 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3087 } else {
3088 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3089 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3090 }
3091 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3092 expect_bts_rf_states := expect_bts_rf_states & "on,";
3093 if (i < nr_bts) {
3094 /* For BTS where RSL is connected, the RSL state will be "up" */
3095 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3096 } else {
3097 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3098 }
3099
3100 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3101 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3102 }
3103 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3104
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003105 f_shutdown_helper();
3106}
3107
3108/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3109private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3110 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3111}
3112testcase TC_stat_num_bts_connected_1() runs on test_CT {
3113 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3114}
3115
3116/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3117private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3118 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3119}
3120testcase TC_stat_num_bts_connected_2() runs on test_CT {
3121 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3122}
3123
3124/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3125private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3126 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3127}
3128testcase TC_stat_num_bts_connected_3() runs on test_CT {
3129 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3130}
3131
Harald Welte4003d112017-12-09 22:35:39 +01003132testcase TC_ctrl() runs on test_CT {
3133 var charstring ctrl_resp;
3134
Harald Welte89d42e82017-12-17 16:42:41 +01003135 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003136
3137 /* all below values must match the osmo-bsc.cfg config file used */
3138
Harald Welte6a129692018-03-17 17:30:14 +01003139 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3140 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003141 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003142
3143 var integer bts_nr := 0;
3144 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3145 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3146 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3147 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3148 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3149 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3150 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3151
3152 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3153 f_sleep(2.0);
3154 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3155 setverdict(fail, "oml-uptime not incrementing as expected");
3156 }
3157 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3158
3159 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3160
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003161 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003162}
3163
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003164/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3165 "location-state" over the SCCPlite IPA conn */
3166testcase TC_ctrl_location() runs on test_CT {
3167 var MSC_ConnHdlr vc_conn;
3168 var integer bts_nr := 0;
3169
3170 f_init(1, true);
3171 f_sleep(1.0);
3172
3173 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3174 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3175 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3176
3177 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3178 f_sleep(2.0);
3179
3180 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3181 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3182 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3183
3184 /* should match the one from config */
3185 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3186
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003187 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003188}
3189
Harald Welte6f521d82017-12-11 19:52:02 +01003190
3191/***********************************************************************
3192 * Paging Testing
3193 ***********************************************************************/
3194
3195type record Cell_Identity {
3196 GsmMcc mcc,
3197 GsmMnc mnc,
3198 GsmLac lac,
3199 GsmCellId ci
3200};
Harald Welte24135bd2018-03-17 19:27:53 +01003201private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003202private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003203
Harald Welte5d1a2202017-12-13 19:51:29 +01003204type set of integer BtsIdList;
3205
3206private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3207 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3208 if (bts_id == bts_ids[j]) {
3209 return true;
3210 }
3211 }
3212 return false;
3213}
Harald Welte6f521d82017-12-11 19:52:02 +01003214
3215/* core paging test helper function; used by most paging test cases */
3216private function f_pageing_helper(hexstring imsi,
3217 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003218 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003219 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003220 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003221{
3222 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003223 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003224 var RSL_Message rx_rsl;
3225 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003226 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003227
3228 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003229
3230 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003231 for (i := 0; i < NUM_BTS; i := i + 1) {
3232 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003233 }
Harald Welte6f521d82017-12-11 19:52:02 +01003234
3235 if (isvalue(rsl_chneed)) {
3236 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3237 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3238 } else {
3239 bssmap_chneed := omit;
3240 }
3241
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003242 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3243 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003244
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003245 if (not istemplatekind(tmsi, "omit")) {
3246 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003247 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003248 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003249 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003250
Harald Welte5d1a2202017-12-13 19:51:29 +01003251 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003252 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003253 /* check channel type, paging group */
3254 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3255 setverdict(fail, "Paging for wrong paging group");
3256 }
3257 if (ispresent(rsl_chneed) and
3258 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3259 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3260 }
Harald Welte6f521d82017-12-11 19:52:02 +01003261 }
Harald Welte2fccd982018-01-31 15:48:19 +01003262 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003263 /* do a quick check on all not-included BTSs if they received paging */
3264 for (i := 0; i < NUM_BTS; i := i + 1) {
3265 timer T := 0.1;
3266 if (f_bts_in_list(i, bts_ids)) {
3267 continue;
3268 }
3269 T.start;
3270 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003271 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003272 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3273 }
3274 [] IPA_RSL[i].receive { repeat; }
3275 [] T.timeout { }
3276 }
Harald Welte6f521d82017-12-11 19:52:02 +01003277 }
3278
3279 setverdict(pass);
3280}
3281
Harald Welte5d1a2202017-12-13 19:51:29 +01003282const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003283const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003284const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3285const BtsIdList c_BtsId_LAC2 := { 2 };
3286
Harald Welte6f521d82017-12-11 19:52:02 +01003287/* PAGING by IMSI + TMSI */
3288testcase TC_paging_imsi_nochan() runs on test_CT {
3289 var BSSMAP_FIELD_CellIdentificationList cid_list;
3290 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003291 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003292 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003293}
3294
3295/* PAGING by IMSI + TMSI */
3296testcase TC_paging_tmsi_nochan() runs on test_CT {
3297 var BSSMAP_FIELD_CellIdentificationList cid_list;
3298 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003299 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003300 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003301}
3302
3303/* Paging with different "channel needed' values */
3304testcase TC_paging_tmsi_any() runs on test_CT {
3305 var BSSMAP_FIELD_CellIdentificationList cid_list;
3306 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003307 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003308 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003309}
3310testcase TC_paging_tmsi_sdcch() runs on test_CT {
3311 var BSSMAP_FIELD_CellIdentificationList cid_list;
3312 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003313 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003314 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003315}
3316testcase TC_paging_tmsi_tch_f() runs on test_CT {
3317 var BSSMAP_FIELD_CellIdentificationList cid_list;
3318 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003319 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003320 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003321}
3322testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3323 var BSSMAP_FIELD_CellIdentificationList cid_list;
3324 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003325 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003326 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003327}
3328
3329/* Paging by CGI */
3330testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3331 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3332 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003333 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003334 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003335}
3336
3337/* Paging by LAC+CI */
3338testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3339 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3340 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003341 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003342 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003343}
3344
3345/* Paging by CI */
3346testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3347 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3348 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003349 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003350 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003351}
3352
3353/* Paging by LAI */
3354testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3355 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3356 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003357 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003358 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003359}
3360
3361/* Paging by LAC */
3362testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3363 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3364 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003365 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003366 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003367}
3368
3369/* Paging by "all in BSS" */
3370testcase TC_paging_imsi_nochan_all() runs on test_CT {
3371 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3372 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003373 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003374 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003375}
3376
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003377/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003378testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3379 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3380 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 +01003381 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003382 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003383}
Harald Welte6f521d82017-12-11 19:52:02 +01003384
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003385/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003386testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3387 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3388 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003389 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003390 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003391}
3392
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003393/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003394testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3395 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3396 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003397 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003398 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003399}
3400
Harald Welte6f521d82017-12-11 19:52:02 +01003401/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003402testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3403 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3404 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3405 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003406 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003407}
3408
3409/* Paging on empty list: Verify none of them page */
3410testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3411 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3412 cid_list := { cIl_LAC := { } };
3413 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003414 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003415}
3416
Stefan Sperling049a86e2018-03-20 15:51:00 +01003417/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3418testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3419 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3420 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3421 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3422 f_shutdown_helper();
3423}
3424
Harald Welte6f521d82017-12-11 19:52:02 +01003425/* Verify paging retransmission interval + count */
3426/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003427/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003428
Harald Weltee65d40e2017-12-13 00:09:06 +01003429/* Verify PCH load */
3430testcase TC_paging_imsi_load() runs on test_CT {
3431 var BSSMAP_FIELD_CellIdentificationList cid_list;
3432 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003433 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003434 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003435 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003436
3437 /* tell BSC there is no paging space anymore */
3438 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003439 f_sleep(0.2);
3440 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003441
3442 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3443 * there would be 8 retransmissions during 4 seconds */
3444 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003445 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003446 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003447 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003448 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003449 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003450 }
Harald Welte2caa1062018-03-17 18:19:05 +01003451 [] T_retrans.timeout {
3452 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3453 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3454 T_retrans.start;
3455 repeat;
3456 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003457 [] T.timeout {
3458 setverdict(pass);
3459 }
3460 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003461
3462 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003463}
3464
Harald Welte235ebf12017-12-15 14:18:16 +01003465/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003466testcase TC_paging_counter() runs on test_CT {
3467 var BSSMAP_FIELD_CellIdentificationList cid_list;
3468 timer T := 4.0;
3469 var integer i;
3470 var integer paging_attempted_bsc;
3471 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003472 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003473 var integer paging_expired_bts[NUM_BTS];
3474 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3475
3476 f_init();
3477
3478 /* read counters before paging */
3479 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003480 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3481 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3482 }
Harald Welte1ff69992017-12-14 12:31:17 +01003483 for (i := 0; i < NUM_BTS; i := i+1) {
3484 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3485 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3486 }
3487
3488 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3489
3490 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3491 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3492 for (i := 0; i < NUM_BTS; i := i+1) {
3493 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3494 paging_attempted_bts[i]+1);
3495 }
3496
3497 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3498 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003499 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3500 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3501 }
Harald Welte1ff69992017-12-14 12:31:17 +01003502 for (i := 0; i < NUM_BTS; i := i+1) {
3503 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3504 paging_expired_bts[i]+1);
3505 }
Harald Welte1ff69992017-12-14 12:31:17 +01003506
Philipp Maier282ca4b2018-02-27 17:17:00 +01003507 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003508}
3509
3510
Harald Welte10985002017-12-12 09:29:15 +01003511/* Verify paging stops after A-RESET */
3512testcase TC_paging_imsi_a_reset() runs on test_CT {
3513 var BSSMAP_FIELD_CellIdentificationList cid_list;
3514 timer T := 3.0;
3515 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003516 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003517
3518 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003519 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 +01003520 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003521 [] 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 +01003522 [] BSSAP.receive { repeat; }
3523 }
3524
Daniel Willmanncbef3982018-07-30 09:22:40 +02003525 /* Wait to avoid a possible race condition if a paging message is
3526 * received right before the reset ACK. */
3527 f_sleep(0.2);
3528
Harald Welte10985002017-12-12 09:29:15 +01003529 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003530 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3531 IPA_RSL[i].clear;
3532 }
Harald Welte10985002017-12-12 09:29:15 +01003533
3534 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3535 T.start;
3536 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003537 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003538 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003539 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003540 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003541 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003542 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003543 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003544 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003545 [] IPA_RSL[2].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 }
Harald Welte10985002017-12-12 09:29:15 +01003549 [] T.timeout {
3550 setverdict(pass);
3551 }
3552 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003553
3554 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003555}
Harald Welteae026692017-12-09 01:03:01 +01003556
Philipp Maierf45824a2019-08-14 14:44:10 +02003557/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3558 * paging response we can not know which MSC is in charge, so we will blindly
3559 * pick the first configured MSC. This behavior is required in order to make
3560 * MT-CSFB calls working because in those cases the BSC can not know that the
3561 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3562 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003563 */
3564testcase TC_paging_resp_unsol() runs on test_CT {
3565
3566 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003567 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003568
3569 var BSSAP_N_CONNECT_ind rx_c_ind;
3570 var DchanTuple dt;
3571 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003572 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003573
3574 /* Send CHAN RQD and wait for allocation; acknowledge it */
3575 dt.rsl_chan_nr := f_chreq_act_ack();
3576
3577 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3578 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3579
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003580
Philipp Maierf45824a2019-08-14 14:44:10 +02003581 /* Expevct a CR with a matching Paging response on the A-Interface */
3582 T.start;
3583 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003584 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003585 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003586 dt.sccp_conn_id := rx_c_ind.connectionId;
3587 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003588 }
3589 [] BSSAP.receive {
3590 setverdict(fail, "Received unexpected message on A-Interface!");
3591 }
3592 [] T.timeout {
3593 setverdict(fail, "Received nothing on A-Interface!");
3594 }
3595 }
3596
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003597 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003598 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003599}
3600
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003601/* Test RSL link drop causes counter increment */
3602testcase TC_rsl_drop_counter() runs on test_CT {
3603 var integer rsl_fail;
3604
Harald Welte89d42e82017-12-17 16:42:41 +01003605 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003606
3607 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3608
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01003609 f_ipa_rsl_stop(bts[0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003610
3611 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3612
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003613 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003614}
3615
3616/* TODO: Test OML link drop causes counter increment */
3617
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003618/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3619function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3620 timer T := 10.0;
3621
3622 bts[0].rsl.id := "IPA-0-RSL";
Harald Welte71389132021-12-09 21:58:18 +01003623 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA") alive;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003624 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3625 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003626 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003627
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003628 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003629
3630 f_init_mgcp("VirtMSC");
3631
3632 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3633 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3634 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3635 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3636
3637 /* wait for IPA OML link to connect and then disconnect */
3638 T.start;
3639 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003640 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003641 T.stop;
3642 return true;
3643 }
3644 [] IPA_RSL[0].receive { repeat }
3645 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003646 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003647 }
3648 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003649 return false;
3650}
3651
3652/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3653testcase TC_rsl_unknown_unit_id() runs on test_CT {
3654 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3655 setverdict(pass);
3656 } else {
3657 setverdict(fail, "Timeout RSL waiting for connection to close");
3658 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003659 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003660}
3661
3662
3663/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3664testcase TC_oml_unknown_unit_id() runs on test_CT {
3665 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3666 setverdict(pass);
3667 } else {
3668 setverdict(fail, "Timeout OML waiting for connection to close");
3669 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003670 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003671}
3672
3673
Harald Weltec1a2fff2017-12-17 11:06:19 +01003674/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003675 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003676 ***********************************************************************/
3677
Harald Welte6811d102019-04-14 22:23:14 +02003678import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003679import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003680import from RSL_Emulation all;
3681import from MSC_ConnectionHandler all;
3682
3683type function void_fn(charstring id) runs on MSC_ConnHdlr;
3684
Harald Welte336820c2018-05-31 20:34:52 +02003685/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003686private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3687 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003688 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003689 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003690 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003691 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003692 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3693 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3694 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003695 if (isvalue(bts[2])) {
3696 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3697 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3698 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003699 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003700 if (mp_enable_lcs_tests) {
3701 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3702 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3703 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003704 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003705 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003706 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003707}
3708
Neels Hofmeyrda436782021-07-20 22:09:06 +02003709function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003710runs on test_CT return MSC_ConnHdlr {
3711 var charstring id := testcasename();
3712 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003713 var integer bssap_idx := 0;
3714 if (isvalue(pars)) {
3715 bssap_idx := valueof(pars).mscpool.bssap_idx;
3716 }
Harald Welte336820c2018-05-31 20:34:52 +02003717 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003718 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003719 return vc_conn;
3720}
3721
3722function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3723runs on test_CT return MSC_ConnHdlr {
3724 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003725 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003726 return vc_conn;
3727}
3728
Neels Hofmeyrda436782021-07-20 22:09:06 +02003729function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3730runs on test_CT return MSC_ConnHdlr {
3731 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3732}
3733
Harald Weltea0630032018-03-20 21:09:55 +01003734/* first function inside ConnHdlr component; sets g_pars + starts function */
3735private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3736runs on MSC_ConnHdlr {
3737 if (isvalue(pars)) {
3738 g_pars := valueof(pars);
3739 }
3740 fn.apply(id);
3741}
3742
Oliver Smith26a3db72021-07-09 13:51:29 +02003743private function f_vty_encryption_a5(charstring options) runs on test_CT {
3744 f_vty_transceive(BSCVTY, "configure terminal");
3745 f_vty_transceive(BSCVTY, "network");
3746 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3747 f_vty_transceive(BSCVTY, "exit");
3748 f_vty_transceive(BSCVTY, "exit");
3749}
3750
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003751const charstring VTY_A5_DEFAULT := "0 1 3";
3752
Oliver Smith26a3db72021-07-09 13:51:29 +02003753private function f_vty_encryption_a5_reset() runs on test_CT {
3754 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003755 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003756}
3757
Harald Welte3c86ea02018-05-10 22:28:05 +02003758/* Establish signalling channel (non-assignment case) followed by cipher mode */
3759private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003760 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3761 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003762 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003763 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3764 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3765 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3766 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003767
Philipp Maier23000732018-05-18 11:25:37 +02003768 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003769 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003770}
3771testcase TC_ciph_mode_a5_0() runs on test_CT {
3772 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003773 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003774 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3775
3776 f_init(1, true);
3777 f_sleep(1.0);
3778 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3779 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003780 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003781}
3782testcase TC_ciph_mode_a5_1() runs on test_CT {
3783 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003784 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003785 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3786
3787 f_init(1, true);
3788 f_sleep(1.0);
3789 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3790 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003791 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003792}
Oliver Smith50b98122021-07-09 15:00:28 +02003793/* OS#4975: verify that A5/2 is preferred over A5/0 */
3794testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3795 var MSC_ConnHdlr vc_conn;
3796 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3797
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003798 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003799
3800 f_init(1, true);
3801 f_vty_encryption_a5("0 1 2 3");
3802 f_sleep(1.0);
3803 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3804 vc_conn.done;
3805 f_vty_encryption_a5_reset();
3806 f_shutdown_helper();
3807}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003808/* OS#4975: verify that A5/1 is preferred over A5/2 */
3809testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3810 var MSC_ConnHdlr vc_conn;
3811 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3812
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003813 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003814
3815 f_init(1, true);
3816 f_vty_encryption_a5("1 2");
3817 f_sleep(1.0);
3818 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3819 vc_conn.done;
3820 f_vty_encryption_a5_reset();
3821 f_shutdown_helper();
3822}
Harald Welte3c86ea02018-05-10 22:28:05 +02003823testcase TC_ciph_mode_a5_3() runs on test_CT {
3824 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003825 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003826 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3827
3828 f_init(1, true);
3829 f_sleep(1.0);
3830 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3831 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003832 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003833}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003834/* Establish a Signalling channel with A5/4 encryption. */
3835testcase TC_ciph_mode_a5_4() runs on test_CT {
3836 var MSC_ConnHdlr vc_conn;
3837 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3838 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003839
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003840 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003841 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003842 f_sleep(1.0);
3843 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3844 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003845 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003846 f_shutdown_helper();
3847}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003848/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3849private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3850 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3851 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3852 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3853 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3854
3855 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003856 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003857}
3858testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3859 var MSC_ConnHdlr vc_conn;
3860 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3861
3862 f_init(1, true);
3863 f_sleep(1.0);
3864 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3865 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003866 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003867}
3868
Harald Welte3c86ea02018-05-10 22:28:05 +02003869
3870/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003871private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003872 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3873 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003874
Harald Welte552620d2017-12-16 23:21:36 +01003875 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3876 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003877
Harald Weltea0630032018-03-20 21:09:55 +01003878 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003879 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003880}
Harald Welte552620d2017-12-16 23:21:36 +01003881testcase TC_assignment_fr_a5_0() runs on test_CT {
3882 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003883 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003884 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003885
Harald Welte89d42e82017-12-17 16:42:41 +01003886 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003887 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003888 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003889 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003890 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003891}
Harald Welte552620d2017-12-16 23:21:36 +01003892testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003893 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003894 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003895 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003896
Harald Welte89d42e82017-12-17 16:42:41 +01003897 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003898 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003899 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3900 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003901 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003902}
3903testcase TC_assignment_fr_a5_3() runs on test_CT {
3904 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003905 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003906 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003907
Harald Welte651fcdc2018-05-10 20:23:16 +02003908 f_init(1, true);
3909 f_sleep(1.0);
3910 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003911 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003912 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003913}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003914/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3915testcase TC_assignment_fr_a5_4() runs on test_CT {
3916 var MSC_ConnHdlr vc_conn;
3917 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3918 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3919
3920 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003921 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003922 f_sleep(1.0);
3923 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3924 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003925 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003926 f_shutdown_helper();
3927}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003928
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003929/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3930testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3931 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3932 var MSC_ConnHdlr vc_conn;
3933
3934 f_init(1, true);
3935 f_sleep(1.0);
3936
3937 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3938 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3939 vc_conn.done;
3940 f_shutdown_helper();
3941}
3942
Harald Welte552620d2017-12-16 23:21:36 +01003943/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3944private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003945 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003946 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003947 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003948
3949 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003950 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3951
Harald Weltea0630032018-03-20 21:09:55 +01003952 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003953 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003954}
Harald Welte552620d2017-12-16 23:21:36 +01003955testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3956 var MSC_ConnHdlr vc_conn;
3957
Harald Welte89d42e82017-12-17 16:42:41 +01003958 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003959 f_sleep(1.0);
3960
Harald Welte8863fa12018-05-10 20:15:27 +02003961 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003962 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003963 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003964}
3965
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003966private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3967 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3968 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003969
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003970 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3971 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3972
3973 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3974
3975 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003976
3977 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3978 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3979
3980 f_create_chan_and_exp();
3981 /* we should now have a COMPL_L3 at the MSC */
3982
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003983 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003984 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003985 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003986}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003987testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3988 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003989 var MSC_ConnHdlr vc_conn;
3990
Harald Welte89d42e82017-12-17 16:42:41 +01003991 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003992 f_sleep(1.0);
3993
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003994 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003995 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003996 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003997 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003998}
3999
4000
Harald Welte4532e0a2017-12-23 02:05:44 +01004001private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004002 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004003 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004004 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004005 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004006
4007 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004008 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004009
4010 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004011 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4012 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004013 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4014 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4015 };
4016 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004017 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004018}
4019
4020testcase TC_assignment_sign() runs on test_CT {
4021 var MSC_ConnHdlr vc_conn;
4022
4023 f_init(1, true);
4024 f_sleep(1.0);
4025
Harald Welte8863fa12018-05-10 20:15:27 +02004026 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004027 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004028 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004029}
4030
Harald Welte60aa5762018-03-21 19:33:13 +01004031/***********************************************************************
4032 * Codec (list) testing
4033 ***********************************************************************/
4034
4035/* check if the given rsl_mode is compatible with the a_elem */
4036private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4037return boolean {
4038 select (a_elem.codecType) {
4039 case (GSM_FR) {
4040 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4041 return true;
4042 }
4043 }
4044 case (GSM_HR) {
4045 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4046 return true;
4047 }
4048 }
4049 case (GSM_EFR) {
4050 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4051 return true;
4052 }
4053 }
4054 case (FR_AMR) {
4055 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4056 return true;
4057 }
4058 }
4059 case (HR_AMR) {
4060 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4061 return true;
4062 }
4063 }
4064 case else { }
4065 }
4066 return false;
4067}
4068
4069/* check if the given rsl_mode is compatible with the a_list */
4070private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4071return boolean {
4072 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4073 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4074 return true;
4075 }
4076 }
4077 return false;
4078}
4079
4080/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004081function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004082return BSSMAP_IE_ChannelType {
4083 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4084 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4085 select (a_elem.codecType) {
4086 case (GSM_FR) {
4087 ret.channelRateAndType := ChRate_TCHF;
4088 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4089 }
4090 case (GSM_HR) {
4091 ret.channelRateAndType := ChRate_TCHH;
4092 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4093 }
4094 case (GSM_EFR) {
4095 ret.channelRateAndType := ChRate_TCHF;
4096 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4097 }
4098 case (FR_AMR) {
4099 ret.channelRateAndType := ChRate_TCHF;
4100 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4101 }
4102 case (HR_AMR) {
4103 ret.channelRateAndType := ChRate_TCHH;
4104 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4105 }
4106 case else {
4107 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004108 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004109 }
4110 }
4111 return ret;
4112}
4113
Harald Weltea63b9102018-03-22 20:36:16 +01004114private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4115return template RSL_IE_Body {
4116 var template RSL_IE_Body mode_ie := {
4117 chan_mode := {
4118 len := ?,
4119 reserved := ?,
4120 dtx_d := ?,
4121 dtx_u := ?,
4122 spd_ind := RSL_SPDI_SPEECH,
4123 ch_rate_type := -,
4124 coding_alg_rate := -
4125 }
4126 }
4127
4128 select (a_elem.codecType) {
4129 case (GSM_FR) {
4130 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4131 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4132 }
4133 case (GSM_HR) {
4134 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4135 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4136 }
4137 case (GSM_EFR) {
4138 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4139 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4140 }
4141 case (FR_AMR) {
4142 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4143 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4144 }
4145 case (HR_AMR) {
4146 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4147 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4148 }
4149 }
4150 return mode_ie;
4151}
4152
Harald Welte60aa5762018-03-21 19:33:13 +01004153type record CodecListTest {
4154 BSSMAP_IE_SpeechCodecList codec_list,
4155 charstring id
4156}
4157type record of CodecListTest CodecListTests
4158
4159private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004160 f_assignment_codec(id);
4161}
4162
4163private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004164 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
4165 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01004166
4167 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004168 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004169 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4170 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4171 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004172 if (isvalue(g_pars.expect_mr_s0_s7)) {
4173 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4174 g_pars.expect_mr_s0_s7;
4175 }
Harald Welte79f3f542018-05-25 20:02:37 +02004176 }
Harald Welte60aa5762018-03-21 19:33:13 +01004177 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4178 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004179 log("expecting ASS COMPL like this: ", exp_compl);
4180
4181 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004182
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004183 if (not g_pars.expect_channel_mode_modify) {
4184 /* Verify that the RSL-side activation actually matches our expectations */
4185 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004186
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004187 var RSL_IE_Body mode_ie;
4188 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4189 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004190 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004191 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004192 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4193 if (not match(mode_ie, t_mode_ie)) {
4194 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4195 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004196 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004197
4198 var RSL_IE_Body mr_conf;
4199 if (g_pars.expect_mr_conf_ie != omit) {
4200 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4201 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4202 mtc.stop;
4203 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004204 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004205
4206 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4207 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4208 g_pars.expect_mr_conf_ie);
4209 }
4210 } else {
4211 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4212 log("found RSL MR CONFIG IE: ", mr_conf);
4213 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4214 mtc.stop;
4215 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004216 }
4217 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004218
4219 if (do_perform_clear) {
4220 f_perform_clear();
4221 }
Harald Welte60aa5762018-03-21 19:33:13 +01004222}
4223
Philipp Maierd0e64b02019-03-13 14:15:23 +01004224private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4225
4226 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4227 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4228
4229 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004230 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004231 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4232 }
4233 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4234 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4235 log("expecting ASS FAIL like this: ", exp_fail);
4236
4237 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004238 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004239}
4240
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004241const CounterNameVals counternames_bsc_bts_assignment := {
4242 { "assignment:attempted", 0 },
4243 { "assignment:completed", 0 },
4244 { "assignment:stopped", 0 },
4245 { "assignment:no_channel", 0 },
4246 { "assignment:timeout", 0 },
4247 { "assignment:failed", 0 },
4248 { "assignment:error", 0 }
4249};
4250
4251const CounterNameVals counternames_bts_assignment := {
4252 { "assignment:attempted_sign", 0 },
4253 { "assignment:attempted_speech", 0 },
4254 { "assignment:completed_sign", 0 },
4255 { "assignment:completed_speech", 0 },
4256 { "assignment:stopped_sign", 0 },
4257 { "assignment:stopped_speech", 0 },
4258 { "assignment:no_channel_sign", 0 },
4259 { "assignment:no_channel_speech", 0 },
4260 { "assignment:timeout_sign", 0 },
4261 { "assignment:timeout_speech", 0 },
4262 { "assignment:failed_sign", 0 },
4263 { "assignment:failed_speech", 0 },
4264 { "assignment:error_sign", 0 },
4265 { "assignment:error_speech", 0 }
4266};
4267
4268function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4269 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4270 f_ctrs_bts_init(bts_count, bts_names);
4271 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4272}
4273
Harald Welte60aa5762018-03-21 19:33:13 +01004274testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004275 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004276 var MSC_ConnHdlr vc_conn;
4277
4278 f_init(1, true);
4279 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004280 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004281
4282 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004283 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004284 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004285
4286 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4287 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4288 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4289 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4290 f_ctrs_bts_verify();
4291
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004292 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004293}
4294
4295testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004296 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004297 var MSC_ConnHdlr vc_conn;
4298
4299 f_init(1, true);
4300 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004301 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004302
4303 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004304 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004305 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004306
4307 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4308 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4309 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4310 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4311 f_ctrs_bts_verify();
4312
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004313 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004314}
4315
4316testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004317 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004318 var MSC_ConnHdlr vc_conn;
4319
4320 f_init(1, true);
4321 f_sleep(1.0);
4322
4323 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004324 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004325 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004326 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004327}
4328
Philipp Maierd0e64b02019-03-13 14:15:23 +01004329/* Allow 5,90k only (current default config) */
4330private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004331 f_vty_cfg_msc(BSCVTY, 0, {
4332 "amr-config 12_2k forbidden",
4333 "amr-config 10_2k forbidden",
4334 "amr-config 7_95k forbidden",
4335 "amr-config 7_40k forbidden",
4336 "amr-config 6_70k forbidden",
4337 "amr-config 5_90k allowed",
4338 "amr-config 5_15k forbidden",
4339 "amr-config 4_75k forbidden"
4340 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004341}
4342
4343/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4344 * ("Config-NB-Code = 1") */
4345private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004346 f_vty_cfg_msc(BSCVTY, 0, {
4347 "amr-config 12_2k allowed",
4348 "amr-config 10_2k forbidden",
4349 "amr-config 7_95k forbidden",
4350 "amr-config 7_40k allowed",
4351 "amr-config 6_70k forbidden",
4352 "amr-config 5_90k allowed",
4353 "amr-config 5_15k forbidden",
4354 "amr-config 4_75k allowed"
4355 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004356}
4357
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004358private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4359 var charstring tch;
4360 if (fr) {
4361 tch := "tch-f";
4362 } else {
4363 tch := "tch-h";
4364 }
4365 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4366}
4367
4368/* Set the AMR start-mode for this TCH back to the default configuration. */
4369private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4370 f_vty_amr_start_mode_set(fr, "auto");
4371}
4372
Harald Welte60aa5762018-03-21 19:33:13 +01004373testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004374 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004375 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004376
4377 /* Note: This setups the codec configuration. The parameter payload in
4378 * mr_conf must be consistant with the parameter codecElements in pars
4379 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004380 var RSL_IE_Body mr_conf := {
4381 other := {
4382 len := 2,
4383 payload := '2804'O
4384 }
4385 };
Harald Welte60aa5762018-03-21 19:33:13 +01004386
Philipp Maier7695a0d2018-09-27 17:52:14 +02004387 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004388 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004389 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4390 pars.expect_mr_conf_ie := mr_conf;
4391
Harald Welte60aa5762018-03-21 19:33:13 +01004392 f_init(1, true);
4393 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004394 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004395 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004396
Harald Welte8863fa12018-05-10 20:15:27 +02004397 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004398 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004399
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004400 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4401 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4402 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4403 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4404 f_ctrs_bts_verify();
4405
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004406 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004407 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004408}
4409
4410testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004411 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004412 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004413
4414 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004415 var RSL_IE_Body mr_conf := {
4416 other := {
4417 len := 2,
4418 payload := '2804'O
4419 }
4420 };
Harald Welte60aa5762018-03-21 19:33:13 +01004421
Philipp Maier7695a0d2018-09-27 17:52:14 +02004422 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004423 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004424 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4425 pars.expect_mr_conf_ie := mr_conf;
4426
Harald Welte60aa5762018-03-21 19:33:13 +01004427 f_init(1, true);
4428 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004429 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004430 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004431
Harald Welte8863fa12018-05-10 20:15:27 +02004432 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004433 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004434
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004435 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4436 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4437 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4438 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4439 f_ctrs_bts_verify();
4440
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004441 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004442 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004443}
4444
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004445/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4446testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4447 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4448 var MSC_ConnHdlr vc_conn;
4449
4450 f_init(1, true);
4451 f_sleep(1.0);
4452
4453 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4454 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4455 * expecting a Channel Mode Modify if the channel type is compatible. */
4456 f_disable_all_sdcch();
4457 f_disable_all_tch_h();
4458
4459 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4460 pars.expect_channel_mode_modify := true;
4461 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4462 vc_conn.done;
4463
4464 f_enable_all_sdcch();
4465 f_enable_all_tch();
4466 f_shutdown_helper();
4467}
4468
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004469/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4470testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4471 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4472 var MSC_ConnHdlr vc_conn;
4473
4474 var RSL_IE_Body mr_conf := {
4475 other := {
4476 len := 2,
4477 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4478 }
4479 };
4480
4481 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4482 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4483 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4484 pars.expect_mr_conf_ie := mr_conf;
4485
4486 f_init(1, true);
4487 f_sleep(1.0);
4488
4489 /* First set nonzero start mode bits */
4490 f_vty_amr_start_mode_set(true, "4");
4491 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4492 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4493 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4494 f_vty_amr_start_mode_set(true, "auto");
4495
4496 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4497 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004498
4499 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4500 f_vty_amr_start_mode_set(true, "1");
4501 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004502 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004503}
4504
Neels Hofmeyr21863562020-11-26 00:34:33 +00004505function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4506 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004507runs on test_CT {
4508
4509 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4510 var MSC_ConnHdlr vc_conn;
4511
4512 /* See note above */
4513 var RSL_IE_Body mr_conf := {
4514 other := {
4515 len := lengthof(mrconf),
4516 payload := mrconf
4517 }
4518 };
4519
4520 if (fr) {
4521 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4522 } else {
4523 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4524 }
4525 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4526 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4527 pars.expect_mr_conf_ie := mr_conf;
4528 pars.expect_mr_s0_s7 := exp_s8_s0;
4529
4530 f_init(1, true);
4531 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004532 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004533 f_sleep(1.0);
4534
4535 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4536 vc_conn.done;
4537 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004538 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004539}
4540
4541function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4542runs on test_CT {
4543
4544 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4545 var MSC_ConnHdlr vc_conn;
4546
4547 if (fr) {
4548 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4549 } else {
4550 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4551 }
4552 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4553 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4554
4555 f_init(1, true);
4556 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004557 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004558 f_sleep(1.0);
4559
4560 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4561 vc_conn.done;
4562 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004563 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004564}
4565
4566
4567/* Set S1, we expect an AMR multirate configuration IE with all four rates
4568 * set. */
4569testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004570 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004571 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004572}
4573
4574/* Set S1, we expect an AMR multirate configuration IE with the lower three
4575 * rates set. */
4576testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004577 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004578 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004579}
4580
4581/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4582 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4583testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004584 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004585 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004586}
4587
4588/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4589 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4590testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004591 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004592 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004593}
4594
4595/* The following block of tests selects more and more rates until all four
4596 * possible rates are in the active set (full rate) */
4597testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004598 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004599 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004600}
4601
4602testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004603 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004604 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004605}
4606
4607testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004608 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004609 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004610}
4611
4612testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004613 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004614 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004615}
4616
4617/* The following block of tests selects more and more rates until all three
4618 * possible rates are in the active set (half rate) */
4619testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004620 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004621 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004622}
4623
4624testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004625 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004626 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004627}
4628
4629testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004630 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004631 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004632}
4633
4634/* The following block tests what happens when the MSC does offer rate
4635 * configurations that are not supported by the BSC. Normally such situations
4636 * should not happen because the MSC gets informed by the BSC in advance via
4637 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4638 * to offer rates that are not applicable anyway. */
4639
4640testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004641 /* Try to include 12,2k in into the active set even though the channel
4642 * is half rate only. The BSC is expected to remove the 12,0k */
4643 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004644 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004645}
4646
4647testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004648 /* See what happens when all rates are selected at once. Since then
4649 * Also S1 is selected, this setting will be prefered and we should
4650 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4651 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004652 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004653}
4654
4655testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004656 /* Same as above, but with S1 missing, the MSC is then expected to
4657 * select the currently supported rates, which are also 12.2k, 7,40k,
4658 * 5,90k, and 4,75k, into the active set. */
4659 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004660 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004661}
4662
4663testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004664 /* Try to select no rates at all */
4665 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004666 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004667}
4668
4669testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004670 /* Try to select only unsupported rates */
4671 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004672 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004673}
4674
4675testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004676 /* Try to select 12,2k for half rate */
4677 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004678 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004679}
4680
Neels Hofmeyr21863562020-11-26 00:34:33 +00004681testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4682 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4683 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004684 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004685}
4686
4687testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4688 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4689 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004690 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004691}
4692
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004693testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004694 /* "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 +00004695 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4696 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004697 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004698}
4699
4700testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004701 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4702 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004703 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004704 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004705}
4706
Philipp Maierac09bfc2019-01-08 13:41:39 +01004707private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004708 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4709 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4710 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4711 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004712}
4713
4714private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004715 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4716 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004717}
4718
4719private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004720 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4721 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4722 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4723 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4724 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4725 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004726}
4727
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004728private function f_disable_all_sdcch() runs on test_CT {
4729 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4730 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4731 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4732 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4733}
4734
4735private function f_enable_all_sdcch() runs on test_CT {
4736 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4737 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4738 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4739 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4740}
4741
Philipp Maierac09bfc2019-01-08 13:41:39 +01004742/* Allow HR only */
4743private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4744 g_pars := f_gen_test_hdlr_pars();
4745 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4746 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4747 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4748 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4749 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4750 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4751 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004752 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004753}
4754
4755/* Allow FR only */
4756private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4757 g_pars := f_gen_test_hdlr_pars();
4758 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4759 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4760 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4761 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4762 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4763 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4764 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004765 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004766}
4767
4768/* Allow HR only (expect assignment failure) */
4769private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4770 g_pars := f_gen_test_hdlr_pars();
4771 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4772 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4773 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4774 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4775 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4776 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4777 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004778 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004779}
4780
4781/* Allow FR only (expect assignment failure) */
4782private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4783 g_pars := f_gen_test_hdlr_pars();
4784 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4785 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4786 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4787 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4788 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4789 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4790 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004791 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004792}
4793
4794/* Allow FR and HR, but prefer FR */
4795private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4796 g_pars := f_gen_test_hdlr_pars();
4797 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4798 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4799 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4800 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4801 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4802 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4803 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4804 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004805 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004806}
4807
4808/* Allow FR and HR, but prefer HR */
4809private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4810 g_pars := f_gen_test_hdlr_pars();
4811 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4812 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4813 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4814 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4815 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4816 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4817 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4818 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004819 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004820}
4821
4822/* Allow FR and HR, but prefer FR */
4823private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4824 g_pars := f_gen_test_hdlr_pars();
4825 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4826 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4827 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4828 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4829 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4830 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4831 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4832 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004833 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004834}
4835
4836/* Allow FR and HR, but prefer HR */
4837private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4838 g_pars := f_gen_test_hdlr_pars();
4839 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4840 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4841 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4842 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4843 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4844 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4845 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4846 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004847 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004848}
4849
4850/* Request a HR channel while all FR channels are exhausted, this is expected
4851 * to work without conflicts */
4852testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4853 var MSC_ConnHdlr vc_conn;
4854 f_init(1, true);
4855 f_sleep(1.0);
4856 f_enable_all_tch();
4857 f_disable_all_tch_f();
4858 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4859 vc_conn.done;
4860 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004861 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004862}
4863
4864/* Request a FR channel while all FR channels are exhausted, this is expected
4865 * to fail. */
4866testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4867 var MSC_ConnHdlr vc_conn;
4868 f_init(1, true);
4869 f_sleep(1.0);
4870 f_enable_all_tch();
4871 f_disable_all_tch_f();
4872 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4873 vc_conn.done;
4874 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004875 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004876}
4877
4878/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4879 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4880testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4881 var MSC_ConnHdlr vc_conn;
4882 f_init(1, true);
4883 f_sleep(1.0);
4884 f_enable_all_tch();
4885 f_disable_all_tch_f();
4886 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4887 vc_conn.done;
4888 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004889 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004890}
4891
4892/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4893 * are exhausted, this is expected to work without conflicts. */
4894testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4895 var MSC_ConnHdlr vc_conn;
4896 f_init(1, true);
4897 f_sleep(1.0);
4898 f_enable_all_tch();
4899 f_disable_all_tch_f();
4900 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4901 vc_conn.done;
4902 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004903 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004904}
4905
4906/* Request a FR channel while all HR channels are exhausted, this is expected
4907 * to work without conflicts */
4908testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4909 var MSC_ConnHdlr vc_conn;
4910 f_init(1, true);
4911 f_sleep(1.0);
4912 f_enable_all_tch();
4913 f_disable_all_tch_h();
4914 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4915 vc_conn.done;
4916 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004917 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004918}
4919
4920/* Request a HR channel while all HR channels are exhausted, this is expected
4921 * to fail. */
4922testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4923 var MSC_ConnHdlr vc_conn;
4924 f_init(1, true);
4925 f_sleep(1.0);
4926 f_enable_all_tch();
4927 f_disable_all_tch_h();
4928 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4929 vc_conn.done;
4930 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004931 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004932}
4933
4934/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4935 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4936testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4937 var MSC_ConnHdlr vc_conn;
4938 f_init(1, true);
4939 f_sleep(1.0);
4940 f_enable_all_tch();
4941 f_disable_all_tch_h();
4942 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4943 vc_conn.done;
4944 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004945 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004946}
4947
4948/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4949 * are exhausted, this is expected to work without conflicts. */
4950testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4951 var MSC_ConnHdlr vc_conn;
4952 f_init(1, true);
4953 f_sleep(1.0);
4954 f_enable_all_tch();
4955 f_disable_all_tch_h();
4956 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4957 vc_conn.done;
4958 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004959 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004960}
4961
4962/* Allow FR and HR, but prefer HR */
4963private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4964 g_pars := f_gen_test_hdlr_pars();
4965 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4966 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4967 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4968 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4969 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4970 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4971 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4972 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004973 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004974}
4975
4976/* Allow FR and HR, but prefer FR */
4977private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4978 g_pars := f_gen_test_hdlr_pars();
4979 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4980 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4981 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4982 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4983 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4984 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4985 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4986 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004987 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004988}
4989
4990/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4991 * HR, which is the prefered type, is selected. */
4992testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4993 var MSC_ConnHdlr vc_conn;
4994 f_init(1, true);
4995 f_sleep(1.0);
4996 f_enable_all_tch();
4997 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4998 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004999 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005000}
5001
5002/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5003 * FR, which is the prefered type, is selected. */
5004testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5005 var MSC_ConnHdlr vc_conn;
5006 f_init(1, true);
5007 f_sleep(1.0);
5008 f_enable_all_tch();
5009 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5010 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005011 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005012}
5013
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005014/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5015private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5016 g_pars := f_gen_test_hdlr_pars();
5017 g_pars.ra := '02'O; /* RA containing reason=LU */
5018
5019 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5020 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5021 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5022 var template uint3_t tsc := ?;
5023
5024 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5025 f_create_bssmap_exp(l3_enc);
5026 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5027 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5028
5029 /* we should now have a COMPL_L3 at the MSC */
5030 timer T := 10.0;
5031 T.start;
5032 alt {
5033 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5034 [] T.timeout {
5035 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5036 }
5037 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005038
5039 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005040}
5041testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5042 var MSC_ConnHdlr vc_conn;
5043 f_init(1, true);
5044 f_sleep(1.0);
5045 f_disable_all_sdcch();
5046 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5047 vc_conn.done;
5048 f_enable_all_sdcch();
5049 f_shutdown_helper();
5050}
5051
5052/* Request a signalling channel with all SDCCH exhausted, it is
5053 expected that no TCH will be selected for signalling and assigment will fail
5054 because it's dictated by VTY config */
5055testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5056 var RSL_Message rsl_unused, rsl_msg;
5057 var GsmRrMessage rr;
5058 f_init(1, false);
5059 f_sleep(1.0);
5060 f_vty_allow_tch_for_signalling(false, 0);
5061 f_disable_all_sdcch();
5062
5063 /* RA containing reason=LU */
5064 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
5065 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
5066 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5067 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5068 setverdict(fail, "Expected reject");
5069 }
5070
5071 f_vty_allow_tch_for_signalling(true, 0);
5072 f_enable_all_sdcch();
5073 f_shutdown_helper();
5074}
5075
5076/* Request a voice channel with all SDCCH exhausted, it is
5077 * expected that TCH channel will be allocated since the VTY option is only
5078 * aimed at signalling requests */
5079private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5080 g_pars := f_gen_test_hdlr_pars();
5081 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5082
5083 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5084 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5085 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5086 var template uint3_t tsc := ?;
5087
5088 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5089 f_create_bssmap_exp(l3_enc);
5090 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5091 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5092
5093 /* we should now have a COMPL_L3 at the MSC */
5094 timer T := 10.0;
5095 T.start;
5096 alt {
5097 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5098 [] T.timeout {
5099 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5100 }
5101 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005102 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005103}
5104testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5105 var MSC_ConnHdlr vc_conn;
5106 f_init(1, true);
5107 f_sleep(1.0);
5108 f_vty_allow_tch_for_signalling(false, 0);
5109 f_disable_all_sdcch();
5110
5111 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5112 vc_conn.done;
5113
5114 f_vty_allow_tch_for_signalling(true, 0);
5115 f_enable_all_sdcch();
5116 f_shutdown_helper();
5117}
5118
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005119testcase TC_assignment_osmux() runs on test_CT {
5120 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5121 var MSC_ConnHdlr vc_conn;
5122
5123 /* See note above */
5124 var RSL_IE_Body mr_conf := {
5125 other := {
5126 len := 2,
5127 payload := '2804'O
5128 }
5129 };
5130
5131 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5132 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5133 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
5134 pars.expect_mr_conf_ie := mr_conf;
5135 pars.use_osmux := true;
5136
5137 f_init(1, true, true);
5138 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005139 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005140
5141 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5142 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005143
5144 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005145 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005146}
5147
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005148/* test the procedure of the MSC requesting a Classmark Update:
5149 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5150 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005151private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005152 g_pars := f_gen_test_hdlr_pars();
5153
Harald Weltea0630032018-03-20 21:09:55 +01005154 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005155 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005156
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005157 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5158 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5159
Harald Welte898113b2018-01-31 18:32:21 +01005160 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5161 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5162 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005163
5164 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005165}
5166testcase TC_classmark() runs on test_CT {
5167 var MSC_ConnHdlr vc_conn;
5168 f_init(1, true);
5169 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005170 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005171 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005172 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005173}
5174
Harald Welteeddf0e92020-06-21 19:42:15 +02005175/* Send a CommonID from the simulated MSC and verify that the information is used to
5176 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5177private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5178 g_pars := f_gen_test_hdlr_pars();
5179 f_MscConnHdlr_init_vty();
5180
5181 f_create_chan_and_exp();
5182 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005183
5184 /* Send CommonID */
5185 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5186
5187 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5188 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5189 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5190
5191 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005192
5193 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005194}
5195testcase TC_common_id() runs on test_CT {
5196 var MSC_ConnHdlr vc_conn;
5197 f_init(1, true);
5198 f_sleep(1.0);
5199 vc_conn := f_start_handler(refers(f_tc_common_id));
5200 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005201 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005202}
5203
Harald Weltee3bd6582018-01-31 22:51:25 +01005204private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005205 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005206 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005207 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005208
Harald Weltee3bd6582018-01-31 22:51:25 +01005209 /* send the single message we want to send */
5210 f_rsl_send_l3(l3);
5211}
5212
5213private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5214 timer T := sec;
5215 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005216 T.start;
5217 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005218 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5219 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005220 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005221 }
5222 [] T.timeout {
5223 setverdict(pass);
5224 }
5225 }
5226}
5227
Harald Weltee3bd6582018-01-31 22:51:25 +01005228/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5229private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5230 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5231 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005232 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005233}
Harald Welte898113b2018-01-31 18:32:21 +01005234testcase TC_unsol_ass_fail() runs on test_CT {
5235 var MSC_ConnHdlr vc_conn;
5236 f_init(1, true);
5237 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005238 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005239 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005240 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005241}
Harald Welte552620d2017-12-16 23:21:36 +01005242
Harald Welteea99a002018-01-31 20:46:43 +01005243
5244/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5245private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005246 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5247 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005248 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005249}
5250testcase TC_unsol_ass_compl() runs on test_CT {
5251 var MSC_ConnHdlr vc_conn;
5252 f_init(1, true);
5253 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005254 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005255 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005256 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005257}
5258
5259
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005260/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5261private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005262 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5263 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005264 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005265}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005266testcase TC_unsol_ho_fail() runs on test_CT {
5267 var MSC_ConnHdlr vc_conn;
5268 f_init(1, true);
5269 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005270 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005271 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005272 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005273}
5274
5275
Harald Weltee3bd6582018-01-31 22:51:25 +01005276/* short message from MS should be ignored */
5277private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005278 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005279 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005280 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005281
5282 /* send short message */
5283 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5284 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005285 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005286}
5287testcase TC_err_82_short_msg() runs on test_CT {
5288 var MSC_ConnHdlr vc_conn;
5289 f_init(1, true);
5290 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005291 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005292 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005293 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005294}
5295
5296
Harald Weltee9e02e42018-01-31 23:36:25 +01005297/* 24.008 8.4 Unknown message must trigger RR STATUS */
5298private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5299 f_est_single_l3(ts_RRM_UL_REL('00'O));
5300 timer T := 3.0
5301 alt {
5302 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5303 setverdict(pass);
5304 }
5305 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005306 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005307 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005308 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005309}
5310testcase TC_err_84_unknown_msg() runs on test_CT {
5311 var MSC_ConnHdlr vc_conn;
5312 f_init(1, true);
5313 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005314 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005315 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005316 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005317}
5318
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005319/***********************************************************************
5320 * Handover
5321 ***********************************************************************/
5322
Harald Welte94e0c342018-04-07 11:33:23 +02005323/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5324private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5325runs on test_CT {
5326 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5327 " timeslot "&int2str(ts_nr)&" ";
5328 f_vty_transceive(BSCVTY, cmd & suffix);
5329}
5330
Harald Welte261af4b2018-02-12 21:20:39 +01005331/* 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 +07005332private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5333 uint8_t bts_nr, uint8_t trx_nr,
5334 in RslChannelNr chan_nr)
5335{
Harald Welte261af4b2018-02-12 21:20:39 +01005336 /* FIXME: resolve those from component-global state */
5337 var integer ts_nr := chan_nr.tn;
5338 var integer ss_nr;
5339 if (ischosen(chan_nr.u.ch0)) {
5340 ss_nr := 0;
5341 } else if (ischosen(chan_nr.u.lm)) {
5342 ss_nr := chan_nr.u.lm.sub_chan;
5343 } else if (ischosen(chan_nr.u.sdcch4)) {
5344 ss_nr := chan_nr.u.sdcch4.sub_chan;
5345 } else if (ischosen(chan_nr.u.sdcch8)) {
5346 ss_nr := chan_nr.u.sdcch8.sub_chan;
5347 } else {
5348 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005349 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005350 }
5351
5352 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5353 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005354 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005355}
5356
Neels Hofmeyr91401012019-07-11 00:42:35 +02005357/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5358 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5359 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5360 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5361 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005362private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5363 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5364{
5365 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005366}
5367
5368/* intra-BSC hand-over between BTS0 and BTS1 */
5369private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005370 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5371 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005372
5373 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5374 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5375
Harald Weltea0630032018-03-20 21:09:55 +01005376 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005377 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005378
5379 var HandoverState hs := {
5380 rr_ho_cmpl_seen := false,
5381 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005382 old_chan_nr := -,
5383 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005384 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005385 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005386 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005387 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5388 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005389
5390 /* From the MGW perspective, a handover is is characterized by
5391 * performing one MDCX operation with the MGW. So we expect to see
5392 * one more MDCX during handover. */
5393 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5394
Harald Welte261af4b2018-02-12 21:20:39 +01005395 alt {
5396 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005397 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005398
Philipp Maier4dae0652018-11-12 12:03:26 +01005399 /* Since this is an internal handover we expect the BSC to inform the
5400 * MSC about the event */
5401 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5402
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005403 /* Check the amount of MGCP transactions is still consistant with the
5404 * test expectation */
5405 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005406
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005407 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5408
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005409 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5410 * 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 +02005411 f_verify_encr_info(chan_act);
5412
5413 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005414
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005415 f_perform_clear(RSL1, RSL1_PROC);
5416
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005417 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005418}
5419
5420testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005421 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005422 var MSC_ConnHdlr vc_conn;
5423 f_init(2, true);
5424 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005425
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005426 pars.expect_tsc := BTS_TSC[0];
5427
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005428 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005429
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005430 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005431 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005432
5433 /* from f_establish_fully() */
5434 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5435 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5436 /* from handover */
5437 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5438 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5439 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5440 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005441 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5442 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005443 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005444 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005445}
Harald Weltee9e02e42018-01-31 23:36:25 +01005446
Oliver Smith7eabd312021-07-12 14:18:56 +02005447function 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 +02005448 var MSC_ConnHdlr vc_conn;
5449 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5450 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5451
5452 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005453 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005454 f_sleep(1.0);
5455
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005456 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005457
5458 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5459 vc_conn.done;
5460
5461 /* from f_establish_fully() */
5462 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5463 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5464 /* from handover */
5465 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5466 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5467 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5468 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005469 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5470 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005471 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005472 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005473 f_shutdown_helper();
5474}
5475
5476testcase TC_ho_int_a5_0() runs on test_CT {
5477 f_tc_ho_int_a5('01'O);
5478}
5479
5480testcase TC_ho_int_a5_1() runs on test_CT {
5481 f_tc_ho_int_a5('02'O);
5482}
5483
5484testcase TC_ho_int_a5_3() runs on test_CT {
5485 f_tc_ho_int_a5('08'O);
5486}
5487
5488testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005489 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005490}
5491
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005492/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5493private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5494 g_pars := f_gen_test_hdlr_pars();
5495 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5496 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005497
5498 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5499 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5500
5501 f_establish_fully(ass_cmd, exp_compl);
5502 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5503
5504 var HandoverState hs := {
5505 rr_ho_cmpl_seen := false,
5506 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005507 old_chan_nr := -,
5508 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005509 };
5510 /* issue hand-over command on VTY */
5511 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5512 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5513 f_rslem_suspend(RSL1_PROC);
5514
5515 /* From the MGW perspective, a handover is is characterized by
5516 * performing one MDCX operation with the MGW. So we expect to see
5517 * one more MDCX during handover. */
5518 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5519
5520 var RSL_Message rsl;
5521 var PDU_ML3_NW_MS l3;
5522 var RslChannelNr new_chan_nr;
5523 var GsmArfcn arfcn;
5524 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5525 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5526 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5527 setverdict(fail, "Expected handoverCommand");
5528 mtc.stop;
5529 }
5530 }
5531 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5532 new_chan_nr, arfcn);
5533
5534 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5535
5536 /* resume processing of RSL DChan messages, which was temporarily suspended
5537 * before performing a hand-over */
5538 f_rslem_resume(RSL1_PROC);
5539 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5540
5541 f_sleep(1.0);
5542
5543 /* Handover fails because no HANDO DET appears on the new lchan,
5544 * and the old lchan reports a Radio Link Failure. */
5545 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5546
5547 var PDU_BSSAP rx_clear_request;
5548 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5549 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5550 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5551
5552 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5553
5554 var MgcpCommand mgcp;
5555 interleave {
5556 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5557 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005558 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005559 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005560 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005561 }
5562 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005563 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005564 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005565 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005566 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005567 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5568 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5569 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005570 }
5571
5572 f_sleep(0.5);
5573 setverdict(pass);
5574}
5575testcase TC_ho_int_radio_link_failure() runs on test_CT {
5576 var MSC_ConnHdlr vc_conn;
5577 f_init(2, true);
5578 f_sleep(1.0);
5579
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005580 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005581
5582 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5583 vc_conn.done;
5584
5585 /* from f_establish_fully() */
5586 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5587 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5588 /* from handover */
5589 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5590 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5591 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5592 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005593 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5594 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005595 f_ctrs_bsc_and_bts_verify();
5596 f_shutdown_helper();
5597}
5598
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005599/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005600private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005601 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005602 var template MgcpResponse mgcp_resp;
5603 var MGCP_RecvFrom mrf;
5604 var template MgcpMessage msg_resp;
5605 var template MgcpMessage msg_dlcx := {
5606 command := tr_DLCX()
5607 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005608
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005609 if (g_pars.aoip) {
5610 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005611 log("Got first DLCX: ", mgcp);
5612 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005613 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005614
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005615 MGCP.receive(tr_DLCX()) -> value mgcp {
5616 log("Got second DLCX: ", mgcp);
5617 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5618 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005619 } else {
5620 /* For SCCPLite, BSC doesn't handle the MSC-side */
5621 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5622 log("Got first DLCX: ", mrf.msg.command);
5623 msg_resp := {
5624 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5625 }
5626 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5627 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005628 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005629}
5630
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005631private 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 +01005632
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005633 var NcellReports neighbor_rep := {
5634 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5635 };
5636 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5637 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5638 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005639
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005640 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005641
5642 f_sleep(0.5);
5643 /* The MSC negotiates Handover Request and Handover Request Ack with
5644 * the other BSS and comes back with a BSSMAP Handover Command
5645 * containing an RR Handover Command coming from the target BSS... */
5646
5647 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5648 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5649 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5650 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5651 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5652
5653 /* expect the Handover Command to go out on RR */
5654 var RSL_Message rsl_ho_cmd
5655 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5656 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5657 var RSL_IE_Body rsl_ho_cmd_l3;
5658 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5659 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5660 setverdict(fail);
5661 } else {
5662 log("Found L3 Info: ", rsl_ho_cmd_l3);
5663 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5664 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5665 setverdict(fail);
5666 } else {
5667 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5668 setverdict(pass);
5669 }
5670 }
5671
5672 /* When the other BSS has reported a completed handover, this side is
5673 * torn down. */
5674
5675 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5676 var BssmapCause cause := enum2int(cause_val);
5677 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5678
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005679 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005680
5681 interleave {
5682 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5683 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5684 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005685 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5686 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5687 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005688 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005689 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005690}
5691
5692private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5693 g_pars := f_gen_test_hdlr_pars();
5694 var PDU_BSSAP ass_req := f_gen_ass_req();
5695 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5696 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5697 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5698 f_establish_fully(ass_req, exp_compl);
5699
5700 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005701}
5702testcase TC_ho_out_of_this_bsc() runs on test_CT {
5703 var MSC_ConnHdlr vc_conn;
5704
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005705 f_init_vty();
5706 f_bts_0_cfg(BSCVTY,
5707 {"neighbor-list mode automatic",
5708 "handover 1",
5709 "handover algorithm 2",
5710 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005711 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005712 "neighbor lac 99 arfcn 123 bsic any"});
5713 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5714
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005715 f_init(1, true);
5716 f_sleep(1.0);
5717
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005718 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005719
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005720 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5721 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005722
5723 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5724 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5725 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5726 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5727 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5728 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5729 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005730 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005731}
5732
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005733private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5734 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005735 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005736 octetstring l3 := '0123456789'O)
5737runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005738 /* The old lchan and conn should still be active. See that arbitrary L3
5739 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005740 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005741 var template PDU_BSSAP exp_data := {
5742 discriminator := '1'B,
5743 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005744 dlci := dlci,
5745 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005746 pdu := {
5747 dtap := l3
5748 }
5749 };
5750 BSSAP.receive(exp_data);
5751 setverdict(pass);
5752}
5753
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005754private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5755 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005756 template (value) OCT1 dlci := '00'O,
5757 octetstring l3 := '0123456789'O)
5758runs on MSC_ConnHdlr {
5759 BSSAP.send(PDU_BSSAP:{
5760 discriminator := '1'B,
5761 spare := '0000000'B,
5762 dlci := dlci,
5763 lengthIndicator := lengthof(l3),
5764 pdu := {
5765 dtap := l3
5766 }
5767 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005768 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005769 setverdict(pass);
5770}
5771
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005772/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5773 * simply never sends a BSSMAP Handover Command. */
5774private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005775 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005776
5777 var PDU_BSSAP ass_req := f_gen_ass_req();
5778 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5779 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5780 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5781 f_establish_fully(ass_req, exp_compl);
5782
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005783 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005784 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5785
5786 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5787
5788 /* osmo-bsc should time out 10 seconds after the handover started.
5789 * Let's give it a bit extra. */
5790 f_sleep(15.0);
5791
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005792 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005793 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005794 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005795}
5796testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5797 var MSC_ConnHdlr vc_conn;
5798
5799 f_init(1, true);
5800 f_sleep(1.0);
5801
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005802 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005803
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005804 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5805 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005806
5807 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5808 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5809 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5810 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5811 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5812 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5813 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005814 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005815}
5816
5817/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5818 * RR Handover Failure. */
5819private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005820 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005821
5822 var PDU_BSSAP ass_req := f_gen_ass_req();
5823 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5824 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5825 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5826 f_establish_fully(ass_req, exp_compl);
5827
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005828 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005829 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5830
5831 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5832
5833 f_sleep(0.5);
5834 /* The MSC negotiates Handover Request and Handover Request Ack with
5835 * the other BSS and comes back with a BSSMAP Handover Command
5836 * containing an RR Handover Command coming from the target BSS... */
5837
5838 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5839 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5840 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5841 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5842 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5843
5844 /* expect the Handover Command to go out on RR */
5845 var RSL_Message rsl_ho_cmd
5846 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5847 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5848 var RSL_IE_Body rsl_ho_cmd_l3;
5849 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5850 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5851 setverdict(fail);
5852 } else {
5853 log("Found L3 Info: ", rsl_ho_cmd_l3);
5854 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5855 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5856 setverdict(fail);
5857 } else {
5858 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5859 setverdict(pass);
5860 }
5861 }
5862
5863 f_sleep(0.2);
5864 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5865
5866 /* Should tell the MSC about the failure */
5867 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5868
5869 f_sleep(1.0);
5870
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005871 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005872 f_sleep(1.0);
5873
5874 setverdict(pass);
5875 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005876 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005877}
5878testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5879 var MSC_ConnHdlr vc_conn;
5880
5881 f_init(1, true);
5882 f_sleep(1.0);
5883
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005884 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005885
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005886 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5887 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005888
5889 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5890 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5891 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5892 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5893 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5894 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5895 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005896 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005897}
5898
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005899/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5900 * (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 +02005901 * and the lchan is released. */
5902private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005903 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005904
5905 var PDU_BSSAP ass_req := f_gen_ass_req();
5906 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5907 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5908 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5909 f_establish_fully(ass_req, exp_compl);
5910
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005911 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005912 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5913
5914 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5915
5916 f_sleep(0.5);
5917 /* The MSC negotiates Handover Request and Handover Request Ack with
5918 * the other BSS and comes back with a BSSMAP Handover Command
5919 * containing an RR Handover Command coming from the target BSS... */
5920
5921 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5922 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5923 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5924 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5925 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5926
5927 /* expect the Handover Command to go out on RR */
5928 var RSL_Message rsl_ho_cmd
5929 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5930 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5931 var RSL_IE_Body rsl_ho_cmd_l3;
5932 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5933 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5934 setverdict(fail);
5935 } else {
5936 log("Found L3 Info: ", rsl_ho_cmd_l3);
5937 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5938 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5939 setverdict(fail);
5940 } else {
5941 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5942 setverdict(pass);
5943 }
5944 }
5945
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005946 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5947 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5948 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005949
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005950 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005951 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5952 log("Got BSSMAP Clear Request");
5953 /* Instruct BSC to clear channel */
5954 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5955 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5956
5957 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005958 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005959 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5960 log("Got Deact SACCH");
5961 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005962 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005963 log("Got RR Release");
5964 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005965 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005966 log("Got RF Chan Rel");
5967 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005968 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005969 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005970 }
5971
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005972 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005973 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005974 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005975
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005976 setverdict(pass);
5977 f_sleep(1.0);
5978}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005979testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005980 var MSC_ConnHdlr vc_conn;
5981
5982 f_init(1, true);
5983 f_sleep(1.0);
5984
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005985 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005986
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005987 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005988 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005989
5990 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5991 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5992 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5993 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5994 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5995 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5996 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005997 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005998}
5999
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006000private 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 +01006001 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006002 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6003 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6004 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6005 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6006 * before we get started. */
6007 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6008 f_rslem_register(0, new_chan_nr);
6009 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006010 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006011 f_sleep(1.0);
6012
6013 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6014 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6015 activate(as_Media());
6016
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006017 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6018 cell_id_source := g_pars.cell_id_source,
6019 oldToNewBSSIEs := oldToNewBSSIEs,
6020 enc := g_pars.encr);
6021 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6022 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6023 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6024 } else {
6025 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6026 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6027 BSSAP.send(ho_req);
6028 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006029
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006030 alt {
6031 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6032 if (g_pars.expect_ho_fail) {
6033 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6034 "Expected Handover Request to fail, but got Handover Request Ack")
6035 }
6036 }
6037 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6038 if (not g_pars.expect_ho_fail) {
6039 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6040 "Expected Handover Request to succeed, but got Handover Failure")
6041 }
6042 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6043 // For now just accept any cause.
6044 BSSAP.receive(tr_BSSMAP_ClearRequest);
6045 setverdict(pass);
6046 return;
6047 }
6048 }
6049
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006050 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6051
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006052 /* we're sure that the channel activation is done now, verify the parameters in it */
6053 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6054 f_verify_encr_info(chan_act);
6055 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006056
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006057 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6058 if (not g_pars.aoip) {
6059 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6060 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6061 }
6062 /* TODO: check actual codecs? */
6063 } else {
6064 if (g_pars.aoip) {
6065 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6066 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6067 }
6068 }
6069
6070 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6071 if (not g_pars.aoip) {
6072 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6073 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6074 }
6075 /* TODO: check actual codec? */
6076 } else {
6077 if (g_pars.aoip) {
6078 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6079 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6080 }
6081 }
6082
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006083 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006084 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6085 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6086 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6087 log("L3 Info in HO Request Ack is ", ho_command);
6088
6089 var GsmArfcn arfcn;
6090 var RslChannelNr actual_new_chan_nr;
6091 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6092 actual_new_chan_nr, arfcn);
6093
6094 if (actual_new_chan_nr != new_chan_nr) {
6095 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6096 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6097 setverdict(fail);
6098 return;
6099 }
6100 log("Handover Command chan_nr is", actual_new_chan_nr);
6101
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006102 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6103 if (not match(got_tsc, expect_target_tsc)) {
6104 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6105 expect_target_tsc, " got ", got_tsc);
6106 mtc.stop;
6107 } else {
6108 log("handoverCommand: verified TSC = ", got_tsc);
6109 }
6110
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006111 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6112 * tells the MS to handover to the new lchan. Here comes the new MS on
6113 * the new lchan with a Handover RACH: */
6114
6115 /* send handover detect */
6116
6117 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6118
6119 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6120
6121 /* send handover complete over the new channel */
6122
6123 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6124 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6125 enc_PDU_ML3_MS_NW(l3_tx)));
6126
6127 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006128 setverdict(pass);
6129}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006130
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006131private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006132 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006133 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6134 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6135 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006136 }
6137 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006138 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006139 } else {
6140 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006141 }
6142 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006143 if (g_pars.expect_ho_fail) {
6144 f_perform_clear_no_lchan();
6145 } else {
6146 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6147 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006148 setverdict(pass);
6149}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006150function 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 +01006151 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006152
6153 f_init(1, true);
6154 f_sleep(1.0);
6155
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006156 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006157 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006158
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006159 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6160 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006161
6162 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6163 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006164
6165 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006166 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006167 if (pars.expect_ho_fail) {
6168 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6169 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6170 } else {
6171 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6172 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6173 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006174 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006175
6176 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006177}
6178
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006179testcase TC_ho_into_this_bsc() runs on test_CT {
6180 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6181 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006182 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006183}
6184
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006185function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6186 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006187 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006188 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006189 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006190 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006191 f_shutdown_helper();
6192}
6193
6194testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006195 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006196}
6197
6198testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006199 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006200}
6201
6202testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006203 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006204}
6205
6206testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006207 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006208}
6209
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006210/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6211 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6212 *
6213 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6214 * omitted.
6215 *
6216 * Related: SYS#5839
6217 */
6218testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6219 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6220}
6221
6222testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6223 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6224}
6225
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006226/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6227testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6228 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6229 expect_fail := true); // 0x18 = A5/3 and A5/4
6230}
6231
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006232testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6233 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6234 pars.host_aoip_tla := "::6";
6235 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006236 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006237}
6238
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006239/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006240 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006241 channel is later released (RR CHannel Release), should trigger inclusion of
6242 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6243 neighbors. */
6244testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6245 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6246 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006247 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006248 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006249
6250 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6251 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6252 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006253 f_shutdown_helper();
6254}
6255
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006256/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6257 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6258 list when the channel is released. */
6259testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6260 f_init_vty();
6261 f_vty_allow_srvcc_fast_return(true, 0)
6262
6263 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6264 pars.last_used_eutran_plmn := '323454'O;
6265 pars.exp_fast_return := false;
6266 f_tc_ho_into_this_bsc_main(pars);
6267 f_vty_allow_srvcc_fast_return(false, 0);
6268 f_shutdown_helper();
6269}
6270
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006271/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6272testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6273 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6274 pars.last_used_eutran_plmn := '323454'O;
6275 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6276 f_tc_ho_into_this_bsc_main(pars);
6277
6278 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6279 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6280 f_ctrs_bsc_and_bts_verify();
6281 f_shutdown_helper();
6282}
6283
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006284private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6285 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6286 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6287 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6288 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6289 setverdict(pass);
6290}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006291
6292private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6293 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006294 var MSC_ConnHdlr vc_conn;
6295 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6296
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006297 f_init_vty();
6298 f_bts_0_cfg(BSCVTY,
6299 {"neighbor-list mode automatic",
6300 "handover 1",
6301 "handover algorithm 2",
6302 "handover2 window rxlev averaging 1",
6303 "no neighbors",
6304 "neighbor lac 99 arfcn 123 bsic any"});
6305 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6306
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006307 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006308 if (disable_fast_return) {
6309 f_vty_allow_srvcc_fast_return(true, 0);
6310 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006311 f_sleep(1.0);
6312
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006313 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006314
6315 pars.last_used_eutran_plmn := '323454'O;
6316 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6317 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6318
6319 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6320 vc_conn.done;
6321
6322 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6323 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6324 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6325 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6326 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6327 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006328
6329 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6330 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006331 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006332
6333 if (disable_fast_return) {
6334 f_vty_allow_srvcc_fast_return(false, 0);
6335 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006336 f_shutdown_helper();
6337}
6338
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006339/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6340 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6341 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6342 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6343testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6344 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6345}
6346/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6347 * independently of fast-reture allowed/forbidden in local BTS */
6348testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6349 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6350}
6351
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006352private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6353 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6354 f_rslem_register(0, new_chan_nr);
6355 g_chan_nr := new_chan_nr;
6356 f_sleep(1.0);
6357
6358 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6359 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6360 activate(as_Media());
6361
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006362 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006363 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006364 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006365
6366 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6367
6368 var PDU_BSSAP rx_bssap;
6369 var octetstring ho_command_str;
6370
6371 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6372
6373 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6374 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6375 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6376 log("L3 Info in HO Request Ack is ", ho_command);
6377
6378 var GsmArfcn arfcn;
6379 var RslChannelNr actual_new_chan_nr;
6380 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6381 actual_new_chan_nr, arfcn);
6382
6383 if (actual_new_chan_nr != new_chan_nr) {
6384 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6385 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6386 setverdict(fail);
6387 return;
6388 }
6389 log("Handover Command chan_nr is", actual_new_chan_nr);
6390
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006391 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6392 f_sleep(1.0);
6393
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006394 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6395 * tells the MS to handover to the new lchan. In this case, the MS
6396 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6397 * Handover Failure to the MSC. The procedure according to 3GPP TS
6398 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6399 * BSSMAP Clear Command: */
6400
6401 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6402 var BssmapCause cause := enum2int(cause_val);
6403 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6404
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006405 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006406 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006407 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006408
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006409 setverdict(pass);
6410 f_sleep(1.0);
6411
6412 setverdict(pass);
6413}
6414testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6415 var MSC_ConnHdlr vc_conn;
6416 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6417
6418 f_init(1, true);
6419 f_sleep(1.0);
6420
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006421 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006422
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006423 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6424 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006425
6426 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6427 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006428
6429 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6430 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6431 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6432 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6433 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006434 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006435}
6436
6437private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6438 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6439 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6440 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6441 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6442 * before we get started. */
6443 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6444 f_rslem_register(0, new_chan_nr);
6445 g_chan_nr := new_chan_nr;
6446 f_sleep(1.0);
6447
6448 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6449 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6450 activate(as_Media());
6451
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006452 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006453 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006454 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006455
6456 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6457
6458 var PDU_BSSAP rx_bssap;
6459 var octetstring ho_command_str;
6460
6461 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6462
6463 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6464 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6465 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6466 log("L3 Info in HO Request Ack is ", ho_command);
6467
6468 var GsmArfcn arfcn;
6469 var RslChannelNr actual_new_chan_nr;
6470 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6471 actual_new_chan_nr, arfcn);
6472
6473 if (actual_new_chan_nr != new_chan_nr) {
6474 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6475 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6476 setverdict(fail);
6477 return;
6478 }
6479 log("Handover Command chan_nr is", actual_new_chan_nr);
6480
6481 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6482 * tells the MS to handover to the new lchan. Here comes the new MS on
6483 * the new lchan with a Handover RACH: */
6484
6485 /* send handover detect */
6486
6487 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6488
6489 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6490
6491 /* The MSC chooses to clear the connection now, maybe we got the
6492 * Handover RACH on the new cell but the MS still signaled Handover
6493 * Failure to the old BSS? */
6494
6495 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6496 var BssmapCause cause := enum2int(cause_val);
6497 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6498
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006499 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006500 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006501 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006502
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006503 f_sleep(1.0);
6504}
6505testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6506 var MSC_ConnHdlr vc_conn;
6507 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6508
6509 f_init(1, true);
6510 f_sleep(1.0);
6511
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006512 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006513
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006514 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6515 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006516
6517 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6518 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006519
6520 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6521 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6522 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6523 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6524 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006525 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006526}
6527
6528/* The new BSS's lchan times out before the MSC decides that handover failed. */
6529private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6530 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6531 f_rslem_register(0, new_chan_nr);
6532 g_chan_nr := new_chan_nr;
6533 f_sleep(1.0);
6534
6535 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6536 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6537 activate(as_Media());
6538
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006539 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006540 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006541 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006542
6543 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6544
6545 var PDU_BSSAP rx_bssap;
6546 var octetstring ho_command_str;
6547
6548 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6549
6550 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6551 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6552 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6553 log("L3 Info in HO Request Ack is ", ho_command);
6554
6555 var GsmArfcn arfcn;
6556 var RslChannelNr actual_new_chan_nr;
6557 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6558 actual_new_chan_nr, arfcn);
6559
6560 if (actual_new_chan_nr != new_chan_nr) {
6561 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6562 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6563 setverdict(fail);
6564 return;
6565 }
6566 log("Handover Command chan_nr is", actual_new_chan_nr);
6567
6568 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6569 * tells the MS to handover to the new lchan. But the MS never shows up
6570 * on the new lchan. */
6571
6572 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6573
6574 /* Did osmo-bsc also send a Clear Request? */
6575 timer T := 0.5;
6576 T.start;
6577 alt {
6578 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6579 [] T.timeout { }
6580 }
6581
6582 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6583 * asked for it, this is a Handover Failure after all). */
6584
6585 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6586 var BssmapCause cause := enum2int(cause_val);
6587 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6588
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006589 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006590 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006591 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006592
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006593 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006594}
6595testcase TC_ho_in_fail_no_detect() runs on test_CT {
6596 var MSC_ConnHdlr vc_conn;
6597 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6598
6599 f_init(1, true);
6600 f_sleep(1.0);
6601
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006602 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006603
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006604 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6605 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006606
6607 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6608 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006609
6610 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6611 f_ctrs_bsc_and_bts_add(0, "handover:error");
6612 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6613 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6614 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006615 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006616}
6617
6618/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6619private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6620 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6621 f_rslem_register(0, new_chan_nr);
6622 g_chan_nr := new_chan_nr;
6623 f_sleep(1.0);
6624
6625 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6626 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6627 activate(as_Media());
6628
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006629 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006630 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006631 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006632
6633 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6634
6635 var PDU_BSSAP rx_bssap;
6636 var octetstring ho_command_str;
6637
6638 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6639
6640 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6641 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6642 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6643 log("L3 Info in HO Request Ack is ", ho_command);
6644
6645 var GsmArfcn arfcn;
6646 var RslChannelNr actual_new_chan_nr;
6647 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6648 actual_new_chan_nr, arfcn);
6649
6650 if (actual_new_chan_nr != new_chan_nr) {
6651 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6652 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6653 setverdict(fail);
6654 return;
6655 }
6656 log("Handover Command chan_nr is", actual_new_chan_nr);
6657
6658 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6659 * tells the MS to handover to the new lchan. But the MS never shows up
6660 * on the new lchan. */
6661
6662 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6663
6664 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006665 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006666
6667 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006668 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6669 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6670 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006671 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006672 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006673 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006674
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006675 f_sleep(1.0);
6676}
6677testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6678 var MSC_ConnHdlr vc_conn;
6679 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6680
6681 f_init(1, true);
6682 f_sleep(1.0);
6683
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006684 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006685
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006686 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6687 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006688
6689 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6690 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006691
6692 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6693 f_ctrs_bsc_and_bts_add(0, "handover:error");
6694 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6695 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6696 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006697 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006698}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006699
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006700/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6701 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6702 * empty N-Connect case. */
6703testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6704 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6705 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6706 f_tc_ho_into_this_bsc_main(pars);
6707 f_shutdown_helper();
6708}
6709
Neels Hofmeyr91401012019-07-11 00:42:35 +02006710type record of charstring Commands;
6711
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006712private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006713{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006714 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006715 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006716 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006717 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006718 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006719}
6720
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006721private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6722{
6723 f_vty_enter_cfg_cs7_inst(pt, 0);
6724 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6725 f_vty_transceive(pt, cmds[i]);
6726 }
6727 f_vty_transceive(pt, "end");
6728}
6729
Neels Hofmeyr91401012019-07-11 00:42:35 +02006730private function f_probe_for_handover(charstring log_label,
6731 charstring log_descr,
6732 charstring handover_vty_cmd,
6733 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006734 boolean is_inter_bsc_handover := false,
6735 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006736runs on MSC_ConnHdlr
6737{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006738 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6739 * lchans to be established on bts 1 or bts 2. */
6740 f_rslem_suspend(RSL1_PROC);
6741 f_rslem_suspend(RSL2_PROC);
6742
Neels Hofmeyr91401012019-07-11 00:42:35 +02006743 var RSL_Message rsl;
6744
6745 var charstring log_msg := " (expecting handover)"
6746 if (not expect_handover) {
6747 log_msg := " (expecting NO handover)";
6748 }
6749 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6750 f_vty_transceive(BSCVTY, handover_vty_cmd);
6751
Neels Hofmeyr91401012019-07-11 00:42:35 +02006752 timer T := 2.0;
6753 T.start;
6754
6755 alt {
6756 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6757 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6758 log("Rx L3 from net: ", l3);
6759 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6760 var RslChannelNr new_chan_nr;
6761 var GsmArfcn arfcn;
6762 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6763 new_chan_nr, arfcn);
6764 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6765 log(l3.msgs.rrm.handoverCommand);
6766
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006767 /* Verify correct TSC in handoverCommand */
6768 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6769 if (not match(got_tsc, expect_target_tsc)) {
6770 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6771 expect_target_tsc, " got ", got_tsc);
6772 mtc.stop;
6773 } else {
6774 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6775 expect_target_tsc, ")");
6776 }
6777
Neels Hofmeyr91401012019-07-11 00:42:35 +02006778 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6779 * matter on which BTS it really is, we're not going to follow through an entire handover
6780 * anyway. */
6781 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6782 f_rslem_resume(RSL1_PROC);
6783 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6784 f_rslem_resume(RSL2_PROC);
6785
6786 if (expect_handover and not is_inter_bsc_handover) {
6787 setverdict(pass);
6788 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6789 } else {
6790 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6791 & log_label & ": " & log_descr);
6792 }
6793
6794 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6795 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6796 * Handover Failure. */
6797 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6798
6799 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6800 f_sleep(0.5);
6801 RSL1.clear;
6802 RSL2.clear;
6803 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6804 break;
6805 } else {
6806 repeat;
6807 }
6808 }
6809 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6810 if (expect_handover and is_inter_bsc_handover) {
6811 setverdict(pass);
6812 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6813 } else {
6814 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6815 & log_label & ": " & log_descr);
6816 }
6817
6818 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6819
6820 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6821 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6822 * setting a short timeout and waiting is the only way. */
6823 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6824 f_sleep(1.5);
6825 log("f_probe_for_handover(" & log_label & "): ...done");
6826
6827 break;
6828 }
6829 [] T.timeout {
6830 if (expect_handover) {
6831 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6832 & log_label & ": " & log_descr);
6833 } else {
6834 setverdict(pass);
6835 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6836 }
6837 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6838 break;
6839 }
6840 }
6841
6842 f_rslem_resume(RSL1_PROC);
6843 f_rslem_resume(RSL2_PROC);
6844 f_sleep(3.0);
6845 RSL.clear;
6846
6847 log("f_probe_for_handover(" & log_label & "): done clearing");
6848}
6849
6850/* Test the effect of various neighbor configuration scenarios:
6851 *
6852 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6853 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6854 */
6855private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6856 g_pars := f_gen_test_hdlr_pars();
6857 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6858 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006859
6860 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6861 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6862
6863 /* Establish lchan at bts 0 */
6864 f_establish_fully(ass_cmd, exp_compl);
6865
6866 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6867 f_vty_enter_cfg_network(BSCVTY);
6868 f_vty_transceive(BSCVTY, "timer T7 1");
6869 f_vty_transceive(BSCVTY, "end");
6870}
6871
6872private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6873 f_tc_ho_neighbor_config_start();
6874
6875 /*
6876 * bts 0 ARFCN 871 BSIC 10
6877 * bts 1 ARFCN 871 BSIC 11
6878 * bts 2 ARFCN 871 BSIC 12
6879 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6880 */
6881
6882 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006883 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006884 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6885 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006886 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006887
6888 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6889 "handover any to arfcn 13 bsic 39",
6890 false);
6891
6892 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6893 "handover any to arfcn 871 bsic 12",
6894 false);
6895
6896 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6897 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006898 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006899
6900 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006901}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006902testcase TC_ho_neighbor_config_1() runs on test_CT {
6903 var MSC_ConnHdlr vc_conn;
6904 f_init(3, true, guard_timeout := 60.0);
6905 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006906 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006907 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6908 vc_conn.done;
6909
6910 /* f_tc_ho_neighbor_config_start() */
6911 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6912 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6913
6914 /* 1.a */
6915 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6916 * handover quickly by sending a Handover Failure message. */
6917 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6918 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6919 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6920 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006921 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6922 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006923
6924 /* 1.b */
6925 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6926 f_ctrs_bsc_and_bts_add(0, "handover:error");
6927
6928 /* 1.c */
6929 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6930 f_ctrs_bsc_and_bts_add(0, "handover:error");
6931
6932 /* 1.d */
6933 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6934 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6935 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6936 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006937 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6938 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006939
6940 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006941 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006942}
6943
Neels Hofmeyr91401012019-07-11 00:42:35 +02006944private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6945 f_tc_ho_neighbor_config_start();
6946
6947 /*
6948 * bts 0 ARFCN 871 BSIC 10
6949 * bts 1 ARFCN 871 BSIC 11
6950 * bts 2 ARFCN 871 BSIC 12
6951 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6952 */
6953
6954 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006955 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006956 f_sleep(0.5);
6957
6958 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6959 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006960 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006961
6962 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6963 "handover any to arfcn 871 bsic 12",
6964 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006965 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006966}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006967testcase TC_ho_neighbor_config_2() runs on test_CT {
6968 var MSC_ConnHdlr vc_conn;
6969 f_init(3, true, guard_timeout := 50.0);
6970 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006971 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006972 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6973 vc_conn.done;
6974
6975 /* f_tc_ho_neighbor_config_start() */
6976 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6977 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6978
6979 /* 2.a */
6980 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6981 * handover quickly by sending a Handover Failure message. */
6982 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6983 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6984 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6985 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006986 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6987 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006988
6989 /* 2.b */
6990 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6991 f_ctrs_bsc_and_bts_add(0, "handover:error");
6992
6993 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006994 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006995}
6996
Neels Hofmeyr91401012019-07-11 00:42:35 +02006997private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6998 f_tc_ho_neighbor_config_start();
6999
7000 /*
7001 * bts 0 ARFCN 871 BSIC 10
7002 * bts 1 ARFCN 871 BSIC 11
7003 * bts 2 ARFCN 871 BSIC 12
7004 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7005 */
7006
7007 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007008 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007009 f_sleep(0.5);
7010
7011 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7012 "handover any to arfcn 871 bsic 11",
7013 false);
7014 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",
7015 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007016 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007017 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007018}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007019testcase TC_ho_neighbor_config_3() runs on test_CT {
7020 var MSC_ConnHdlr vc_conn;
7021 f_init(3, true, guard_timeout := 50.0);
7022 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007023 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007024 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7025 vc_conn.done;
7026
7027 /* f_tc_ho_neighbor_config_start() */
7028 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7029 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7030
7031 /* 3.a */
7032 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7033 f_ctrs_bsc_and_bts_add(0, "handover:error");
7034
7035 /* 3.b */
7036 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7037 * handover quickly by sending a Handover Failure message. */
7038 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7039 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7040 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7041 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007042 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7043 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007044
7045 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007046 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007047}
7048
Neels Hofmeyr91401012019-07-11 00:42:35 +02007049private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7050 f_tc_ho_neighbor_config_start();
7051
7052 /*
7053 * bts 0 ARFCN 871 BSIC 10
7054 * bts 1 ARFCN 871 BSIC 11
7055 * bts 2 ARFCN 871 BSIC 12
7056 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7057 */
7058
7059 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007060 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007061 f_sleep(0.5);
7062
7063 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7064 "handover any to arfcn 871 bsic 11",
7065 false);
7066 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7067 "handover any to arfcn 871 bsic 12",
7068 false);
7069 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7070 "handover any to arfcn 123 bsic 45",
7071 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007072 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007073}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007074testcase TC_ho_neighbor_config_4() runs on test_CT {
7075 var MSC_ConnHdlr vc_conn;
7076 f_init(3, true, guard_timeout := 50.0);
7077 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007078 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007079 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7080 vc_conn.done;
7081
7082 /* f_tc_ho_neighbor_config_start() */
7083 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7084 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7085
7086 /* 4.a */
7087 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7088 f_ctrs_bsc_and_bts_add(0, "handover:error");
7089
7090 /* 4.b */
7091 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7092 f_ctrs_bsc_and_bts_add(0, "handover:error");
7093
7094 /* 4.c */
7095 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7096 * handover quickly by timing out after the Handover Required message */
7097 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7098 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7099 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7100 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7101
7102 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007103 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007104}
7105
Neels Hofmeyr91401012019-07-11 00:42:35 +02007106private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7107 f_tc_ho_neighbor_config_start();
7108
7109 /*
7110 * bts 0 ARFCN 871 BSIC 10
7111 * bts 1 ARFCN 871 BSIC 11
7112 * bts 2 ARFCN 871 BSIC 12
7113 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7114 */
7115
7116 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 +02007117 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007118 f_sleep(0.5);
7119
7120 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7121 "handover any to arfcn 871 bsic 12",
7122 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007123 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007124}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007125testcase TC_ho_neighbor_config_5() runs on test_CT {
7126 var MSC_ConnHdlr vc_conn;
7127 f_init(3, true);
7128 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007129 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007130 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7131 vc_conn.done;
7132
7133 /* f_tc_ho_neighbor_config_start() */
7134 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7135 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7136
7137 /* 5 */
7138 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7139 * handover quickly by timing out after the Handover Required message */
7140 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7141 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7142 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7143 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7144
7145 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007146 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007147}
7148
Neels Hofmeyr91401012019-07-11 00:42:35 +02007149private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7150 f_tc_ho_neighbor_config_start();
7151
7152 /*
7153 * bts 0 ARFCN 871 BSIC 10
7154 * bts 1 ARFCN 871 BSIC 11
7155 * bts 2 ARFCN 871 BSIC 12
7156 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7157 */
7158
7159 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7160 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007161 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007162 f_sleep(0.5);
7163
7164 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7165 "handover any to arfcn 871 bsic 12",
7166 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007167 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007168}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007169testcase TC_ho_neighbor_config_6() runs on test_CT {
7170 var MSC_ConnHdlr vc_conn;
7171 f_init(3, true);
7172 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007173 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007174 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7175 vc_conn.done;
7176
7177 /* f_tc_ho_neighbor_config_start() */
7178 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7179 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7180
7181 /* 6.a */
7182 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7183 * handover quickly by timing out after the Handover Required message */
7184 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7185 f_ctrs_bsc_and_bts_add(0, "handover:error");
7186
7187 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007188 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007189}
7190
Neels Hofmeyr91401012019-07-11 00:42:35 +02007191private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7192 f_tc_ho_neighbor_config_start();
7193
7194 /*
7195 * bts 0 ARFCN 871 BSIC 10
7196 * bts 1 ARFCN 871 BSIC 11
7197 * bts 2 ARFCN 871 BSIC 12
7198 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7199 */
7200
7201 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7202 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007203 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007204 f_sleep(0.5);
7205
7206 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7207 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007208 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007209 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7210 "handover any to arfcn 123 bsic 45",
7211 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007212 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007213}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007214testcase TC_ho_neighbor_config_7() runs on test_CT {
7215 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007216 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007217 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007218 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007219 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7220 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007221
7222 /* f_tc_ho_neighbor_config_start() */
7223 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7224 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7225
7226 /* 7.a */
7227 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7228 * handover quickly by sending a Handover Failure message. */
7229 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7230 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7231 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7232 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007233 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7234 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007235
7236 /* 7.b */
7237 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7238 * handover quickly by timing out after the Handover Required message */
7239 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7240 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7241 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7242 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7243
7244 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007245 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007246}
7247
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007248/* OS#3041: Open and close N connections in a normal fashion, and expect no
7249 * BSSMAP Reset just because of that. */
7250testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7251 var default d;
7252 var integer i;
7253 var DchanTuple dt;
7254
7255 f_init();
7256
7257 /* Wait for initial BSSMAP Reset to pass */
7258 f_sleep(4.0);
7259
7260 d := activate(no_bssmap_reset());
7261
7262 /* Setup up a number of connections and RLSD them again from the MSC
7263 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7264 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007265 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007266 /* Since we're doing a lot of runs, give each one a fresh
7267 * T_guard from the top. */
7268 T_guard.start;
7269
7270 /* Setup a BSSAP connection and clear it right away. This is
7271 * the MSC telling the BSC about a planned release, it's not an
7272 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007273 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007274
7275 /* MSC disconnects (RLSD). */
7276 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7277 }
7278
7279 /* In the buggy behavior, a timeout of 2 seconds happens between above
7280 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7281 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7282 f_sleep(4.0);
7283
7284 deactivate(d);
7285 f_shutdown_helper();
7286}
Harald Welte552620d2017-12-16 23:21:36 +01007287
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007288/* OS#3041: Open and close N connections in a normal fashion, and expect no
7289 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7290 * the MSC. */
7291testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7292 var default d;
7293 var integer i;
7294 var DchanTuple dt;
7295 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007296 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7297 var BssmapCause cause := enum2int(cause_val);
7298
7299 f_init();
7300
7301 /* Wait for initial BSSMAP Reset to pass */
7302 f_sleep(4.0);
7303
7304 d := activate(no_bssmap_reset());
7305
7306 /* Setup up a number of connections and RLSD them again from the MSC
7307 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7308 * Let's do it some more times for good measure. */
7309 for (i := 0; i < 8; i := i+1) {
7310 /* Since we're doing a lot of runs, give each one a fresh
7311 * T_guard from the top. */
7312 T_guard.start;
7313
7314 /* Setup a BSSAP connection and clear it right away. This is
7315 * the MSC telling the BSC about a planned release, it's not an
7316 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007317 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007318
7319 /* Instruct BSC to clear channel */
7320 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7321
7322 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007323 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007324 }
7325
7326 /* In the buggy behavior, a timeout of 2 seconds happens between above
7327 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7328 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7329 f_sleep(4.0);
7330
7331 deactivate(d);
7332 f_shutdown_helper();
7333}
7334
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007335/* OS#3041: Open and close N connections in a normal fashion, and expect no
7336 * BSSMAP Reset just because of that. Close connections from the MS side with a
7337 * Release Ind on RSL. */
7338testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7339 var default d;
7340 var integer i;
7341 var DchanTuple dt;
7342 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007343 var integer j;
7344
7345 f_init();
7346
7347 /* Wait for initial BSSMAP Reset to pass */
7348 f_sleep(4.0);
7349
7350 d := activate(no_bssmap_reset());
7351
7352 /* Setup up a number of connections and RLSD them again from the MSC
7353 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7354 * Let's do it some more times for good measure. */
7355 for (i := 0; i < 8; i := i+1) {
7356 /* Since we're doing a lot of runs, give each one a fresh
7357 * T_guard from the top. */
7358 T_guard.start;
7359
7360 /* Setup a BSSAP connection and clear it right away. This is
7361 * the MSC telling the BSC about a planned release, it's not an
7362 * erratic loss of a connection. */
7363 dt := f_est_dchan('23'O, 23, '00010203040506'O);
7364
7365 /* simulate RLL REL IND */
7366 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
7367
7368 /* expect Clear Request on MSC side */
7369 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7370
7371 /* Instruct BSC to clear channel */
7372 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7373 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7374
7375 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007376 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007377 }
7378
7379 /* In the buggy behavior, a timeout of 2 seconds happens between above
7380 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7381 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7382 f_sleep(4.0);
7383
7384 deactivate(d);
7385 f_shutdown_helper();
7386}
7387
Harald Welte94e0c342018-04-07 11:33:23 +02007388/***********************************************************************
7389 * IPA style dynamic PDCH
7390 ***********************************************************************/
7391
7392private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7393 template (omit) RSL_Cause nack := omit)
7394runs on test_CT {
7395 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7396 var RSL_Message rsl_unused;
7397 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7398 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7399 /* expect the BSC to issue the related RSL command */
7400 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7401 if (istemplatekind(nack, "omit")) {
7402 /* respond with a related acknowledgement */
7403 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7404 } else {
7405 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
7406 }
7407}
7408
7409private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7410 template (omit) RSL_Cause nack := omit)
7411runs on test_CT {
7412 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7413 var RSL_Message rsl_unused;
7414 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7415 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7416 /* expect the BSC to issue the related RSL command */
7417 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
7418 if (istemplatekind(nack, "omit")) {
7419 /* respond with a related acknowledgement */
7420 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
7421 } else {
7422 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
7423 }
7424}
7425
7426private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7427runs on test_CT return charstring {
7428 var charstring cmd, resp;
7429 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007430 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007431}
7432
7433private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7434 template charstring exp)
7435runs on test_CT {
7436 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7437 if (not match(mode, exp)) {
7438 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007439 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007440 }
7441}
7442
7443private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7444runs on test_CT {
7445 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7446 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7447 f_vty_transceive(BSCVTY, "end");
7448}
7449
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007450
7451private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7452 var integer i;
7453 for (i := 0; i < 8; i := i + 1) {
7454 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7455 }
7456}
7457
Harald Welte94e0c342018-04-07 11:33:23 +02007458private const charstring TCHF_MODE := "TCH/F mode";
7459private const charstring TCHH_MODE := "TCH/H mode";
7460private const charstring PDCH_MODE := "PDCH mode";
7461private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007462private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007463
7464/* Test IPA PDCH activation / deactivation triggered by VTY */
7465testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7466 var RSL_Message rsl_unused;
7467
7468 /* change Timeslot 6 before f_init() starts RSL */
7469 f_init_vty();
7470 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7471 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7472
7473 f_init(1, false);
7474 f_sleep(1.0);
7475
7476 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7477
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007478 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007479 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7480 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7481 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7482 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7483 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007484 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007485 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7486
7487 /* De-activate it via VTY */
7488 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7489 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007490 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007491 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7492
7493 /* re-activate it via VTY */
7494 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7495 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007496 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007497 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7498
7499 /* and finally de-activate it again */
7500 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7501 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007502 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007503 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7504
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007505 /* clean up config */
7506 f_ts_set_chcomb(0, 0, 6, "PDCH");
7507
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007508 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007509}
7510
7511/* Test IPA PDCH activation NACK */
7512testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7513 var RSL_Message rsl_unused;
7514
7515 /* change Timeslot 6 before f_init() starts RSL */
7516 f_init_vty();
7517 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7518 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7519
7520 f_init(1, false);
7521 f_sleep(1.0);
7522
7523 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7524
7525 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7526 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7527 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7528 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7529 f_sleep(1.0);
7530 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7531
7532 /* De-activate it via VTY */
7533 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7534 f_sleep(1.0);
7535 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7536
7537 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7538 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7539 f_sleep(1.0);
7540 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7541
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007542 /* clean up config */
7543 f_ts_set_chcomb(0, 0, 6, "PDCH");
7544
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007545 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007546}
7547
7548
7549/***********************************************************************
7550 * Osmocom style dynamic PDCH
7551 ***********************************************************************/
7552
7553private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7554 template (omit) RSL_Cause nack := omit)
7555runs on test_CT {
7556 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7557 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007558 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007559 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7560 /* expect the BSC to issue the related RSL command */
7561 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7562 if (istemplatekind(nack, "omit")) {
7563 /* respond with a related acknowledgement */
7564 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7565 } else {
7566 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7567 }
7568}
7569
7570private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7571 template (omit) RSL_Cause nack := omit)
7572runs on test_CT {
7573 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7574 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007575 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007576 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7577 /* expect the BSC to issue the related RSL command */
7578 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7579 if (istemplatekind(nack, "omit")) {
7580 /* respond with a related acknowledgement */
7581 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7582 } else {
7583 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7584 }
7585}
7586
7587/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7588testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7589 var RSL_Message rsl_unused;
7590
7591 /* change Timeslot 6 before f_init() starts RSL */
7592 f_init_vty();
7593 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7594 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7595
7596 f_init(1, false);
7597 f_sleep(1.0);
7598
7599 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7600
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007601 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007602 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7603 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007604 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007605
7606 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7607 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007608 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 +02007609 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7610
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007611 /* clean up config */
7612 f_ts_set_chcomb(0, 0, 6, "PDCH");
7613
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007614 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007615}
7616
7617/* Test Osmocom dyn PDCH activation NACK behavior */
7618testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7619 var RSL_Message rsl_unused;
7620
7621 /* change Timeslot 6 before f_init() starts RSL */
7622 f_init_vty();
7623 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7624 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7625
7626 f_init(1, false);
7627 f_sleep(1.0);
7628
7629 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7630
7631 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7632 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007633 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007634
7635 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7636 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7637 f_sleep(1.0);
7638 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7639
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007640 /* clean up config */
7641 f_ts_set_chcomb(0, 0, 6, "PDCH");
7642
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007643 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007644}
7645
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007646/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7647testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7648 var RSL_Message rsl_unused, rsl_msg;
7649 var DchanTuple dt;
7650 var BSSAP_N_CONNECT_ind rx_c_ind;
7651
7652 /* change Timeslot 6 before f_init() starts RSL */
7653 f_init_vty();
7654 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7655 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7656
7657 f_init(1, false);
7658 f_sleep(1.0);
7659
7660 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7661
7662 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7663 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7664 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007665 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007666
7667 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7668 f_sleep(1.0);
7669 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7670 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7671
7672 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7673 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007674 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007675 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007676 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007677 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007678 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007679 }
7680
7681 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7682 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7683 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7684 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7685
7686 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7687 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7688
7689 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7690 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7691 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7692 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7693
7694 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7695 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7696 dt.sccp_conn_id := rx_c_ind.connectionId;
7697 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7698
7699 /* Instruct BSC to clear channel */
7700 var BssmapCause cause := 0;
7701 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7702 f_exp_chan_rel_and_clear(dt, 0);
7703
7704 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007705 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007706 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7707 f_sleep(1.0);
7708 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7709
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007710 /* Clean up SDCCH lchans */
7711 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
7712 f_perform_clear_test_ct(sdcch_cleanup[i]);
7713 }
7714
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007715 /* clean up config */
7716 f_ts_set_chcomb(0, 0, 6, "PDCH");
7717
7718 f_shutdown_helper();
7719}
7720
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007721/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7722testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7723 var ASP_RSL_Unitdata rsl_ud;
7724 var integer i;
7725 var integer chreq_total, chreq_nochan;
7726
7727 f_init_vty();
7728 for (i := 1; i < 8; i := i + 1) {
7729 if (i == 2) {
7730 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7731 } else {
7732 f_ts_set_chcomb(0, 0, i, "PDCH");
7733 }
7734 }
7735 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7736
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007737 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007738
7739 /* The dyn TS want to activate PDCH mode, ACK that. */
7740 var RslChannelNr chan_nr;
7741 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007742 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007743 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7744
7745 f_sleep(1.0);
7746
7747 /* Exhaust all dedicated SDCCH lchans.
7748 /* GSM 44.018 Table 9.1.8.2:
7749 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7750 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007751 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007752 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007753 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007754 }
7755
7756 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007757 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007758 /* Also occupy the seven other SDCCH of the dyn TS */
7759 for (i := 0; i < 7; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007760 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
7761 }
7762
7763 /* Clean up SDCCH lchans */
7764 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7765 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007766 }
7767
7768 /* clean up config */
7769 f_ts_reset_chcomb(0);
7770
7771 f_shutdown_helper();
7772}
7773
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007774/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7775 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7776 it as TCH directly instead. SYS#5309. */
7777testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7778 var RSL_Message rsl_unused, rsl_msg;
7779 var DchanTuple dt;
7780 var BSSAP_N_CONNECT_ind rx_c_ind;
7781 var integer i;
7782
7783 /* change Timeslot 6 before f_init() starts RSL */
7784 f_init_vty();
7785 for (i := 1; i < 8; i := i + 1) {
7786 if (i == 6) {
7787 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7788 } else {
7789 f_ts_set_chcomb(0, 0, i, "PDCH");
7790 }
7791 }
7792 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7793
7794 f_init(1, false);
7795 f_sleep(1.0);
7796
7797 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7798
7799 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7800 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7801 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007802 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007803
7804 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7805 f_sleep(1.0);
7806 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7807 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7808
7809 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7810 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007811 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007812 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007813 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007814 dt := f_est_dchan(ra, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007815 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007816 }
7817
7818 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007819 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007820 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7821 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7822
7823 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7824 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7825
7826 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7827 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7828 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7829 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7830
7831 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7832 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7833 dt.sccp_conn_id := rx_c_ind.connectionId;
7834 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7835
7836 /* Instruct BSC to clear channel */
7837 var BssmapCause cause := 0;
7838 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7839 f_exp_chan_rel_and_clear(dt, 0);
7840
7841 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007842 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007843 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7844 f_sleep(1.0);
7845 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7846
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007847 /* Clean up SDCCH lchans */
7848 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7849 f_perform_clear_test_ct(chan_cleanup[i]);
7850 }
7851
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007852 /* clean up config */
7853 f_ts_reset_chcomb(0);
7854 /* TODO: clean up other channels? */
7855
7856 f_shutdown_helper();
7857}
7858
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007859/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7860testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7861 var RSL_Message rsl_unused, rsl_msg;
7862 var DchanTuple dt;
7863 var BSSAP_N_CONNECT_ind rx_c_ind;
7864 var GsmRrMessage rr;
7865
7866 /* change Timeslot 6 before f_init() starts RSL */
7867 f_init_vty();
7868 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7869 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7870
7871 f_init(1, false);
7872 f_sleep(1.0);
7873
7874 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7875
7876 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7877 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7878 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007879 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007880
7881 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7882 f_sleep(1.0);
7883 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7884 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7885
7886 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7887 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007888 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007889 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007890 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007891 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007892 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007893 }
7894
7895 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7896 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7897 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7898 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7899
7900 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7901 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7902
7903 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7904 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7905 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7906 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7907 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7908 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7909 }
7910
7911 /* FIXME? Currently the TS stays in state BORKEN: */
7912
7913 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007914 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007915 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7916 * f_sleep(1.0);
7917 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7918 */
7919
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007920 /* Clean up SDCCH lchans */
7921 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7922 f_perform_clear_test_ct(chan_cleanup[i]);
7923 }
7924
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007925 /* clean up config */
7926 f_ts_set_chcomb(0, 0, 6, "PDCH");
7927
7928 f_shutdown_helper();
7929}
7930
Stefan Sperling0796a822018-10-05 13:01:39 +02007931testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007932 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007933 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7934 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7935 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007936 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007937}
7938
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007939testcase TC_chopped_ipa_payload() runs on test_CT {
7940 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7941 /* TODO: mp_bsc_ctrl_port does not work yet */};
7942 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7943 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7944 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007945 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007946}
7947
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007948/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7949 the BTS does autonomous MS power control loop */
7950testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7951 var MSC_ConnHdlr vc_conn;
7952 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7953 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7954 pars.exp_ms_power_params := true;
7955
7956 f_init(1, true);
7957 f_sleep(1.0);
7958 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7959 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007960 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007961}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007962
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007963/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7964testcase TC_c0_power_red_mode() runs on test_CT {
7965 f_init(1);
7966
7967 for (var integer red := 6; red >= 0; red := red - 2) {
7968 /* Configure BCCH carrier power reduction mode via the VTY */
7969 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7970
7971 /* Expect Osmocom specific BS Power Control message on the RSL */
7972 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7973 chan_nr := t_RslChanNr_BCCH(0),
7974 bs_power := tr_RSL_IE_BS_Power(red / 2));
7975 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7976 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7977
7978 /* Additionally verify the applied value over the CTRL interface */
7979 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7980 if (cred != int2str(red)) {
7981 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7982 cred, " (expected ", red, ")");
7983 }
7984 }
7985
7986 f_shutdown_helper();
7987}
7988
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007989/***********************************************************************
7990 * MSC Pooling
7991 ***********************************************************************/
7992
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007993template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007994 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 +02007995
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007996private 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 +02007997runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007998 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007999 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008000 f_logp(BSCVTY, "Got RSL RR Release");
8001 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008002 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008003 f_logp(BSCVTY, "Got RSL Deact SACCH");
8004 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008005 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008006 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008007 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8008 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008009 break;
8010 }
8011 }
8012}
8013
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008014private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8015 var MgcpCommand mgcp_cmd;
8016 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8017 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8018 repeat;
8019 }
8020}
8021
8022private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8023 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8024 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8025 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8026 repeat;
8027 }
8028}
8029
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008030friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8031 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008032runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008033 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8034 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008035 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008036 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8037 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008038 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008039 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008040 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008041 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008042 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008043 }
8044 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008045 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008046 /* Also drop the SCCP connection */
8047 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8048 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008049 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008050 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008051 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8052 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008053 }
8054 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008055 deactivate(ack_dlcx);
8056 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008057}
8058
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008059friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8060runs on MSC_ConnHdlr {
8061 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8062 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8063 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8064 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8065 interleave {
8066 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8067 f_logp(BSCVTY, "Got RSL Deact SACCH");
8068 }
8069 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8070 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8071 /* Also drop the SCCP connection */
8072 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8073 }
8074 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8075 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8076 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8077 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8078 }
8079 }
8080 deactivate(ack_dlcx);
8081 deactivate(ack_rel_req);
8082}
8083
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008084friend function f_perform_clear_no_lchan()
8085runs on MSC_ConnHdlr {
8086 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8087 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8088 BSSAP.receive(tr_BSSMAP_ClearComplete);
8089 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8090 /* Also drop the SCCP connection */
8091 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8092}
8093
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008094private function f_perform_clear_test_ct(DchanTuple dt)
8095 runs on test_CT
8096{
8097 /* Instruct BSC to clear channel */
8098 var BssmapCause cause := 0;
8099 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
8100 f_exp_chan_rel_and_clear(dt, 0);
8101}
8102
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008103private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8104 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008105runs on MSC_ConnHdlr {
8106 timer T := 10.0;
8107 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8108
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008109 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008110 f_create_bssmap_exp(l3_enc);
8111
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008112 /* RSL_Emulation.f_chan_est() on rsl_pt:
8113 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008114 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8115 */
8116 var RSL_Message rx_rsl;
8117 var GsmRrMessage rr;
8118
8119 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008120 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008121 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008122 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008123 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8124 */
8125 timer Tt := 10.0;
8126
8127 /* request a channel to be established */
8128 Tt.start;
8129 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008130 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008131 Tt.stop;
8132 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008133 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008134 setverdict(fail, "Unexpected RSL message on DCHAN");
8135 mtc.stop;
8136 }
8137 [] Tt.timeout {
8138 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8139 mtc.stop;
8140 }
8141 }
8142 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8143 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008144 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008145
8146
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008147 if (expect_bssmap_l3) {
8148 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8149 var template PDU_BSSAP exp_l3_compl;
8150 exp_l3_compl := tr_BSSMAP_ComplL3()
8151 if (g_pars.aoip == false) {
8152 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8153 } else {
8154 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8155 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008156
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008157 var PDU_BSSAP bssap;
8158 T.start;
8159 alt {
8160 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8161 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8162 log("rx exp_l3_compl = ", bssap);
8163 }
8164 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8165 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8166 }
8167 [] T.timeout {
8168 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8169 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008170 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008171
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008172 /* start ciphering, if requested */
8173 if (ispresent(g_pars.encr)) {
8174 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008175 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008176 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008177 }
8178
8179 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008180 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008181 }
8182 setverdict(pass);
8183 f_sleep(1.0);
8184}
8185
8186private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8187 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8188 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008189 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008190 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008191 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008192 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008193 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008194 }
8195}
8196
8197/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8198private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8199 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008200 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8201 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8202 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8203 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 +02008204}
8205testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8206
8207 f_init(1, true);
8208 f_sleep(1.0);
8209 var MSC_ConnHdlr vc_conn;
8210 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008211
8212 f_ctrs_msc_init();
8213
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008214 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8215 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008216
8217 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008218 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008219}
8220
8221/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8222/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8223 * just as well using only RSL. */
8224testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8225
8226 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8227 f_sleep(1.0);
8228
8229 /* Control which MSC gets chosen next by the round-robin, otherwise
8230 * would be randomly affected by which other tests ran before this. */
8231 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8232
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008233 f_ctrs_msc_init();
8234
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008235 var MSC_ConnHdlr vc_conn1;
8236 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8237 pars1.mscpool.rsl_idx := 0;
8238 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8239 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8240 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008241 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008242
8243 var MSC_ConnHdlr vc_conn2;
8244 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8245 pars2.mscpool.rsl_idx := 1;
8246 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8247 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8248 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008249 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008250
8251 /* Test round-robin wrap to the first MSC */
8252 var MSC_ConnHdlr vc_conn3;
8253 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8254 pars3.mscpool.rsl_idx := 2;
8255 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8256 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8257 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008258 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008259 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008260}
8261
8262/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8263 * (configured in osmo-bsc.cfg). */
8264/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8265 * just as well using only RSL. */
8266testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8267
8268 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8269 f_sleep(1.0);
8270
8271 /* Control which MSC gets chosen next by the round-robin, otherwise
8272 * would be randomly affected by which other tests ran before this. */
8273 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8274
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008275 f_ctrs_msc_init();
8276
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008277 var MSC_ConnHdlr vc_conn1;
8278 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8279 pars1.mscpool.rsl_idx := 0;
8280 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8281 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8282 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008283 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008284
8285 var MSC_ConnHdlr vc_conn2;
8286 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8287 pars2.mscpool.rsl_idx := 1;
8288 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8289 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8290 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008291 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008292
8293 /* Test round-robin wrap to the first MSC */
8294 var MSC_ConnHdlr vc_conn3;
8295 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8296 pars3.mscpool.rsl_idx := 2;
8297 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8298 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8299 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008300 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008301 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008302}
8303
8304/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8305 * (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
8306 * NULL-NRI setting is stronger than that. */
8307/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8308 * just as well using only RSL. */
8309testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8310
8311 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8312 f_sleep(1.0);
8313
8314 /* Control which MSC gets chosen next by the round-robin, otherwise
8315 * would be randomly affected by which other tests ran before this. */
8316 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8317
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008318 f_ctrs_msc_init();
8319
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008320 var MSC_ConnHdlr vc_conn1;
8321 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8322 pars1.mscpool.rsl_idx := 0;
8323 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8324 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8325 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008326 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008327
8328 var MSC_ConnHdlr vc_conn2;
8329 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8330 pars2.mscpool.rsl_idx := 1;
8331 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8332 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8333 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008334 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008335
8336 /* Test round-robin wrap to the first MSC */
8337 var MSC_ConnHdlr vc_conn3;
8338 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8339 pars3.mscpool.rsl_idx := 2;
8340 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8341 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8342 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008343 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008344 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008345}
8346
8347/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8348 * assigned to any MSC (configured in osmo-bsc.cfg). */
8349/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8350 * just as well using only RSL. */
8351testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8352
8353 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8354 f_sleep(1.0);
8355
8356 /* Control which MSC gets chosen next by the round-robin, otherwise
8357 * would be randomly affected by which other tests ran before this. */
8358 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8359
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008360 f_ctrs_msc_init();
8361
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008362 var MSC_ConnHdlr vc_conn1;
8363 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8364 pars1.mscpool.rsl_idx := 0;
8365 /* An NRI that is not assigned to any MSC */
8366 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8367 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8368 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008369 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008370
8371 var MSC_ConnHdlr vc_conn2;
8372 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8373 pars2.mscpool.rsl_idx := 1;
8374 /* An NRI that is not assigned to any MSC */
8375 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8376 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8377 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008378 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008379
8380 /* Test round-robin wrap to the first MSC */
8381 var MSC_ConnHdlr vc_conn3;
8382 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8383 pars3.mscpool.rsl_idx := 2;
8384 /* An NRI that is not assigned to any MSC */
8385 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8386 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8387 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008388 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008389 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008390}
8391
8392/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8393 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8394/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8395 * just as well using only RSL. */
8396testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8397
8398 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8399 f_sleep(1.0);
8400
8401 /* Control which MSC gets chosen next by the round-robin, otherwise
8402 * would be randomly affected by which other tests ran before this. */
8403 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8404
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008405 f_ctrs_msc_init();
8406
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008407 var MSC_ConnHdlr vc_conn1;
8408 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8409 pars1.mscpool.rsl_idx := 0;
8410 /* An NRI that is assigned to an unconnected MSC */
8411 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8412 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8413 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008414 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8415 f_ctrs_msc_add(0, "mscpool:subscr:new");
8416 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008417
8418 var MSC_ConnHdlr vc_conn2;
8419 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8420 pars2.mscpool.rsl_idx := 1;
8421 /* An NRI that is assigned to an unconnected MSC */
8422 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8423 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8424 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008425 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8426 f_ctrs_msc_add(1, "mscpool:subscr:new");
8427 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008428
8429 /* Test round-robin wrap to the first MSC */
8430 var MSC_ConnHdlr vc_conn3;
8431 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8432 pars3.mscpool.rsl_idx := 2;
8433 /* An NRI that is assigned to an unconnected MSC */
8434 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8435 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8436 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008437 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8438 f_ctrs_msc_add(0, "mscpool:subscr:new");
8439 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008440 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008441}
8442
8443/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8444 * osmo-bsc.cfg). */
8445/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8446 * just as well using only RSL. */
8447testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8448
8449 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8450 f_sleep(1.0);
8451
8452 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8453 * this is not using round-robin. */
8454 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8455
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008456 f_ctrs_msc_init();
8457
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008458 var MSC_ConnHdlr vc_conn1;
8459 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8460 pars1.mscpool.rsl_idx := 0;
8461 /* An NRI of the second MSC's range (256-511) */
8462 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8463 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8464 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008465 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008466
8467 var MSC_ConnHdlr vc_conn2;
8468 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8469 pars2.mscpool.rsl_idx := 1;
8470 /* An NRI of the second MSC's range (256-511) */
8471 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8472 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8473 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008474 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008475
8476 var MSC_ConnHdlr vc_conn3;
8477 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8478 pars3.mscpool.rsl_idx := 2;
8479 /* An NRI of the second MSC's range (256-511) */
8480 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8481 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8482 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008483 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008484 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008485}
8486
8487/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8488 * while a round-robin remains unaffected by that. */
8489/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8490 * just as well using only RSL. */
8491testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8492
8493 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8494 f_sleep(1.0);
8495
8496 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8497 * this is not using round-robin. */
8498 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8499
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008500 f_ctrs_msc_init();
8501
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008502 var MSC_ConnHdlr vc_conn1;
8503 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8504 pars1.mscpool.rsl_idx := 0;
8505 /* An NRI of the third MSC's range (512-767) */
8506 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8507 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8508 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008509 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008510
8511 var MSC_ConnHdlr vc_conn2;
8512 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8513 pars2.mscpool.rsl_idx := 1;
8514 /* An NRI of the third MSC's range (512-767) */
8515 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8516 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8517 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008518 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008519
8520 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8521 var MSC_ConnHdlr vc_conn3;
8522 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8523 pars3.mscpool.rsl_idx := 2;
8524 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8525 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8526 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008527 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008528 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008529}
8530
8531/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8532/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8533 * just as well using only RSL. */
8534testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8535
8536 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8537 f_sleep(1.0);
8538
8539 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8540 * instead, and hits msc 0. */
8541 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8542
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008543 f_ctrs_msc_init();
8544
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008545 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8546 var MSC_ConnHdlr vc_conn1;
8547 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8548 pars1.mscpool.rsl_idx := 0;
8549 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8550 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8551 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008552 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008553
8554 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8555 var MSC_ConnHdlr vc_conn2;
8556 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8557 pars2.mscpool.rsl_idx := 1;
8558 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8559 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8560 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008561 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008562 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008563}
8564
8565/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8566 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8567private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8568 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8569 //cid_list := { cIl_allInBSS := ''O };
8570 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8571 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8572 var BSSAP_N_UNITDATA_req paging;
8573 var hexstring imsi := '001010000000123'H;
8574
8575 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8576
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008577 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008578 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8579 BSSAP.send(paging);
8580
8581 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8582 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8583 * channel number is picked here. */
8584 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8585 f_rslem_register(0, new_chan_nr);
8586 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8587 f_rslem_unregister(0, new_chan_nr);
8588
8589 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8590 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008591 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008592 f_sleep(1.0);
8593}
8594testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8595 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8596 f_sleep(1.0);
8597
8598 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8599 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8600 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8601
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008602 f_ctrs_msc_init();
8603
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008604 var MSC_ConnHdlr vc_conn1;
8605 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8606 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008607 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8608 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008609 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8610 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008611 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008612 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008613}
8614
8615/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8616 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8617private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8618 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8619 //cid_list := { cIl_allInBSS := ''O };
8620 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8621 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8622 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008623 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008624 var BSSAP_N_UNITDATA_req paging;
8625
8626 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8627
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008628 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008629 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8630 BSSAP.send(paging);
8631
8632 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8633 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8634 * channel number is picked here. */
8635 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8636 f_rslem_register(0, new_chan_nr);
8637 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8638 f_rslem_unregister(0, new_chan_nr);
8639
8640 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8641 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8642 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008643 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 +02008644 f_sleep(1.0);
8645}
8646testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8647 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8648 f_sleep(1.0);
8649
8650 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8651 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8652 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8653
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008654 f_ctrs_msc_init();
8655
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008656 var MSC_ConnHdlr vc_conn1;
8657 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8658 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008659 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8660 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008661 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8662 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008663 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008664 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008665}
8666
8667/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8668/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8669 * just as well using only RSL. */
8670testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8671
8672 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8673 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008674 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8675 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008676
8677 /* Control which MSC gets chosen next by the round-robin, otherwise
8678 * would be randomly affected by which other tests ran before this. */
8679 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8680
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008681 f_ctrs_msc_init();
8682
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008683 var MSC_ConnHdlr vc_conn1;
8684 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8685 pars1.mscpool.rsl_idx := 0;
8686 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8687 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8688 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008689 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008690
8691 var MSC_ConnHdlr vc_conn2;
8692 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8693 pars2.mscpool.rsl_idx := 1;
8694 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8695 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8696 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008697 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008698
8699 var MSC_ConnHdlr vc_conn3;
8700 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8701 pars3.mscpool.rsl_idx := 2;
8702 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8703 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8704 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008705 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008706 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008707}
8708
8709/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8710 * TMSI NRI. */
8711testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8712
8713 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8714 f_sleep(1.0);
8715
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008716 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8717 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8718
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008719 /* Control which MSC gets chosen next by the round-robin, otherwise
8720 * would be randomly affected by which other tests ran before this. */
8721 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8722
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008723 f_ctrs_msc_init();
8724
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008725 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8726 var MSC_ConnHdlr vc_conn1;
8727 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8728 pars1.mscpool.rsl_idx := 0;
8729 /* An NRI of the second MSC's range (256-511) */
8730 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8731 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8732 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008733 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008734
8735 var MSC_ConnHdlr vc_conn2;
8736 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8737 pars2.mscpool.rsl_idx := 1;
8738 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8739 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8740 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008741 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008742
8743 var MSC_ConnHdlr vc_conn3;
8744 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8745 pars3.mscpool.rsl_idx := 2;
8746 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8747 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8748 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008749 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008750 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008751}
8752
Philipp Maier783681c2020-07-16 16:47:06 +02008753/* Allow/Deny emergency calls globally via VTY */
8754private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8755 f_vty_enter_cfg_msc(BSCVTY, 0);
8756 if (allow) {
8757 f_vty_transceive(BSCVTY, "allow-emergency allow");
8758 } else {
8759 f_vty_transceive(BSCVTY, "allow-emergency deny");
8760 }
8761 f_vty_transceive(BSCVTY, "exit");
8762 f_vty_transceive(BSCVTY, "exit");
8763}
8764
8765/* Allow/Deny emergency calls per BTS via VTY */
8766private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8767 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8768 if (allow) {
8769 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8770 } else {
8771 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8772 }
8773 f_vty_transceive(BSCVTY, "exit");
8774 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008775 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008776}
8777
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008778/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8779private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8780 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8781 if (allow) {
8782 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8783 } else {
8784 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8785 }
8786 f_vty_transceive(BSCVTY, "exit");
8787 f_vty_transceive(BSCVTY, "exit");
8788 f_vty_transceive(BSCVTY, "exit");
8789}
8790
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008791/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8792private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8793 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8794 if (allow) {
8795 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8796 } else {
8797 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8798 }
8799 f_vty_transceive(BSCVTY, "exit");
8800 f_vty_transceive(BSCVTY, "exit");
8801 f_vty_transceive(BSCVTY, "exit");
8802}
8803
Philipp Maier783681c2020-07-16 16:47:06 +02008804/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8805private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8806 var PDU_ML3_MS_NW emerg_setup;
8807 var octetstring emerg_setup_enc;
8808 var RSL_Message emerg_setup_data_ind;
8809
8810 f_establish_fully(omit, omit);
8811
8812 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8813 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8814 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8815
8816 RSL.send(emerg_setup_data_ind);
8817}
8818
8819/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8820 * CALLS are permitted by the BSC config. */
8821private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8822 var PDU_BSSAP emerg_setup_data_ind_bssap;
8823 var PDU_ML3_MS_NW emerg_setup;
8824 timer T := 3.0;
8825
8826 f_assignment_emerg_setup()
8827
8828 T.start;
8829 alt {
8830 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8831 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8832 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8833 setverdict(fail, "no emergency setup");
8834 }
8835 }
8836 [] BSSAP.receive {
8837 setverdict(fail, "unexpected BSSAP message!");
8838 }
8839 [] T.timeout {
8840 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8841 }
8842 }
8843
8844 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008845 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02008846}
8847
8848/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8849 * forbidden by the BSC config. */
8850private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8851 var PDU_BSSAP emerg_setup_data_ind_bssap;
8852 timer T := 3.0;
8853
8854 f_assignment_emerg_setup()
8855
8856 T.start;
8857 alt {
8858 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8859 setverdict(pass);
8860 }
8861 [] RSL.receive {
8862 setverdict(fail, "unexpected RSL message!");
8863 }
8864 [] T.timeout {
8865 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8866 }
8867 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008868 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008869 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02008870}
8871
8872/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8873testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8874 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8875 var MSC_ConnHdlr vc_conn;
8876
8877 f_init(1, true);
8878 f_sleep(1.0);
8879
8880 f_vty_allow_emerg_msc(true);
8881 f_vty_allow_emerg_bts(true, 0);
8882 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8883 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008884 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008885}
8886
8887/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8888testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8889 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8890 var MSC_ConnHdlr vc_conn;
8891
8892 f_init(1, true);
8893 f_sleep(1.0);
8894
8895 f_vty_allow_emerg_msc(false);
8896 f_vty_allow_emerg_bts(true, 0);
8897 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8898 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008899 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008900}
8901
8902/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8903testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8904 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8905 var MSC_ConnHdlr vc_conn;
8906
8907 /* Note: This simulates a spec violation by the MS, correct MS
8908 * implementations would not try to establish an emergency call because
8909 * the system information tells in advance that emergency calls are
8910 * not forbidden */
8911
8912 f_init(1, true);
8913 f_sleep(1.0);
8914
8915 f_vty_allow_emerg_msc(true);
8916 f_vty_allow_emerg_bts(false, 0);
8917 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8918 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008919 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008920}
8921
Philipp Maier82812002020-08-13 18:48:27 +02008922/* Test what happens when an emergency call arrives while all TCH channels are
8923 * busy, the BSC is expected to terminate one call in favor of the incoming
8924 * emergency call */
8925testcase TC_emerg_premption() runs on test_CT {
8926 var ASP_RSL_Unitdata rsl_ud;
8927 var integer i;
8928 var integer chreq_total, chreq_nochan;
8929 var RSL_Message rx_rsl;
8930 var RslChannelNr chan_nr;
8931
8932 f_init(1);
8933 f_sleep(1.0);
8934
8935 f_vty_allow_emerg_msc(true);
8936 f_vty_allow_emerg_bts(true, 0);
8937
8938 /* Fill up all channels on the BTS */
8939 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8940 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8941 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8942 chan_nr := f_chreq_act_ack('33'O, i);
8943 }
8944 IPA_RSL[0].clear;
8945 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8946 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8947
8948 /* Send Channel request for emegergency call */
8949 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8950
8951 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8952 chan_nr := valueof(t_RslChanNr_Bm(1));
8953 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8954
8955 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8956 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8957 chan_nr := rx_rsl.ies[0].body.chan_nr;
8958 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8959 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008960
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008961 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008962}
8963
8964/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008965private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008966private type record FHParamsTs {
8967 boolean enabled,
8968 uint6_t hsn,
8969 uint6_t maio,
8970 ArfcnList ma
8971};
8972
8973/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008974private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02008975 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008976 FHParamsTs ts[8]
8977};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008978
8979/* Randomly generate the hopping parameters for the given timeslot numbers */
8980private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8981runs on test_CT return FHParamsTrx {
8982 var FHParamsTrx fhp;
8983
Philipp Maier798d8952021-10-19 14:43:19 +02008984 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
8985 * fall in the GSM900 band. */
8986 fhp.arfcn.arfcn := f_rnd_int(3);
8987 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008988
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008989 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8990 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008991 fhp.ts[tn].enabled := false;
8992 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008993 continue;
8994 }
8995
8996 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008997 fhp.ts[tn].hsn := f_rnd_int(64);
8998 fhp.ts[tn].maio := f_rnd_int(64);
8999 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009000
9001 /* Random Mobile Allocation (hopping channels) */
9002 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9003 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9004 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009005 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009006 }
9007
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009008 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009009 }
9010
9011 log("f_TC_fh_params_gen(): ", fhp);
9012 return fhp;
9013}
9014
9015/* Make sure that the given Channel Description IE matches the hopping configuration */
9016private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9017{
9018 var template (present) ChannelDescription tr_cd;
9019 var template (present) MaioHsn tr_maio_hsn;
9020 var uint3_t tn := cd.chan_nr.tn;
9021
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009022 if (fhp.ts[tn].enabled) {
9023 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009024 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9025 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009026 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009027 }
9028
9029 if (not match(cd, tr_cd)) {
9030 setverdict(fail, "Channel Description IE does not match: ",
9031 cd, " vs expected ", tr_cd);
9032 }
9033}
9034
9035/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9036private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9037 in MobileAllocationLV ma)
9038{
9039 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9040
9041 if (not match(ma, tr_ma)) {
9042 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9043 tn, "): ", ma, " vs expected: ", tr_ma);
9044 } else {
9045 setverdict(pass);
9046 }
9047}
9048
9049private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9050 in MobileAllocationLV ma)
9051return template MobileAllocationLV {
9052 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009053 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009054 return { len := 0, ma := ''B };
9055 }
9056
9057 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9058 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9059 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009060
9061 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009062 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9063 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9064 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009065 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009066 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009067 }
9068 }
9069
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009070 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009071 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009072
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009073 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009074 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9075 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009076 }
9077
9078 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009079 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009080 if (full_mask[i] != '1'B)
9081 { continue; }
9082
9083 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9084 if (slot_mask[i] == '1'B) {
9085 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009086 } else {
9087 ma_mask := ma_mask & '0'B;
9088 }
9089 }
9090
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009091 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9092 if (full_mask[0] == '1'B) {
9093 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9094 if (slot_mask[0] == '1'B) {
9095 ma_mask := ma_mask & '1'B;
9096 } else {
9097 ma_mask := ma_mask & '0'B;
9098 }
9099 }
9100
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009101 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009102 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009103 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9104
9105 return { len := ma_mask_len, ma := ma_mask };
9106}
9107
Philipp Maier798d8952021-10-19 14:43:19 +02009108/* Configure the appropriate band for a given arfcn, exc */
9109private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9110{
9111 var charstring band;
9112 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9113
9114 select (arfcn_) {
9115 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9116 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9117 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9118 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9119 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9120 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9121 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9122 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9123 case else { return; }
9124 }
9125
9126 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9127 f_vty_transceive(BSCVTY, "band " & band);
9128 f_vty_transceive(BSCVTY, "end");
9129}
9130
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009131/* Configure the hopping parameters in accordance with the given record */
9132private function f_TC_fh_params_set(in FHParamsTrx fhp,
9133 uint8_t bts_nr := 0,
9134 uint8_t trx_nr := 0)
9135runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009136
9137 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9138
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009139 /* Enter the configuration node for the given BTS/TRX numbers */
9140 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9141
Philipp Maier798d8952021-10-19 14:43:19 +02009142 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009143
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009144 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009145 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9146
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009147 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009148 f_vty_transceive(BSCVTY, "hopping enabled 0");
9149 f_vty_transceive(BSCVTY, "exit"); /* go back */
9150 continue;
9151 }
9152
9153 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009154 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9155 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009156
9157 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009158 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9159 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009160 }
9161
9162 f_vty_transceive(BSCVTY, "hopping enabled 1");
9163 f_vty_transceive(BSCVTY, "exit"); /* go back */
9164 }
9165
9166 f_vty_transceive(BSCVTY, "end");
9167}
9168
9169/* Disable frequency hopping on all timeslots */
9170private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9171 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009172 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009173 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009174runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009175
9176 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9177
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009178 /* Enter the configuration node for the given BTS/TRX numbers */
9179 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9180
Philipp Maier798d8952021-10-19 14:43:19 +02009181 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009182
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009183 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009184 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9185
9186 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009187 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9188 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009189 }
9190
9191 f_vty_transceive(BSCVTY, "hopping enabled 0");
9192 f_vty_transceive(BSCVTY, "exit"); /* go back */
9193 }
9194
9195 f_vty_transceive(BSCVTY, "end");
9196 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9197}
9198
9199/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9200 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9201testcase TC_fh_params_chan_activ() runs on test_CT {
9202 var FHParamsTrx fhp := f_TC_fh_params_gen();
9203 var RSL_Message rsl_msg;
9204 var RSL_IE_Body ie;
9205
9206 f_init_vty();
9207
9208 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9209 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9210
9211 f_init(1);
9212
9213 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9214 for (var integer i := 0; i < 9; i := i + 1) {
9215 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9216 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9217
9218 /* Make sure that Channel Identification IE is present */
9219 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9220 setverdict(fail, "RSL Channel Identification IE is absent");
9221 continue;
9222 }
9223
9224 /* Make sure that hopping parameters (HSN/MAIO) match */
9225 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9226
9227 /* "Mobile Allocation shall be included but empty" - let's check this */
9228 if (ie.chan_ident.ma.v.len != 0) {
9229 setverdict(fail, "Mobile Allocation IE is not empty: ",
9230 ie.chan_ident.ma, ", despite it shall be");
9231 continue;
9232 }
9233 }
9234
9235 /* Disable frequency hopping */
9236 f_TC_fh_params_unset(fhp);
9237
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009238 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009239}
9240
9241/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9242testcase TC_fh_params_imm_ass() runs on test_CT {
9243 var FHParamsTrx fhp := f_TC_fh_params_gen();
9244 var RSL_Message rsl_msg;
9245 var RSL_IE_Body ie;
9246
9247 f_init_vty();
9248
9249 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9250 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9251
9252 f_init(1);
9253
9254 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9255 for (var integer i := 0; i < 9; i := i + 1) {
9256 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9257 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9258
9259 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9260 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
9261
9262 /* Make sure that Full Immediate Assign Info IE is present */
9263 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9264 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9265 continue;
9266 }
9267
9268 /* Decode the actual Immediate Assignment message */
9269 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9270 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9271 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9272 continue;
9273 }
9274
9275 /* Make sure that hopping parameters (HSN/MAIO) match */
9276 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9277
9278 /* Make sure that the Mobile Allocation IE matches */
9279 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9280 rr_msg.payload.imm_ass.mobile_allocation);
9281 }
9282
9283 /* Disable frequency hopping */
9284 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009285
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009286 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009287}
9288
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009289/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9290testcase TC_fh_params_assignment_cmd() runs on test_CT {
9291 var FHParamsTrx fhp := f_TC_fh_params_gen();
9292 var RSL_Message rsl_msg;
9293 var RSL_IE_Body ie;
9294
9295 f_init_vty();
9296
9297 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9298 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9299
9300 f_init(1);
9301
9302 /* HACK: work around "Couldn't find Expect for CRCX" */
9303 vc_MGCP.stop;
9304
9305 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9306 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9307
9308 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9309 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9310 for (var integer i := 0; i < 3; i := i + 1) {
9311 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
9312 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
9313
9314 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9315 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
9316 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9317
9318 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
9319 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9320 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9321
9322 /* Make sure that L3 Information IE is present */
9323 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9324 setverdict(fail, "RSL L3 Information IE is absent");
9325 continue;
9326 }
9327
9328 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9329 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9330 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9331 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9332 continue;
9333 }
9334
9335 /* Make sure that hopping parameters (HSN/MAIO) match */
9336 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9337 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9338
9339 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9340 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009341 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009342 continue;
9343 }
9344
9345 /* Make sure that the Mobile Allocation IE matches (if present) */
9346 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9347 if (chan_desc.h and ma_present) {
9348 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9349 l3_msg.payload.ass_cmd.mobile_allocation.v);
9350 } else if (chan_desc.h and not ma_present) {
9351 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9352 continue;
9353 } else if (not chan_desc.h and ma_present) {
9354 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9355 continue;
9356 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009357
9358 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009359 }
9360
9361 /* Give the IUT some time to release all channels */
9362 f_sleep(3.0);
9363
9364 /* Disable frequency hopping */
9365 f_TC_fh_params_unset(fhp);
9366
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009367 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009368}
9369
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009370/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9371private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9372runs on test_CT {
9373 var RSL_Message rsl_msg;
9374 var RSL_IE_Body ie;
9375 var DchanTuple dt;
9376
9377 /* Establish a dedicated channel, so we can trigger handover */
9378 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009379 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009380
9381 /* Trigger handover from BTS0 to BTS1 */
9382 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9383 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9384
9385 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
9386 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9387
9388 /* ACKnowledge channel activation and expect (RR) Handover Command */
9389 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9390 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9391
9392 /* Make sure that L3 Information IE is present */
9393 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9394 setverdict(fail, "RSL L3 Information IE is absent");
9395 return;
9396 }
9397
9398 /* Decode the L3 message and make sure it is (RR) Handover Command */
9399 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9400 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9401 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9402 return;
9403 }
9404
9405 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9406 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9407 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9408 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9409 return;
9410 }
9411
9412 /* Make sure that hopping parameters (HSN/MAIO) match */
9413 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9414
9415 /* Make sure that Cell Channel Description IE is present */
9416 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9417 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9418 return;
9419 }
9420
9421 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9422 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9423 if (ma_present) {
9424 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9425 l3_msg.payload.ho_cmd.mobile_allocation.v);
9426 } else {
9427 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9428 return;
9429 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009430
9431 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009432}
9433testcase TC_fh_params_handover_cmd() runs on test_CT {
9434 var FHParamsTrx fhp := f_TC_fh_params_gen();
9435
9436 f_init_vty();
9437
9438 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9439 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9440
9441 f_vty_transceive(BSCVTY, "timeslot 0");
9442 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9443 f_vty_transceive(BSCVTY, "exit"); /* go back */
9444
9445 f_vty_transceive(BSCVTY, "timeslot 1");
9446 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9447 f_vty_transceive(BSCVTY, "end"); /* we're done */
9448
9449 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9450 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9451
9452 f_init(2);
9453
9454 f_TC_fh_params_handover_cmd(fhp);
9455
9456 /* Disable frequency hopping on BTS1 */
9457 f_TC_fh_params_unset(fhp, 1);
9458
9459 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9460 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9461
9462 f_vty_transceive(BSCVTY, "timeslot 0");
9463 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9464 f_vty_transceive(BSCVTY, "exit"); /* go back */
9465
9466 f_vty_transceive(BSCVTY, "timeslot 1");
9467 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9468 f_vty_transceive(BSCVTY, "end"); /* we're done */
9469
9470 f_shutdown_helper();
9471}
9472
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009473/* Verify the hopping parameters in System Information Type 4 */
9474testcase TC_fh_params_si4_cbch() runs on test_CT {
9475 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9476 var ASP_RSL_Unitdata rx_rsl_ud;
9477 timer T := 5.0;
9478
9479 f_init_vty();
9480
9481 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9482 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9483
9484 f_vty_transceive(BSCVTY, "timeslot 0");
9485 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9486 f_vty_transceive(BSCVTY, "exit"); /* go back */
9487
9488 f_vty_transceive(BSCVTY, "timeslot 1");
9489 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9490 f_vty_transceive(BSCVTY, "end"); /* we're done */
9491
9492 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9493 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9494
9495 f_init(1);
9496
9497 T.start;
9498 alt {
9499 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
9500 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9501 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9502
9503 /* Make sure that what we decoded is System Information Type 4 */
9504 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9505 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9506 repeat;
9507 }
9508
9509 /* Make sure that CBCH Channel Description IE is present */
9510 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9511 setverdict(fail, "CBCH Channel Description IE is absent");
9512 break;
9513 }
9514
9515 /* Finally, check the hopping parameters (HSN, MAIO) */
9516 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9517 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9518
9519 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9520 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9521 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9522 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9523 break;
9524 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9525 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9526 si.payload.si4.cbch_mobile_alloc.v);
9527 }
9528 }
9529 [] IPA_RSL[0].receive { repeat; }
9530 [] T.timeout {
9531 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9532 }
9533 }
9534
9535 /* Disable frequency hopping */
9536 f_TC_fh_params_unset(fhp);
9537
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009538 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009539 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9540
9541 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009542 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009543 f_vty_transceive(BSCVTY, "exit"); /* go back */
9544
9545 f_vty_transceive(BSCVTY, "timeslot 1");
9546 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9547 f_vty_transceive(BSCVTY, "end"); /* we're done */
9548
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009549 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009550}
9551
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009552template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9553 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9554
9555private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9556 template (present) BSSLAP_PDU expect_bsslap)
9557{
9558 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9559 if (not match(bsslap, expect_bsslap)) {
9560 log("EXPECTING BSSLAP: ", expect_bsslap);
9561 log("GOT BSSLAP: ", bsslap);
9562 setverdict(fail, "BSSLAP is not as expected");
9563 mtc.stop;
9564 }
9565 setverdict(pass);
9566}
9567
9568/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9569const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9570
9571private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9572 var PDU_BSSAP_LE rx_bsslap;
9573 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9574 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9575}
9576
9577/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9578 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9579private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9580 f_sleep(1.0);
9581
9582 f_establish_fully(omit, omit);
9583 f_bssap_le_register_imsi(g_pars.imsi, omit);
9584
9585 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9586 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9587
9588 var PDU_BSSAP_LE plr;
9589 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9590
9591 if (not do_ta_request) {
9592 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9593 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9594 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9595 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9596 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9597 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9598 mtc.stop;
9599 }
9600 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9601 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9602 if (not match(bsslap, expect_ta_layer3)) {
9603 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9604 log("GOT BSSLAP: ", bsslap);
9605 setverdict(fail, "BSSLAP is not as expected");
9606 mtc.stop;
9607 }
9608 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9609 * has no need to request the TA from the BSC and directly responds. */
9610 } else {
9611 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9612 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9613 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9614 }
9615
9616 /* SMLC got the TA from the BSC, now responds with geo information data. */
9617 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9618 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9619 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9620
9621 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9622 f_mo_l3_transceive();
9623
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009624 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009625
9626 f_sleep(2.0);
9627 setverdict(pass);
9628}
9629
9630/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9631 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9632private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9633 f_lcs_loc_req_for_active_ms(false);
9634}
9635testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9636 var MSC_ConnHdlr vc_conn;
9637 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9638
9639 f_init(1, true);
9640 f_sleep(1.0);
9641 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9642 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009643 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009644}
9645
9646/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9647 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9648private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9649 f_lcs_loc_req_for_active_ms(true);
9650}
9651testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9652 var MSC_ConnHdlr vc_conn;
9653 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9654
9655 f_init(1, true);
9656 f_sleep(1.0);
9657 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9658 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009659 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009660}
9661
9662/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9663 * conn without an active lchan. */
9664private function f_clear_A_conn() runs on MSC_ConnHdlr
9665{
9666 var BssmapCause cause := 0;
9667 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9668 BSSAP.receive(tr_BSSMAP_ClearComplete);
9669 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9670
9671 timer no_more_bssap := 5.0;
9672 no_more_bssap.start;
9673 alt {
9674 [] no_more_bssap.timeout { break; }
9675 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9676 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9677 mtc.stop;
9678 }
9679 }
9680 setverdict(pass);
9681}
9682
9683/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9684 * for LCS, for cases where there is only an A conn without an active lchan. */
9685private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9686{
9687 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9688
9689 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9690 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9691 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9692 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9693 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9694 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9695
9696 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9697 f_clear_A_conn();
9698 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9699 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9700}
9701
9702/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9703 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9704 */
9705private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9706 f_sleep(1.0);
9707
9708 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9709 f_bssap_le_register_imsi(g_pars.imsi, omit);
9710
9711 /* Register to receive the Paging Command */
9712 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9713 g_chan_nr := new_chan_nr;
9714 f_rslem_register(0, g_chan_nr);
9715
9716 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9717 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9718 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9719 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9720
9721 var PDU_BSSAP_LE plr;
9722 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9723
9724 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9725 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9726
9727 /* OsmoBSC needs to Page */
9728 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9729 f_logp(BSCVTY, "got Paging Command");
9730
9731 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9732 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009733 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);
9734 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009735
9736 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9737
9738 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9739
9740 /* SMLC got the TA from the BSC, now responds with geo information data. */
9741 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9742 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9743
9744 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9745
9746 /* The lchan is gone, the A-interface conn was created for the LCS only.
9747 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9748 f_verify_active_A_conn_and_clear();
9749
9750 f_sleep(2.0);
9751 setverdict(pass);
9752}
9753testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9754 var MSC_ConnHdlr vc_conn;
9755 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9756
9757 f_init(1, true);
9758 f_sleep(1.0);
9759
9760 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9761 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9762
9763 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9764 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009765 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009766}
9767
9768/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9769 */
9770private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9771 f_sleep(1.0);
9772
9773 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9774 f_bssap_le_register_imsi(g_pars.imsi, omit);
9775
9776 /* provoke an abort by omitting both IMSI and IMEI */
9777 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9778 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9779 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9780 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9781
9782 /* BSC tells MSC about failure */
9783 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9784 locationEstimate := omit, positioningData := omit,
9785 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9786
9787 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9788 f_verify_active_A_conn_and_clear();
9789
9790 f_sleep(2.0);
9791 setverdict(pass);
9792}
9793testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9794 var MSC_ConnHdlr vc_conn;
9795 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9796
9797 f_init(1, true);
9798 f_sleep(1.0);
9799
9800 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9801 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9802
9803 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9804 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009805 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009806}
9807
9808/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9809 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9810private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9811 f_sleep(1.0);
9812
9813 f_establish_fully(omit, omit);
9814 f_bssap_le_register_imsi(g_pars.imsi, omit);
9815
9816 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9817 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9818
9819 var PDU_BSSAP_LE plr;
9820 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9821
9822 if (do_ta) {
9823 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9824 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9825 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9826 }
9827
9828 /* SMLC fails to respond, BSC runs into timeout */
9829 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9830 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9831
9832 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9833 locationEstimate := omit, positioningData := omit,
9834 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9835
9836 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9837 f_verify_active_A_conn_and_clear();
9838
9839 f_sleep(2.0);
9840 setverdict(pass);
9841}
9842
9843/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9844 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9845private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9846 f_lcs_loc_req_for_active_ms_le_timeout(false);
9847}
9848
9849testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9850 var MSC_ConnHdlr vc_conn;
9851 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9852
9853 f_init(1, true);
9854 f_sleep(1.0);
9855 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9856 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009857 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009858}
9859
9860/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9861 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9862private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9863 f_lcs_loc_req_for_active_ms_le_timeout(true);
9864}
9865
9866testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9867 var MSC_ConnHdlr vc_conn;
9868 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9869
9870 f_init(1, true);
9871 f_sleep(1.0);
9872 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9873 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009874 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009875}
9876
9877/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9878private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9879 f_sleep(1.0);
9880
9881 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9882 f_bssap_le_register_imsi(g_pars.imsi, omit);
9883
9884 /* Register to receive the Paging Command */
9885 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9886 g_chan_nr := new_chan_nr;
9887 f_rslem_register(0, g_chan_nr);
9888
9889 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9890 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9891 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9892 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9893
9894 var PDU_BSSAP_LE plr;
9895 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9896
9897 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9898 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9899
9900 /* OsmoBSC needs to Page */
9901 var PDU_BSSAP_LE rx_bsslap;
9902 alt {
9903 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9904 f_logp(BSCVTY, "got Paging Command");
9905 repeat;
9906 }
9907 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9908 /* MS does not respond to Paging, TA Req runs into timeout. */
9909 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9910 }
9911 }
9912
9913 /* SMLC responds with failure */
9914 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9915 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9916
9917 /* BSC tells MSC about failure */
9918 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9919 locationEstimate := omit, positioningData := omit,
9920 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9921
9922 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9923 f_verify_active_A_conn_and_clear();
9924
9925 f_sleep(2.0);
9926 setverdict(pass);
9927}
9928testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9929 var MSC_ConnHdlr vc_conn;
9930 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9931
9932 f_init(1, true);
9933 f_sleep(1.0);
9934
9935 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9936 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9937
9938 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9939 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009940 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009941}
9942
9943/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9944 * over. */
9945private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9946 f_sleep(1.0);
9947
9948 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9949 f_bssap_le_register_imsi(g_pars.imsi, omit);
9950
9951 /* Register to receive the Paging Command */
9952 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9953 g_chan_nr := new_chan_nr;
9954 f_rslem_register(0, g_chan_nr);
9955
9956 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9957 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9958 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9959 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9960
9961 var PDU_BSSAP_LE plr;
9962 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9963
9964 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9965 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009966 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 +02009967 do_clear := false, expect_bssmap_l3 := true);
9968
9969 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9970 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9971
9972 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9973 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9974
9975 /* SMLC got the TA from the BSC, now responds with geo information data. */
9976 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9977 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9978 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9979
9980 /* The lchan should still exist, it was from a CM Service Request. */
9981 f_mo_l3_transceive();
9982
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009983 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009984
9985 f_sleep(2.0);
9986 setverdict(pass);
9987}
9988testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9989 var MSC_ConnHdlr vc_conn;
9990 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9991
9992 f_init(1, true);
9993 f_sleep(1.0);
9994
9995 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9996 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9997
9998 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9999 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010000 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010001}
10002
10003/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10004 * the new lchan after handover. */
10005private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10006 f_sleep(1.0);
10007
10008 f_establish_fully(omit, omit);
10009 f_bssap_le_register_imsi(g_pars.imsi, omit);
10010
10011 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10012 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10013
10014 var PDU_BSSAP_LE plr;
10015 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10016
10017 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10018 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10019
10020 var HandoverState hs := {
10021 rr_ho_cmpl_seen := false,
10022 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010023 old_chan_nr := -,
10024 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010025 };
10026 /* issue hand-over command on VTY */
10027 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10028 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10029 f_rslem_suspend(RSL1_PROC);
10030
10031 /* From the MGW perspective, a handover is is characterized by
10032 * performing one MDCX operation with the MGW. So we expect to see
10033 * one more MDCX during handover. */
10034 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10035
10036 alt {
10037 [] as_handover(hs);
10038 }
10039
10040 var PDU_BSSAP_LE rx_bsslap;
10041
10042 interleave {
10043 /* Expect the BSC to inform the MSC about the handover */
10044 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10045
10046 /* Expect the BSC to inform the SMLC about the handover */
10047 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10048 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10049 }
10050 }
10051
10052 /* SMLC now responds with geo information data. */
10053 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10054 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10055 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10056
10057 /* lchan still active */
10058 f_mo_l3_transceive(RSL1);
10059
10060 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010061 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010062
10063 f_sleep(2.0);
10064 setverdict(pass);
10065}
10066testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10067 var MSC_ConnHdlr vc_conn;
10068 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10069
10070 f_init(2, true);
10071 f_sleep(1.0);
10072 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10073 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010074 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010075}
10076
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010077/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10078private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10079 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10080
10081 /* Also disable attach for the single connected MSC */
10082 f_vty_msc_allow_attach(BSCVTY, { false });
10083
10084 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) ));
10085 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10086
10087 /* No MSC is found, expecting a proper release on RSL */
10088 interleave {
10089 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10090 f_logp(BSCVTY, "Got RSL RR Release");
10091 }
10092 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10093 f_logp(BSCVTY, "Got RSL Deact SACCH");
10094 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010095 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010096 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10097 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010098 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010099 }
10100 }
10101 setverdict(pass);
10102}
10103testcase TC_no_msc() runs on test_CT {
10104
10105 f_init(1, true);
10106 f_sleep(1.0);
10107 var MSC_ConnHdlr vc_conn;
10108 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10109
10110 f_ctrs_bsc_init(counternames_bsc_mscpool);
10111
10112 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10113 vc_conn.done;
10114
10115 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10116 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010117 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010118}
10119
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010120/* Dyn PDCH todo:
10121 * activate OSMO as TCH/F
10122 * activate OSMO as TCH/H
10123 * does the BSC-located PCU socket get the updated INFO?
10124 * what if no PCU is connected at the time?
10125 * is the info correct on delayed PCU (re)connect?
10126 */
Harald Welte94e0c342018-04-07 11:33:23 +020010127
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010128private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
10129 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
10130 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
10131
10132 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10133 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10134 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10135 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10136 g_pars.ass_codec_list.codecElements[0];
10137 if (isvalue(g_pars.expect_mr_s0_s7)) {
10138 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10139 g_pars.expect_mr_s0_s7;
10140 }
10141 }
10142 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10143 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10144 log("expecting ASS COMPL like this: ", exp_compl);
10145
10146 f_establish_fully(ass_cmd, exp_compl);
10147
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010148 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 +000010149
10150 var RSL_Message rsl;
10151
10152 timer T := 5.0;
10153 T.start;
10154 alt {
10155 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10156 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10157 log("Rx L3 from net: ", l3);
10158 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10159 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10160 mtc.stop;
10161 }
10162 }
10163 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10164 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10165 mtc.stop;
10166 }
10167 [] T.timeout {
10168 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10169 setverdict(pass);
10170 }
10171 }
10172 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010173
10174 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010175}
10176
10177/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10178 * osmo-bsc. */
10179testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10180 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10181 var MSC_ConnHdlr vc_conn;
10182
10183 f_init(1, true);
10184 f_sleep(1.0);
10185
10186 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10187 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10188 vc_conn.done;
10189 f_shutdown_helper();
10190}
10191
10192/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10193 */
10194testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10195 f_init_vty();
10196
10197 f_init(1, false);
10198 f_sleep(1.0);
10199
10200 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10201
10202 var ASP_RSL_Unitdata rx_rsl_ud;
10203 timer T := 5.0;
10204
10205 T.start;
10206 alt {
10207 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
10208 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10209 T.stop;
10210 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10211 mtc.stop;
10212 }
10213 repeat;
10214 }
10215 [] T.timeout {
10216 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10217 setverdict(pass);
10218 }
10219 }
10220}
10221
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010222private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10223 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010224 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010225
10226 /* Trigger re-assignment to another lchan */
10227 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10228
10229 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10230 * one MDCX on MGCP. */
10231 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10232
10233 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10234 * as the old lchan used. */
10235 g_media.bts.ipa_crcx_seen := false;
10236 g_media.bts.ipa_mdcx_seen := false;
10237
10238 /* Send different BTS side RTP port number for the new lchan */
10239 g_media.bts.bts.port_nr := 4223;
10240
10241 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10242
10243 /* Trigger re-assignment. */
10244 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10245
10246 timer T := 5.0;
10247 T.start;
10248 alt {
10249 [] as_assignment(assignment_st);
10250 [] as_Media();
10251 [] T.timeout {
10252 break;
10253 }
10254 }
10255
10256 if (not assignment_st.assignment_done) {
10257 setverdict(fail, "Assignment did not complete");
10258 mtc.stop;
10259 }
10260
10261 f_check_mgcp_expectations()
10262 setverdict(pass);
10263
10264 f_sleep(2.0);
10265 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10266
10267 /* Instruct BSC to clear channel */
10268 var BssmapCause cause := 0;
10269 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10270 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010271 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10272 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010273 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010274 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010275 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010276 }
10277 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10278 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10279 }
10280 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010281 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010282
10283 f_sleep(0.5);
10284}
10285
10286testcase TC_reassignment_fr() runs on test_CT {
10287 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10288 var MSC_ConnHdlr vc_conn;
10289
10290 f_init(1, true);
10291 f_sleep(1.0);
10292
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010293 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010294
10295 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10296 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10297 vc_conn.done;
10298
10299 /* from f_establish_fully() */
10300 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10301 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10302 /* from re-assignment */
10303 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10304 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10305 f_ctrs_bsc_and_bts_verify();
10306 f_shutdown_helper();
10307}
10308
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010309const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10310const charstring REEST_CLEAR := "REEST_CLEAR";
10311const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10312
10313/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10314 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10315 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10316 * the MSC as the CM Re-Establishment is handled.
10317 *
10318 * MS bts0 bts1 bsc msc test-component
10319 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10320 * | | _1 wait a bit, to settle down
10321 * |<-x x--| | _1 "lose connection"
10322 * | | REEST_LOST_CONNECTION
10323 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10324 * | | REEST_CLEAR
10325 * | |<-0---| _1 Clear Command on first A-conn
10326 * | |--0-->| _1 Clear Complete
10327 * | |<----------------->| | _1 Release first channel
10328 * | | REEST_CLEAR_DONE
10329 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10330 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10331 *
10332 */
10333private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10334 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10335 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10336
10337 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10338 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10339
10340 f_establish_fully(ass_cmd, exp_compl);
10341
10342 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10343 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10344 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10345 f_sleep(2.0);
10346 COORD.send(REEST_LOST_CONNECTION);
10347
10348 alt {
10349 [] COORD.receive(REEST_CLEAR);
10350 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10351 setverdict(fail, "Unexpected channel release");
10352 mtc.stop;
10353 }
10354 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10355 setverdict(fail, "Unexpected channel release");
10356 mtc.stop;
10357 }
10358 }
10359 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010360 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010361 COORD.send(REEST_CLEAR_DONE);
10362}
10363
10364private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10365 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10366
10367 /* The MS lost the connection on the first channel, now establishes another one */
10368 COORD.receive(REEST_LOST_CONNECTION);
10369
10370 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10371 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10372 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10373
10374 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010375 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 +020010376 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10377
10378 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10379 COORD.send(REEST_CLEAR);
10380 COORD.receive(REEST_CLEAR_DONE);
10381
10382 f_sleep(2.0);
10383
10384 /* Answer the CM Re-Establishment with an Assignment Command. */
10385 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10386 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10387 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10388 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10389
10390 var AssignmentState st := valueof(ts_AssignmentStateInit);
10391 st.voice_call := true;
10392 st.is_assignment := true;
10393
10394 var ExpectCriteria mgcpcrit := {
10395 connid := omit,
10396 endpoint := omit,
10397 transid := omit
10398 };
10399 f_create_mgcp_expect(mgcpcrit);
10400
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010401 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010402
10403 BSSAP.send(ass_cmd);
10404
10405 var PDU_BSSAP bssap;
10406
10407 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010408 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10409 [] as_Media_ipacc(RSL1, RSL2);
10410 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010411 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10412 break;
10413 }
10414 }
10415
10416 f_sleep(3.0);
10417
10418 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010419 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010420}
10421
10422testcase TC_cm_reestablishment() runs on test_CT {
10423 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10424 var MSC_ConnHdlr vc_conn1;
10425
10426 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10427 var MSC_ConnHdlr vc_conn2;
10428 pars2.imsi := pars1.imsi;
10429 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +020010430 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010431
10432 f_init(2, true, guard_timeout := 40.0);
10433 f_sleep(1.0);
10434
10435 vc_conn1 := f_start_handler_create(pars1);
10436 vc_conn2 := f_start_handler_create(pars2);
10437 connect(vc_conn1:COORD, vc_conn2:COORD);
10438 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10439 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10440 vc_conn1.done;
10441 vc_conn2.done;
10442
10443 f_shutdown_helper();
10444}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010445
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010446function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
10447 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
10448runs on test_CT return template (omit) RSL_Message {
10449 var ASP_RSL_Unitdata rx_rsl_ud;
10450 timer T := t_secs;
10451
10452 T.start;
10453 alt {
10454 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
10455 T.stop;
10456 }
10457 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
10458 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
10459 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10460 T.stop;
10461 return omit;
10462 }
10463 [] T.timeout {
10464 return omit;
10465 }
10466 }
10467 return rx_rsl_ud.rsl;
10468}
10469
10470private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
10471 f_vty_enter_cfg_bts(pt, bts_nr);
10472 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
10473 f_vty_transceive(pt, "exit");
10474 f_vty_transceive(pt, "exit");
10475 f_vty_transceive(pt, "exit");
10476}
10477
10478private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010479 template RslChannelNr chan_nr := ?,
10480 template (present) uint12_t arfcn := ?,
10481 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010482{
10483 var RSL_IE_Body full_imm_ass_info;
10484 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10485 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10486 mtc.stop;
10487 }
10488
10489 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10490 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10491 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010492 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010493 page_mode := ?);
10494 if (not match(rr_imm_ass, expect_imm_ass)) {
10495 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10496 setverdict(fail, "Failed to match Immediate Assignment");
10497 mtc.stop;
10498 }
10499}
10500
10501testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10502 var RSL_Message chan_act;
10503 var RSL_Message imm_ass;
10504
10505 f_init(1, false);
10506 f_sleep(1.0);
10507
10508 /* (should be the default anyway, just to make things clear) */
10509 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10510
10511 /* RA containing reason=LU */
10512 var GsmFrameNumber fn := 2342;
10513 var uint8_t ra := 2;
10514 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10515
10516 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10517
10518 /* First send the Chan Act ACK */
10519 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010520 var DchanTuple dt;
10521 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010522 var RSL_IE_Body chan_ident_ie;
10523 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10524 setverdict(fail, "RSL Channel Identification IE is absent");
10525 mtc.stop;
10526 }
10527
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010528 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
10529
10530 /* Then expect the Immediate Assignment, after we ACKed the chan act */
10531 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10532
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010533 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10534 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010535
10536 /* Check that the lchan is working */
10537 var octetstring l3 := '00010203040506'O;
10538 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10539
10540 var BSSAP_N_CONNECT_ind rx_c_ind;
10541 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010542 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010543 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10544
10545 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010546 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010547 f_shutdown_helper();
10548}
10549
10550testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10551 var RSL_Message chan_act;
10552 var RSL_Message imm_ass;
10553
10554 f_init(1, false);
10555 f_sleep(1.0);
10556
10557 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10558
10559 /* RA containing reason=LU */
10560 var GsmFrameNumber fn := 2342;
10561 var uint8_t ra := 2;
10562 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10563
10564 /* (set bts 0 cfg back to default) */
10565 f_vty_set_imm_ass(BSCVTY);
10566
10567 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10568 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010569 var DchanTuple dt;
10570 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010571 var RSL_IE_Body chan_ident_ie;
10572 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10573 setverdict(fail, "RSL Channel Identification IE is absent");
10574 mtc.stop;
10575 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010576
10577 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10578 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010579 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10580 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010581
10582 /* Only now send the Chan Act ACK */
10583 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10584
10585 /* Check that the lchan is working */
10586 var octetstring l3 := '00010203040506'O;
10587 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10588
10589 var BSSAP_N_CONNECT_ind rx_c_ind;
10590 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010591 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010592 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10593
10594 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010595 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010596 f_shutdown_helper();
10597}
10598
Neels Hofmeyr23158742021-09-07 19:08:07 +020010599testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10600 var RSL_Message chan_act;
10601 var RSL_Message imm_ass;
10602
10603 f_init(1, false);
10604 f_sleep(1.0);
10605
10606 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10607
10608 /* RA containing reason=LU */
10609 var GsmFrameNumber fn := 2342;
10610 var uint8_t ra := 2;
10611 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10612
10613 /* (set bts 0 cfg back to default) */
10614 f_vty_set_imm_ass(BSCVTY);
10615
10616 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10617 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010618 var DchanTuple dt;
10619 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010620 var RSL_IE_Body chan_ident_ie;
10621 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10622 setverdict(fail, "RSL Channel Identification IE is absent");
10623 mtc.stop;
10624 }
10625
10626 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10627 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10628 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10629 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10630
10631 /* Only now send the Chan Act ACK */
10632 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10633
10634 /* Check that the lchan is working */
10635 var octetstring l3 := '00010203040506'O;
10636 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10637
10638 var BSSAP_N_CONNECT_ind rx_c_ind;
10639 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010640 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010641 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10642
10643 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010644 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020010645 f_shutdown_helper();
10646}
10647
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010648testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10649 /* change Timeslot 6 before f_init() starts RSL */
10650 f_init_vty();
10651 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10652 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10653
10654 f_init(1, false);
10655 f_sleep(1.0);
10656
10657 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10658 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010659 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010660 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10661
10662 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10663 f_ts_set_chcomb(0, 0, 6, "PDCH");
10664
10665 /* block all static timeslots so that the dyn TS will be used */
10666 f_disable_all_tch_f();
10667 f_disable_all_tch_h();
10668 f_disable_all_sdcch();
10669
10670 var RSL_Message chan_act;
10671 var RSL_Message imm_ass;
10672
10673 f_init(1, false);
10674 f_sleep(1.0);
10675
10676 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10677
10678 /* RA containing reason=LU */
10679 var GsmFrameNumber fn := 2342;
10680 var uint8_t ra := 2;
10681 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10682
10683 /* (set bts 0 cfg back to default) */
10684 f_vty_set_imm_ass(BSCVTY);
10685
10686 /* Expect the dyn TS to deactivate PDCH first */
10687 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10688 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10689
10690 /* Now activation as SDCCH8 */
10691 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010692 var DchanTuple dt;
10693 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010694
10695 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010696 var RSL_IE_Body chan_ident_ie;
10697 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10698 setverdict(fail, "RSL Channel Identification IE is absent");
10699 mtc.stop;
10700 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010701
10702 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10703 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010704 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10705 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010706
10707 /* Only now send the Chan Act ACK */
10708 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10709
10710 /* Check that the lchan is working */
10711 var octetstring l3 := '00010203040506'O;
10712 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10713
10714 var BSSAP_N_CONNECT_ind rx_c_ind;
10715 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010716 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010717 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10718
10719 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010720 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010721 f_shutdown_helper();
10722}
10723
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010724testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10725 /* change Timeslot 6 before f_init() starts RSL */
10726 f_init_vty();
10727 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10728 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10729
10730 f_init(1, false);
10731 f_sleep(1.0);
10732
10733 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10734 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010735 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010736 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10737
10738 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10739 f_ts_set_chcomb(0, 0, 6, "PDCH");
10740
10741 /* block all static timeslots so that the dyn TS will be used */
10742 f_disable_all_tch_f();
10743 f_disable_all_tch_h();
10744 f_disable_all_sdcch();
10745
10746 var RSL_Message chan_act;
10747 var RSL_Message imm_ass;
10748
10749 f_init(1, false);
10750 f_sleep(1.0);
10751
10752 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10753
10754 /* RA containing reason=LU */
10755 var GsmFrameNumber fn := 2342;
10756 var uint8_t ra := 2;
10757 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10758
10759 /* (set bts 0 cfg back to default) */
10760 f_vty_set_imm_ass(BSCVTY);
10761
10762 /* Expect the dyn TS to deactivate PDCH first */
10763 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10764
10765 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10766 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10767
10768 /* continue the Osmo style PDCH Deact (usual chan rel) */
10769 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10770
10771 /* Now activation as SDCCH8 */
10772 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010773 var DchanTuple dt;
10774 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010775
10776 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010777 var RSL_IE_Body chan_ident_ie;
10778 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10779 setverdict(fail, "RSL Channel Identification IE is absent");
10780 mtc.stop;
10781 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010782 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10783
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010784 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10785 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010786
10787 /* Check that the lchan is working */
10788 var octetstring l3 := '00010203040506'O;
10789 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10790
10791 var BSSAP_N_CONNECT_ind rx_c_ind;
10792 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010793 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010794 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10795
10796 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010797 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010798 f_shutdown_helper();
10799}
10800
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010801/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10802testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10803 var MSC_ConnHdlr vc_conn;
10804
10805 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10806 f_sleep(1.0);
10807
10808 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10809 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10810 "0,0,operational,unlocked,on,rsl-up;" &
10811 "1,0,operational,unlocked,on,rsl-up;" &
10812 "2,0,operational,unlocked,on,rsl-down;" &
10813 "3,0,inoperational,locked,on,rsl-down;");
10814
10815 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10816 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10817 /* give it a moment to settle the FSM status */
10818 f_sleep(1.0);
10819
10820 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10821 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10822 * of "off"? But that's for a future patch if at all. */
10823 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10824 "0,0,operational,unlocked,on,rsl-up;" &
10825 "1,0,operational,locked,on,rsl-up;" &
10826 "2,0,operational,unlocked,on,rsl-down;" &
10827 "3,0,inoperational,locked,on,rsl-down;");
10828
10829 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10830 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10831 f_sleep(1.0);
10832 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10833 "0,0,operational,unlocked,on,rsl-up;" &
10834 "1,0,operational,locked,on,rsl-up;" &
10835 "2,0,operational,unlocked,on,rsl-down;" &
10836 "3,0,inoperational,locked,on,rsl-down;");
10837
10838 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10839 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10840 f_sleep(1.0);
10841 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10842 "0,0,operational,unlocked,on,rsl-up;" &
10843 "1,0,operational,unlocked,on,rsl-up;" &
10844 "2,0,operational,unlocked,on,rsl-down;" &
10845 "3,0,inoperational,locked,on,rsl-down;");
10846
10847 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10848 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10849 f_sleep(1.0);
10850 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10851 "0,0,operational,unlocked,on,rsl-up;" &
10852 "1,0,operational,unlocked,on,rsl-up;" &
10853 "2,0,operational,unlocked,on,rsl-down;" &
10854 "3,0,inoperational,locked,on,rsl-down;");
10855
10856 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10857 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10858 f_sleep(1.0);
10859 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10860 "0,0,operational,unlocked,on,rsl-up;" &
10861 "1,0,operational,unlocked,on,rsl-up;" &
10862 "2,0,operational,unlocked,on,rsl-down;" &
10863 "3,0,inoperational,locked,on,rsl-down;");
10864
10865 f_shutdown_helper();
10866}
10867
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010868const CounterNameVals counternames_cm_serv_rej := {
10869 { "cm_serv_rej", 0 },
10870 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
10871 { "cm_serv_rej:illegal_ms", 0 },
10872 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
10873 { "cm_serv_rej:imei_not_accepted", 0 },
10874 { "cm_serv_rej:illegal_me", 0 },
10875 { "cm_serv_rej:plmn_not_allowed", 0 },
10876 { "cm_serv_rej:loc_not_allowed", 0 },
10877 { "cm_serv_rej:roaming_not_allowed", 0 },
10878 { "cm_serv_rej:network_failure", 0 },
10879 { "cm_serv_rej:synch_failure", 0 },
10880 { "cm_serv_rej:congestion", 0 },
10881 { "cm_serv_rej:srv_opt_not_supported", 0 },
10882 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
10883 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
10884 { "cm_serv_rej:call_can_not_be_identified", 0 },
10885 { "cm_serv_rej:incorrect_message", 0 },
10886 { "cm_serv_rej:invalid_mandantory_inf", 0 },
10887 { "cm_serv_rej:msg_type_not_implemented", 0 },
10888 { "cm_serv_rej:msg_type_not_compatible", 0 },
10889 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
10890 { "cm_serv_rej:condtional_ie_error", 0 },
10891 { "cm_serv_rej:msg_not_compatible", 0 },
10892 { "cm_serv_rej:protocol_error", 0 },
10893 { "cm_serv_rej:retry_in_new_cell", 0 }
10894};
10895
10896private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
10897{
10898 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030010899 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010900 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010901 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
10902 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010903 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010904}
10905testcase TC_cm_serv_rej() runs on test_CT {
10906 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10907 var MSC_ConnHdlr vc_conn;
10908
10909 f_init(1, true);
10910 f_sleep(1.0);
10911
10912 f_ctrs_bts_init(1, counternames_cm_serv_rej);
10913
10914 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
10915 vc_conn.done;
10916
10917 f_ctrs_bts_add(0, "cm_serv_rej", 1);
10918 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
10919 f_ctrs_bts_verify();
10920
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010921 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010922 f_shutdown_helper();
10923}
10924
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010925/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10926 * Activ Ack (SYS#5627). */
10927private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10928 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030010929
10930 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10931 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010932
10933 var BSSMAP_FIELD_CodecType codecType;
10934 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
10935
10936 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
10937
10938 /* First establish a signalling lchan */
10939 f_create_chan_and_exp();
10940 f_rslem_dchan_queue_enable();
10941
10942 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010943
10944 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
10945 activate(as_Media_mgw());
10946
10947 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
10948 f_rslem_register(0, chan_nr);
10949
10950 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
10951 BSSAP.send(ass_cmd);
10952
10953
10954 /* Wait for the Channel Activ for the TCH channel */
10955 var ASP_RSL_Unitdata rx_rsl_ud;
10956 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
10957
10958 /* make the original SDCCH disappear */
10959 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10960
10961 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
10962 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
10963
10964 interleave {
10965 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
10966 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
10967 }
10968
10969 BSSAP.send(ts_BSSMAP_ClearCommand(0));
10970 BSSAP.receive(tr_BSSMAP_ClearComplete);
10971 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10972
10973 var MgcpCommand mgcp;
10974 MGCP.receive(tr_DLCX()) -> value mgcp {
10975 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
10976 };
10977
10978 f_sleep(0.5);
10979}
10980testcase TC_lost_sdcch_during_assignment() runs on test_CT {
10981 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10982 var MSC_ConnHdlr vc_conn;
10983
10984 f_init(1, true);
10985 f_sleep(1.0);
10986
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010987 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
10988 vc_conn.done;
10989
10990 f_shutdown_helper();
10991}
10992
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010993const CounterNameVals counternames_bsc_bts_all_available_allocated := {
10994 { "all_allocated:sdcch", 0 },
10995 { "all_allocated:static_sdcch", 0 },
10996 { "all_allocated:tch", 0 },
10997 { "all_allocated:static_tch", 0 }
10998}
10999
11000private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11001{
11002 /* Make sure counters settle first */
11003 f_sleep(1.0);
11004
11005 /* Take a baseline of counters */
11006 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11007
11008 /* Elapse some time so that we see changes in counters, hopefully where expected */
11009 f_sleep(2.0);
11010
11011 /* Get new counters */
11012 var charstring_list all_changed := {};
11013 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11014 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11015
11016 /* Compare with expectations */
11017 var charstring_list all_expect_changed := {};
11018 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11019 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11020 }
11021 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11022}
11023
11024testcase TC_ratectr_all_available_allocated() runs on test_CT {
11025 var ASP_RSL_Unitdata rsl_ud;
11026 var integer i;
11027 var integer chreq_total, chreq_nochan;
11028
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011029 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011030 f_sleep(1.0);
11031
11032 /* Exhaust all dedicated SDCCH lchans.
11033 /* GSM 44.018 Table 9.1.8.2:
11034 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11035 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011036 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011037 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011038 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011039 }
11040
11041 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11042 * level.
11043 * All SDCCH are now occupied. */
11044 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11045
11046 /* Also fill up all remaining (TCH) channels */
11047 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011048 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011049 }
11050
11051 /* All TCH are now also occupied */
11052 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11053 "all_allocated:tch", "all_allocated:static_tch"});
11054
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011055 /* Clean up SDCCH lchans */
11056 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11057 f_perform_clear_test_ct(chan_cleanup[i]);
11058 }
11059
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011060 f_shutdown_helper();
11061}
11062
11063testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11064 var ASP_RSL_Unitdata rsl_ud;
11065 var integer i;
11066 var integer chreq_total, chreq_nochan;
11067
11068 f_init_vty();
11069 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11070 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11071 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11072
11073 f_init(1, guard_timeout := 60.0);
11074 f_sleep(1.0);
11075
11076 /* The dyn TS wants to activate PDCH mode, ACK that. */
11077 var RslChannelNr chan_nr;
11078 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011079 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011080 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11081
11082 /* Exhaust all dedicated SDCCH lchans.
11083 /* GSM 44.018 Table 9.1.8.2:
11084 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11085 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011086 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011087 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011088 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011089 }
11090
11091 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11092 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11093 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11094
11095 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11096 * Will release them later, so remember all the DchanTuples. */
11097 var DchanTuples dyn_sddch := {};
11098 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11099
11100 /* Also occupy the seven other SDCCH of the dyn TS */
11101 for (i := 0; i < 7; i := i+1) {
11102 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11103 }
11104
11105 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11106 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11107
11108 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11109 for (i := 0; i < 5; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011110 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011111 }
11112
11113 /* All TCH lchans are now also occupied, both static and dynamic */
11114 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11115 "all_allocated:tch", "all_allocated:static_tch"});
11116
11117 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11118 * incrementing. */
11119 var BssmapCause cause := 0;
11120 var DchanTuple dt := dyn_sddch[0];
11121 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11122 f_exp_chan_rel_and_clear(dt, 0);
11123
11124 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11125 * count as occupied, so those still both increment. */
11126 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11127 "all_allocated:tch", "all_allocated:static_tch"});
11128
11129 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11130 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11131 dt := dyn_sddch[i];
11132 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11133 f_exp_chan_rel_and_clear(dt, 0);
11134 }
11135
11136 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11137 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011138 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011139 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11140
11141 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11142 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11143
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011144 /* Clean up SDCCH lchans */
11145 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11146 f_perform_clear_test_ct(chan_cleanup[i]);
11147 }
11148
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011149 /* clean up config */
11150 f_ts_reset_chcomb(0);
11151
11152 f_shutdown_helper();
11153}
11154
Harald Welte28d943e2017-11-25 15:00:50 +010011155control {
Harald Welte898113b2018-01-31 18:32:21 +010011156 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010011157 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010011158 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020011159 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
11160 * these in the AoIP test suite. */
11161 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11162 execute( TC_stat_num_msc_connected_1() );
11163 execute( TC_stat_num_msc_connected_2() );
11164 execute( TC_stat_num_msc_connected_3() );
11165 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020011166 execute( TC_stat_num_bts_connected_1() );
11167 execute( TC_stat_num_bts_connected_2() );
11168 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010011169 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011170 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020011171 execute( TC_ctrl_location() );
11172 }
Harald Welte898113b2018-01-31 18:32:21 +010011173
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011174 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020011175 execute( TC_si2quater_2_earfcns() );
11176 execute( TC_si2quater_3_earfcns() );
11177 execute( TC_si2quater_4_earfcns() );
11178 execute( TC_si2quater_5_earfcns() );
11179 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020011180 execute( TC_si2quater_12_earfcns() );
11181 execute( TC_si2quater_23_earfcns() );
11182 execute( TC_si2quater_32_earfcns() );
11183 execute( TC_si2quater_33_earfcns() );
11184 execute( TC_si2quater_42_earfcns() );
11185 execute( TC_si2quater_48_earfcns() );
11186 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020011187 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020011188 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011189
Harald Welte898113b2018-01-31 18:32:21 +010011190 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010011191 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010011192 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010011193 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020011194 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020011195 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010011196 execute( TC_chan_act_ack_est_ind_noreply() );
11197 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010011198 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010011199 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070011200 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010011201 execute( TC_chan_rel_rll_rel_ind() );
11202 execute( TC_chan_rel_conn_fail() );
11203 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020011204 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
11205 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010011206 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010011207 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020011208 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010011209 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010011210 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020011211 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010011212
Harald Weltecfe2c962017-12-15 12:09:32 +010011213 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010011214
11215 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010011216 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010011217 execute( TC_assignment_csd() );
11218 execute( TC_assignment_ctm() );
11219 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011220 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11221 execute( TC_assignment_aoip_tla_v6() );
11222 }
Harald Welte235ebf12017-12-15 14:18:16 +010011223 execute( TC_assignment_fr_a5_0() );
11224 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011225 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020011226 execute( TC_assignment_fr_a5_1_codec_missing() );
11227 }
Harald Welte235ebf12017-12-15 14:18:16 +010011228 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020011229 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020011230 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020011231 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011232 execute( TC_ciph_mode_a5_0() );
11233 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020011234 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020011235 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011236 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020011237 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010011238
Harald Welte60aa5762018-03-21 19:33:13 +010011239 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020011240 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010011241 execute( TC_assignment_codec_hr() );
11242 execute( TC_assignment_codec_efr() );
11243 execute( TC_assignment_codec_amr_f() );
11244 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011245
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011246 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010011247 execute( TC_assignment_codec_amr_f_S1() );
11248 execute( TC_assignment_codec_amr_h_S1() );
11249 execute( TC_assignment_codec_amr_f_S124() );
11250 execute( TC_assignment_codec_amr_h_S124() );
11251 execute( TC_assignment_codec_amr_f_S0() );
11252 execute( TC_assignment_codec_amr_f_S02() );
11253 execute( TC_assignment_codec_amr_f_S024() );
11254 execute( TC_assignment_codec_amr_f_S0247() );
11255 execute( TC_assignment_codec_amr_h_S0() );
11256 execute( TC_assignment_codec_amr_h_S02() );
11257 execute( TC_assignment_codec_amr_h_S024() );
11258 execute( TC_assignment_codec_amr_h_S0247() );
11259 execute( TC_assignment_codec_amr_f_S01234567() );
11260 execute( TC_assignment_codec_amr_f_S0234567() );
11261 execute( TC_assignment_codec_amr_f_zero() );
11262 execute( TC_assignment_codec_amr_f_unsupp() );
11263 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000011264 execute( TC_assignment_codec_amr_f_start_mode_auto() );
11265 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000011266 execute( TC_assignment_codec_amr_f_start_mode_4() );
11267 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000011268 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011269 }
Harald Welte60aa5762018-03-21 19:33:13 +010011270
Philipp Maierac09bfc2019-01-08 13:41:39 +010011271 execute( TC_assignment_codec_fr_exhausted_req_hr() );
11272 execute( TC_assignment_codec_fr_exhausted_req_fr() );
11273 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
11274 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
11275 execute( TC_assignment_codec_hr_exhausted_req_fr() );
11276 execute( TC_assignment_codec_hr_exhausted_req_hr() );
11277 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
11278 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
11279 execute( TC_assignment_codec_req_hr_fr() );
11280 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020011281 execute( TC_assignment_sdcch_exhausted_req_signalling() );
11282 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
11283 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010011284
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020011285 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020011286
Harald Welte898113b2018-01-31 18:32:21 +010011287 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010011288 execute( TC_rll_est_ind_inact_lchan() );
11289 execute( TC_rll_est_ind_inval_sapi1() );
11290 execute( TC_rll_est_ind_inval_sapi3() );
11291 execute( TC_rll_est_ind_inval_sacch() );
11292
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070011293 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
11294 execute( TC_tch_dlci_link_id_sapi() );
11295
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011296 /* SAPI N Reject triggered by RLL establishment failures */
11297 execute( TC_rll_rel_ind_sapi_n_reject() );
11298 execute( TC_rll_err_ind_sapi_n_reject() );
11299 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070011300 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011301
Harald Welte898113b2018-01-31 18:32:21 +010011302 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010011303 execute( TC_paging_imsi_nochan() );
11304 execute( TC_paging_tmsi_nochan() );
11305 execute( TC_paging_tmsi_any() );
11306 execute( TC_paging_tmsi_sdcch() );
11307 execute( TC_paging_tmsi_tch_f() );
11308 execute( TC_paging_tmsi_tch_hf() );
11309 execute( TC_paging_imsi_nochan_cgi() );
11310 execute( TC_paging_imsi_nochan_lac_ci() );
11311 execute( TC_paging_imsi_nochan_ci() );
11312 execute( TC_paging_imsi_nochan_lai() );
11313 execute( TC_paging_imsi_nochan_lac() );
11314 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010011315 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
11316 execute( TC_paging_imsi_nochan_rnc() );
11317 execute( TC_paging_imsi_nochan_lac_rnc() );
11318 execute( TC_paging_imsi_nochan_lacs() );
11319 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010011320 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010011321 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010011322 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010011323 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010011324 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010011325
11326 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010011327 execute( TC_rsl_unknown_unit_id() );
11328
11329 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011330
11331 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020011332 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011333 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010011334 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010011335 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010011336 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010011337 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011338
Harald Welte261af4b2018-02-12 21:20:39 +010011339 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020011340 execute( TC_ho_int_a5_0() );
11341 execute( TC_ho_int_a5_1() );
11342 execute( TC_ho_int_a5_3() );
11343 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000011344 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011345
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011346 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020011347 execute( TC_ho_out_fail_no_msc_response() );
11348 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020011349 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011350
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011351 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020011352 execute( TC_ho_into_this_bsc_a5_0() );
11353 execute( TC_ho_into_this_bsc_a5_1() );
11354 execute( TC_ho_into_this_bsc_a5_3() );
11355 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010011356 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
11357 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010011358 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011359 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11360 execute( TC_ho_into_this_bsc_tla_v6() );
11361 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020011362 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010011363 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020011364 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020011365 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
11366 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011367 execute( TC_ho_in_fail_msc_clears() );
11368 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
11369 execute( TC_ho_in_fail_no_detect() );
11370 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010011371 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011372
Neels Hofmeyr91401012019-07-11 00:42:35 +020011373 execute( TC_ho_neighbor_config_1() );
11374 execute( TC_ho_neighbor_config_2() );
11375 execute( TC_ho_neighbor_config_3() );
11376 execute( TC_ho_neighbor_config_4() );
11377 execute( TC_ho_neighbor_config_5() );
11378 execute( TC_ho_neighbor_config_6() );
11379 execute( TC_ho_neighbor_config_7() );
11380
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011381 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010011382 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010011383 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020011384
11385 execute( TC_dyn_pdch_ipa_act_deact() );
11386 execute( TC_dyn_pdch_ipa_act_nack() );
11387 execute( TC_dyn_pdch_osmo_act_deact() );
11388 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010011389 execute( TC_dyn_ts_sdcch8_act_deact() );
11390 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
11391 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
11392 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011393
Stefan Sperling0796a822018-10-05 13:01:39 +020011394 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020011395 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020011396
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010011397 /* Power control related */
11398 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020011399 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020011400
11401 /* MSC pooling */
11402 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
11403 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
11404 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
11405 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
11406 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11407 execute( TC_mscpool_L3Compl_on_1_msc() );
11408 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
11409 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
11410 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
11411 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
11412 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
11413 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
11414 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
11415 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
11416 execute( TC_mscpool_paging_and_response_imsi() );
11417 execute( TC_mscpool_paging_and_response_tmsi() );
11418 execute( TC_mscpool_no_allow_attach_round_robin() );
11419 execute( TC_mscpool_no_allow_attach_valid_nri() );
11420 }
11421
Harald Welte99f3ca02018-06-14 13:40:29 +020011422 execute( TC_early_conn_fail() );
11423 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020011424 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011425
Philipp Maier783681c2020-07-16 16:47:06 +020011426 /* Emergency call handling (deny / allow) */
11427 execute( TC_assignment_emerg_setup_allow() );
11428 execute( TC_assignment_emerg_setup_deny_msc() );
11429 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020011430 execute( TC_emerg_premption() );
11431
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070011432 /* Frequency hopping parameters handling */
11433 execute( TC_fh_params_chan_activ() );
11434 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070011435 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070011436 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070011437 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020011438
11439 if (mp_enable_lcs_tests) {
11440 execute( TC_lcs_loc_req_for_active_ms() );
11441 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
11442 execute( TC_lcs_loc_req_for_idle_ms() );
11443 execute( TC_lcs_loc_req_no_subscriber() );
11444 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
11445 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
11446 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
11447 execute( TC_cm_service_during_lcs_loc_req() );
11448 execute( TC_ho_during_lcs_loc_req() );
11449 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000011450
11451 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011452
11453 execute( TC_refuse_chan_act_to_vamos() );
11454 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011455
11456 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011457
11458 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011459
11460 execute( TC_imm_ass_post_chan_ack() );
11461 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020011462 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011463 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011464 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011465
11466 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011467
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011468 execute( TC_ratectr_all_available_allocated() );
11469 execute( TC_ratectr_all_available_allocated_dyn() );
11470
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011471 execute( TC_cm_serv_rej() );
11472
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011473 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011474
11475 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
11476 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
11477 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010011478}
11479
11480}