blob: 5f742b2e82aabc7e21f28bde2fca3c100cf9a3c9 [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;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100598
Daniel Willmann191e0d92018-01-17 12:44:35 +0100599 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100600 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100601
Daniel Willmannebdecc02020-08-12 15:30:17 +0200602 /* StatsD */
603 var StatsD_Checker_CT vc_STATSD;
604
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200605 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200606 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100607 /* for old legacy-tests only */
608 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200609 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100610
Harald Welte21b46bd2017-12-17 19:46:32 +0100611 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100612 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100613
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200614 /* Osmux is enabled through VTY */
615 var boolean g_osmux_enabled := false;
616
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100617 /*Configure T(tias) over VTY, seconds */
618 var integer g_bsc_sccp_timer_ias := 7 * 60;
619 /*Configure T(tiar) over VTY, seconds */
620 var integer g_bsc_sccp_timer_iar := 15 * 60;
621
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200622 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100623 timer T_guard := 30.0;
624
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200625 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000626 var CounterNameValsList g_ctr_bsc;
627 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200628
629 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
630 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100631}
632
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200633type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100634modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100635 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100636 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100637 /* port number to which to establish the IPA OML connections */
638 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100639 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100640 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100641 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100642 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200643 /* port number to which to listen for STATSD metrics */
644 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100645 /* IP address at which the test binds */
646 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100647
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200648 RAN_Configurations mp_bssap_cfg := {
649 {
650 transport := BSSAP_TRANSPORT_AoIP,
651 sccp_service_type := "mtp3_itu",
652 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
653 own_pc := 185, /* 0.23.1 first MSC emulation */
654 own_ssn := 254,
655 peer_pc := 187, /* 0.23.3 osmo-bsc */
656 peer_ssn := 254,
657 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200658 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200659 },
660 {
661 transport := BSSAP_TRANSPORT_AoIP,
662 sccp_service_type := "mtp3_itu",
663 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
664 own_pc := 2, /* 0.0.2 second MSC emulation */
665 own_ssn := 254,
666 peer_pc := 187, /* 0.23.3 osmo-bsc */
667 peer_ssn := 254,
668 sio := '83'O,
669 rctx := 2
670 },
671 {
672 transport := BSSAP_TRANSPORT_AoIP,
673 sccp_service_type := "mtp3_itu",
674 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
675 own_pc := 3, /* 0.0.3 third MSC emulation */
676 own_ssn := 254,
677 peer_pc := 187, /* 0.23.3 osmo-bsc */
678 peer_ssn := 254,
679 sio := '83'O,
680 rctx := 3
681 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100682 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200683
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200684 /* Must match per BTS config in osmo-bsc.cfg */
685 phys_chan_configs phys_chan_config := {
686 "CCCH+SDCCH4+CBCH",
687 "TCH/F",
688 "TCH/F",
689 "TCH/F",
690 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600691 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200692 "PDCH",
693 "PDCH"
694 };
695
Harald Welte47cd0e32020-08-21 12:39:11 +0200696 BSSAP_LE_Configuration mp_bssap_le_cfg := {
697 sccp_service_type := "mtp3_itu",
698 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200699 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200700 own_ssn := 252, /* SMLC side SSN */
701 peer_pc := 187, /* 0.23.3 osmo-bsc */
702 peer_ssn := 250, /* BSC side SSN */
703 sio := '83'O,
704 rctx := 6
705 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200706 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200707
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100708 /* Value set in osmo-bsc.cfg "ms max power" */
709 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100710}
711
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200712friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200713
714 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200715 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200716 pars.aoip := true;
717 } else {
718 pars.aoip := false;
719 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100720 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200721 pars.mscpool.bssap_idx := bssap_idx;
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200722 pars.expect_tsc := BTS_TSC[0];
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200723
Philipp Maier48604732018-10-09 15:00:37 +0200724 return pars;
725}
726
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200727/* Convenience functions for rate counters using g_ctr_msc. */
728
729private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
730 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
731 log("initial msc rate counters: ", g_ctr_msc);
732}
733
734private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200735 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200736}
737
738/* f_ctrs_msc_init();
739 * f_do_thing(on_msc := 0);
740 * f_do_thing(on_msc := 0);
741 * f_do_other(on_msc := 1);
742 * f_ctrs_msc_add(0, "thing", 2);
743 * f_ctrs_msc_add(1, "other");
744 * f_ctrs_msc_verify();
745 */
746private function f_ctrs_msc_verify() runs on test_CT {
747 log("verifying msc rate counters: ", g_ctr_msc);
748 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
749}
750
751/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
752 * f_ctrs_msc_init();
753 * f_do_thing(on_msc := 0);
754 * f_do_thing(on_msc := 0);
755 * f_do_thing(on_msc := 0);
756 * f_ctrs_msc_expect(0, "thing", 3);
757 */
758private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
759 f_ctrs_msc_add(msc_nr, countername, val);
760 f_ctrs_msc_verify();
761}
762
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000763/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
764
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100765private 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 +0000766 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100767 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100768}
769
770function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
771 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000772 f_ctrs_bsc_init(counternames);
773}
774
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100775private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
776 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100777 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100778 f_ctrs_bsc_init(counternames_bsc_bts_handover);
779}
780
781private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000782 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100783}
784
785private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
786 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000787 f_ctrs_bsc_add(countername, val);
788}
789
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100790function f_ctrs_bts_verify() runs on test_CT {
791 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
792}
793
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000794/* f_ctrs_bsc_and_bts_init();
795 * f_do_thing(on_bts := 0);
796 * f_do_thing(on_bts := 0);
797 * f_do_other(on_bts := 1);
798 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
799 * f_ctrs_bsc_and_bts_add(1, "other");
800 * f_ctrs_bsc_and_bts_verify();
801 */
802private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100803 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000804 f_ctrs_bsc_verify();
805}
806
807/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
808 * f_ctrs_bsc_and_bts_init();
809 * f_do_thing(on_bts := 0);
810 * f_do_thing(on_bts := 0);
811 * f_do_thing(on_bts := 0);
812 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
813 */
814private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
815 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
816 f_ctrs_bsc_and_bts_verify();
817}
818
819
820/* Convenience functions for rate counters using g_ctr_bsc. */
821
822private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
823 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
824 log("initial bsc rate counters: ", g_ctr_bsc);
825}
826
827private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
828 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
829}
830
831/* f_ctrs_bsc_init();
832 * f_do_thing();
833 * f_do_thing();
834 * f_do_other();
835 * f_ctrs_bsc_add("thing", 2);
836 * f_ctrs_bsc_add("other");
837 * f_ctrs_bsc_verify();
838 */
839private function f_ctrs_bsc_verify() runs on test_CT {
840 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
841}
842
843/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
844 * f_ctrs_bsc_init();
845 * f_do_thing();
846 * f_ctrs_bsc_expect("thing", 1);
847 */
848private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
849 f_ctrs_bsc_add(countername, val);
850 f_ctrs_bsc_verify();
851}
852
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200853
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200854friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200855 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100856 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200857 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100858}
859
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200860private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100861 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200862 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100863 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200864 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
865 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100866 T.start;
867 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200868 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
869 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200870 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100871 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200872 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200873 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100874 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200875 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200876 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100877 repeat;
878 }
879 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200880 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200881 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200882 /* If we received a RESET after ours was sent, it
883 may be a race condition where the other peer beacame
884 available after we sent it, but we are in a desired
885 state anyway, so go forward. */
886 if (not reset_received) {
887 setverdict(fail);
888 }
889 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100890 }
Harald Welte28d943e2017-11-25 15:00:50 +0100891}
892
Harald Welteae026692017-12-09 01:03:01 +0100893type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100894 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100895 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100896 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100897 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100898 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100899 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100900 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100901 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100902}
903
Harald Welte21b46bd2017-12-17 19:46:32 +0100904/*! Start the IPA/RSL related bits for one IPA_Client.
905 * \param clnt IPA_Client for which to establish
906 * \param bsc_host IP address / hostname of the BSC
907 * \param bsc_port TCP port number of the BSC
908 * \param i number identifying this BTS
909 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100910function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
911 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100912runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100913 timer T := 10.0;
914
Harald Welte96c94412017-12-09 03:12:45 +0100915 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100916 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
917 clnt.ccm_pars := c_IPA_default_ccm_pars;
918 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
919 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100920 if (handler_mode) {
921 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100922 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100923 }
Harald Welteae026692017-12-09 01:03:01 +0100924
925 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100926 if (handler_mode) {
927 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
928 } else {
929 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
930 }
Harald Welteae026692017-12-09 01:03:01 +0100931
Harald Welte5d1a2202017-12-13 19:51:29 +0100932 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100933 if (handler_mode) {
934 clnt.vc_RSL.start(RSL_Emulation.main());
935 return;
936 }
Harald Welteae026692017-12-09 01:03:01 +0100937
938 /* wait for IPA RSL link to connect and send ID ACK */
939 T.start;
940 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700941 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100942 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700943 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100944 }
Harald Welte60e823a2017-12-10 14:10:59 +0100945 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100946 [] IPA_RSL[i].receive { repeat }
947 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100948 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200949 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100950 }
951 }
952}
953
Harald Welte12055472018-03-17 20:10:08 +0100954function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
955 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
956 return;
957 }
958 clnt.vc_IPA.stop;
959 if (isbound(clnt.vc_RSL)) {
960 clnt.vc_RSL.stop;
961 }
962}
963
Harald Welte21b46bd2017-12-17 19:46:32 +0100964/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100965function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
966 timer T := secs_max;
967 T.start;
968 while (true) {
969 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
970 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100971 /* the 'degraded' state exists from OML connection time, and we have to wait
972 * until all MO's are initialized */
973 T.start(1.0);
974 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100975 return;
976 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100977 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100978 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100979 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200980 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100981 }
982 }
983}
984
Harald Welte21b46bd2017-12-17 19:46:32 +0100985/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100986altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100987 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100988 [] T_guard.timeout {
989 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200990 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100991 }
Harald Welte60e823a2017-12-10 14:10:59 +0100992 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200993 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100994 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200995 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100996 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100997 }
Harald Welte28d943e2017-11-25 15:00:50 +0100998}
999
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001000altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001001 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001002 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001003 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001004 }
1005}
1006
Daniel Willmann191e0d92018-01-17 12:44:35 +01001007function f_init_mgcp(charstring id) runs on test_CT {
1008 id := id & "-MGCP";
1009
1010 var MGCPOps ops := {
1011 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1012 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1013 };
1014 var MGCP_conn_parameters mgcp_pars := {
1015 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001016 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001017 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001018 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001019 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1020 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001021 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001022 };
1023
1024 vc_MGCP := MGCP_Emulation_CT.create(id);
1025 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1026}
1027
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001028/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1029 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1030 * OsmuxCID IE.
1031 */
1032private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1033 f_vty_enter_cfg_msc(BSCVTY, 0);
1034 if (allow) {
1035 f_vty_transceive(BSCVTY, "osmux on");
1036 } else {
1037 f_vty_transceive(BSCVTY, "osmux off");
1038 }
1039 f_vty_transceive(BSCVTY, "exit");
1040 f_vty_transceive(BSCVTY, "exit");
1041 g_osmux_enabled := allow;
1042}
1043
Max2253c0b2018-11-06 19:28:05 +01001044function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001045 if (BSCVTY.checkstate("Mapped")) {
1046 /* skip initialization if already executed once */
1047 return;
1048 }
Harald Weltebc03c762018-02-12 18:09:38 +01001049 map(self:BSCVTY, system:BSCVTY);
1050 f_vty_set_prompts(BSCVTY);
1051 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001052 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1053 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001054}
1055
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001056friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001057{
1058 // log on TTCN3 log output
1059 log(log_msg);
1060 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001061 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001062}
1063
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001064private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1065{
1066 if (rsl_idx >= lengthof(g_system_information)) {
1067 g_system_information[rsl_idx] := SystemInformationConfig_omit
1068 }
1069 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1070}
1071
1072altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1073 var ASP_RSL_Unitdata rx_rsl_ud;
1074
1075 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1076 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1077 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1078 repeat;
1079 }
1080 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1081 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1082 repeat;
1083 }
1084 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1085 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1086 repeat;
1087 }
1088 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1089 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1090 repeat;
1091 }
1092
1093 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1094 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1095 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1096 repeat;
1097 }
1098 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1099 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1100 repeat;
1101 }
1102 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1103 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1104 repeat;
1105 }
1106 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1107 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1108 repeat;
1109 }
1110}
1111
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001112/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1113private type record of boolean my_BooleanList;
1114
1115private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1116{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001117 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1118
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001119 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001120 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1121 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1122 * stepping into that config node. */
1123 log("msc ", msc_nr, " is not configured, skipping");
1124 continue;
1125 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001126 f_vty_enter_cfg_msc(pt, msc_nr);
1127 if (allow_attach_list[msc_nr]) {
1128 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1129 f_vty_transceive(pt, "allow-attach", strict := false);
1130 } else {
1131 f_vty_transceive(pt, "no allow-attach", strict := false);
1132 }
1133 f_vty_transceive(pt, "exit");
1134 f_vty_transceive(pt, "exit");
1135 }
1136}
1137
Harald Welte21b46bd2017-12-17 19:46:32 +01001138/* global initialization function
1139 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001140 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1141 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1142 */
1143function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001144 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001145 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001146
Harald Welteae026692017-12-09 01:03:01 +01001147 if (g_initialized) {
1148 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001149 }
Harald Welteae026692017-12-09 01:03:01 +01001150 g_initialized := true;
1151
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001152 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001153 activate(as_Tguard());
1154
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001155 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001156 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001157
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001158 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001159 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1160
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001161 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1162 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1163 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1164 }
1165
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001166 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001167 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001168 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1169 * MSC-side BSSAP emulation */
1170 if (handler_mode) {
1171 var RanOps ranops := MSC_RanOps;
1172 ranops.use_osmux := g_osmux_enabled;
1173 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1174 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1175 f_ran_adapter_start(g_bssap[bssap_idx]);
1176 } else {
1177 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1178 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1179 f_ran_adapter_start(g_bssap[bssap_idx]);
1180 f_legacy_bssap_reset();
1181 }
Harald Welte67089ee2018-01-17 22:19:03 +01001182 }
Harald Welted5833a82018-05-27 16:52:56 +02001183
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001184 if (mp_enable_lcs_tests) {
1185 if (handler_mode) {
1186 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1187 } else {
1188 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1189 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1190 }
1191 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001192 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001193
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001194 /* start the test with exactly all enabled MSCs allowed to attach */
1195 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1196
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001197 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001198
Daniel Willmann191e0d92018-01-17 12:44:35 +01001199 f_init_mgcp("VirtMSC");
1200
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001201 for (var integer i := 0; i < nr_bts; i := i+1) {
1202 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001203 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001204}
Harald Welte696ddb62017-12-08 14:01:43 +01001205
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001206function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1207runs on test_CT {
1208 /* wait until osmo-bts-omldummy has respawned */
1209 f_wait_oml(bts_idx, "degraded", 5.0);
1210
1211 /* start RSL connection */
1212 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1213 /* wait until BSC tells us "connected" */
1214 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001215}
1216
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001217function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1218 template SystemInformationConfig expect_si)
1219runs on test_CT {
1220 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1221
1222 f_init_bts(bts_idx, handler_mode);
1223
1224 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1225 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1226 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1227 */
1228 f_sleep(5.0);
1229 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1230
1231 deactivate(sysinfo);
1232
1233 if (match(g_system_information[bts_idx], expect_si)) {
1234 setverdict(pass);
1235 } else {
1236 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1237 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1238 setverdict(fail, "received SI does not match expectations");
1239 return;
1240 }
1241}
1242
Maxd4e56962018-10-31 19:08:25 +01001243/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001244function 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 +01001245runs on test_CT return RSL_Message {
1246 var ASP_RSL_Unitdata rx_rsl_ud;
1247 timer T := t_secs;
1248
1249 T.start;
1250 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001251 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001252 T.stop;
1253 }
1254 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001255 [] T.timeout {
1256 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001257 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001258 }
Harald Welteae026692017-12-09 01:03:01 +01001259 }
1260 return rx_rsl_ud.rsl;
1261}
1262
Harald Welte21b46bd2017-12-17 19:46:32 +01001263/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001264function 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 +01001265runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001266 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001267}
1268
1269
Harald Welte4003d112017-12-09 22:35:39 +01001270/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001271testcase TC_chan_act_noreply() runs on test_CT {
1272 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001273 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001274
Harald Welte89d42e82017-12-17 16:42:41 +01001275 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001276
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001277 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001278 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001279 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001280}
1281
Harald Welte4003d112017-12-09 22:35:39 +01001282/* verify if the "chreq:total" counter increments as expected */
1283testcase TC_chan_act_counter() runs on test_CT {
1284 var BSSAP_N_UNITDATA_ind ud_ind;
1285 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001286 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001287
Harald Welte89d42e82017-12-17 16:42:41 +01001288 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001289
1290 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001291 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001292 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001293 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1294
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001295 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001296}
1297
Harald Welteae026692017-12-09 01:03:01 +01001298/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001299private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001300 var RSL_Message rx_rsl;
1301
Harald Welteae026692017-12-09 01:03:01 +01001302 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001303 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001304
1305 /* expect BSC to disable the channel again if there's no RLL EST IND */
1306 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1307
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001308 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001309}
1310
Philipp Maier9c60a622020-07-09 15:08:46 +02001311/* Normal variant */
1312testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001313 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001314 f_TC_chan_act_ack_noest();
1315}
1316
1317/* Emergency call variant */
1318testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1319 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001320 f_init(1);
1321 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001322 f_TC_chan_act_ack_noest(ra := 'A5'O);
1323}
1324
Philipp Maier606f07d2020-08-12 17:21:58 +02001325/* Emergency call variant, but emergency calls are not allowed */
1326testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1327 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1328
1329 var RSL_Message rx_rsl;
1330 var GsmRrMessage rr;
1331
1332 f_init(1);
1333 f_vty_allow_emerg_bts(false, 0);
1334
1335 IPA_RSL[0].clear;
1336 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1337
1338 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1339 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1340 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1341 setverdict(pass);
1342 } else {
1343 setverdict(fail, "immediate assignment not rejected");
1344 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001345
1346 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001347}
1348
Harald Welteae026692017-12-09 01:03:01 +01001349/* Test behavior if MSC never answers to CR */
1350testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001351 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1352 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001353 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001354 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001355
Harald Welte89d42e82017-12-17 16:42:41 +01001356 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001357
1358 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001359 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001360
1361 var octetstring l3 := '00010203040506'O
1362 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1363
1364 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1365
1366 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001367 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001368 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001369 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001370}
1371
1372/* Test behavior if MSC answers with CREF to CR */
1373testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1374 var BSSAP_N_CONNECT_ind rx_c_ind;
1375 var RSL_Message rx_rsl;
1376
Harald Welte89d42e82017-12-17 16:42:41 +01001377 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001378
1379 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001380 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001381
1382 var octetstring l3 := '00010203040506'O
1383 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1384
1385 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1386 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1387
1388 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001389 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001390 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001391}
1392
Harald Welte618ef642017-12-14 14:58:20 +01001393/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1394testcase TC_chan_act_nack() runs on test_CT {
1395 var RSL_Message rx_rsl;
1396 var integer chact_nack;
1397
Harald Welte89d42e82017-12-17 16:42:41 +01001398 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001399
1400 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1401
1402 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1403 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1404 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1405
1406 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1407
1408 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1409 f_sleep(0.5);
1410
1411 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1412
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001413 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001414}
1415
Harald Welte799c97b2017-12-14 17:50:30 +01001416/* Test for channel exhaustion due to RACH overload */
1417testcase TC_chan_exhaustion() runs on test_CT {
1418 var ASP_RSL_Unitdata rsl_ud;
1419 var integer i;
1420 var integer chreq_total, chreq_nochan;
1421
Harald Welte89d42e82017-12-17 16:42:41 +01001422 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001423
1424 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1425 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1426
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001427 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001428 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1429 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001430 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 +01001431 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001432 }
1433
1434 IPA_RSL[0].clear;
1435
Harald Weltedd8cbf32018-01-28 12:07:52 +01001436 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001437 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001438
1439 /* now expect additional channel activations to fail */
1440 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1441
1442 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001443 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001444 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1445 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001446 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001447 var GsmRrMessage rr;
1448 /* match on IMM ASS REJ */
1449 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1450 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1451 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001452 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001453 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1454 chreq_nochan+1);
1455 setverdict(pass);
1456 } else {
1457 repeat;
1458 }
1459 }
1460 [] IPA_RSL[0].receive { repeat; }
1461 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001462 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001463}
1464
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001465/* Test channel deactivation due to silence from MS */
1466testcase TC_chan_deact_silence() runs on test_CT {
1467 var RslChannelNr chan_nr;
1468
1469 f_init(1);
1470
1471 /* Request for a dedicated channel */
1472 chan_nr := f_chreq_act_ack('23'O);
1473
1474 /* Wait some time until the channel is released */
1475 f_sleep(2.0);
1476
1477 /* Expect CHANnel RELease */
1478 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001479 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001480 log("Received CHANnel RELease");
1481 setverdict(pass);
1482 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001483 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001484 /* See OS#3709, OsmoBSC should not send Immediate
1485 * Assignment Reject since a dedicated channel was
1486 * already allocated, and Immediate Assignment was
1487 * already sent. */
1488 setverdict(fail, "Unexpected Immediate Assignment!");
1489 }
1490 [] IPA_RSL[0].receive {
1491 setverdict(fail, "Unexpected RSL message!");
1492 }
1493 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001494 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001495}
1496
Harald Weltecfe2c962017-12-15 12:09:32 +01001497/***********************************************************************
1498 * Assignment Testing
1499 ***********************************************************************/
1500
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001501/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1502 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001503testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001504 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001505
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001506 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1507 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001508 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001509 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001510}
1511
Harald Welte16a4adf2017-12-14 18:54:01 +01001512/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001513testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001514 var BSSAP_N_CONNECT_ind rx_c_ind;
1515 var RSL_Message rx_rsl;
1516 var DchanTuple dt;
1517
Harald Welte89d42e82017-12-17 16:42:41 +01001518 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001519
1520 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001521 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001522 /* send assignment without AoIP IEs */
1523 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1524 } else {
1525 /* Send assignmetn without CIC in IPA case */
1526 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1527 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1528 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1529 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001530 alt {
1531 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1532 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1533 }
Harald Welte235ebf12017-12-15 14:18:16 +01001534 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001535 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1536 setverdict(pass);
1537 }
1538 [] BSSAP.receive { repeat; }
1539 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001540 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001541}
1542
Harald Welteed848512018-05-24 22:27:58 +02001543/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001544function 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 +02001545 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001546 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001547 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001548 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001549 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001550 if (osmux_enabled) {
1551 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1552 } else {
1553 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1554 }
Harald Welteed848512018-05-24 22:27:58 +02001555 } else {
1556 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001557 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001558 }
1559 return ass_cmd;
1560}
1561
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001562function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001563 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1564 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001565 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001566
1567 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1568 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1569 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1570 var template BSSMAP_IE_KC128 kc128 := omit;
1571 if (ispresent(enc)) {
1572 var TestHdlrEncrParams v_enc := valueof(enc);
1573 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1574 chosenEncryptionAlgorithm := valueof(
1575 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001576 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001577 if (ispresent(v_enc.enc_kc128)) {
1578 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1579 }
1580 }
1581
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001582 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001583 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001584 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001585 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1586 encryptionInformation := encryptionInformation,
1587 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1588 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001589 } else {
1590 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001591 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1592 encryptionInformation := encryptionInformation,
1593 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1594 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001595 }
1596 return ho_req;
1597}
1598
Harald Welteed848512018-05-24 22:27:58 +02001599/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001600function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001601 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001602 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001603 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001604 if (expect_osmux) {
1605 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1606 } else {
1607 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1608 }
Harald Welteed848512018-05-24 22:27:58 +02001609 } else {
1610 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001611 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001612 }
1613 return exp_compl;
1614}
1615
Harald Welte235ebf12017-12-15 14:18:16 +01001616/* Run everything required up to sending a caller-specified assignment command and expect response */
1617function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1618runs on test_CT {
1619 var BSSAP_N_CONNECT_ind rx_c_ind;
1620 var RSL_Message rx_rsl;
1621 var DchanTuple dt;
1622
Harald Welte89d42e82017-12-17 16:42:41 +01001623 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001624
1625 dt := f_est_dchan('23'O, 23, '00000000'O);
1626 /* send assignment without AoIP IEs */
1627 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1628 alt {
1629 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1630 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1631 setverdict(pass);
1632 } else {
1633 setverdict(fail, fail_text);
1634 }
1635 }
1636 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1637 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1638 setverdict(pass);
1639 } else {
1640 setverdict(fail, fail_text);
1641 }
1642 }
1643 [] BSSAP.receive { repeat; }
1644 }
1645}
1646testcase TC_assignment_csd() runs on test_CT {
1647 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001648 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001649 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1650 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1651 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001652 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001653}
1654
1655testcase TC_assignment_ctm() runs on test_CT {
1656 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001657 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001658 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1659 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1660 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001661 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001662}
1663
Harald Welte4003d112017-12-09 22:35:39 +01001664type record DchanTuple {
1665 integer sccp_conn_id,
1666 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001667}
1668
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001669type record of DchanTuple DchanTuples;
1670
Harald Welted6939652017-12-13 21:02:46 +01001671/* Send CHAN RQD and wait for allocation; acknowledge it */
1672private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1673runs on test_CT return RslChannelNr {
1674 var RSL_Message rx_rsl;
1675 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1676 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1677 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1678 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001679 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001680 return chan_nr;
1681}
1682
Harald Welte4003d112017-12-09 22:35:39 +01001683/* helper function to establish a dedicated channel via BTS and MSC */
1684function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1685runs on test_CT return DchanTuple {
1686 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001687 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001688
Harald Welte4003d112017-12-09 22:35:39 +01001689 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001690 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001691
1692 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1693
1694 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1695 dt.sccp_conn_id := rx_c_ind.connectionId;
1696 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1697
1698 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001699}
1700
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001701/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1702function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1703runs on test_CT return DchanTuple {
1704 var BSSAP_N_CONNECT_ind rx_c_ind;
1705 var DchanTuple dt;
1706
1707 /* Send CHAN RQD */
1708 var RSL_Message rx_rsl;
1709 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1710
1711 /* The dyn TS first deactivates PDCH */
1712 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1713 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1714 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1715
1716 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1717 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1718
1719 /* Now activates the signalling channel */
1720 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1721 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1722
1723 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1724
1725 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1726 dt.sccp_conn_id := rx_c_ind.connectionId;
1727 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1728
1729 return dt;
1730}
1731
Harald Welte641fcbe2018-06-14 10:58:35 +02001732/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1733private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1734 var RSL_Message rx_rsl;
1735 /* expect BSC to disable the channel */
1736 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1737 /* respond with CHAN REL ACK */
1738 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1739
1740 /* expect Clear Complete from BSC */
1741 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1742
1743 /* MSC disconnects as instructed. */
1744 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1745}
1746
Harald Welte4003d112017-12-09 22:35:39 +01001747/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1748testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001749 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001750 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001751
Harald Welte89d42e82017-12-17 16:42:41 +01001752 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001753
Harald Welte4003d112017-12-09 22:35:39 +01001754 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1755
1756 /* simulate RLL REL IND */
1757 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1758
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001759 /* expect Clear Request on MSC side */
1760 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1761
1762 /* Instruct BSC to clear channel */
1763 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1764 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1765
Harald Welte4003d112017-12-09 22:35:39 +01001766 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001767 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001768
1769 /* wait for SCCP emulation to do its job */
1770 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001771
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001772 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001773}
1774
1775/* Test behavior of channel release after CONN FAIL IND from BTS */
1776testcase TC_chan_rel_conn_fail() runs on test_CT {
1777 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001778 var DchanTuple dt;
1779
Harald Welte89d42e82017-12-17 16:42:41 +01001780 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001781
1782 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1783
1784 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001785 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 +01001786 /* TODO: different cause values? */
1787
Harald Welte4003d112017-12-09 22:35:39 +01001788 /* expect Clear Request from BSC */
1789 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1790
1791 /* Instruct BSC to clear channel */
1792 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1793 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1794
Harald Welte6ff76ea2018-01-28 13:08:01 +01001795 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001796 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001797
1798 /* wait for SCCP emulation to do its job */
1799 f_sleep(1.0);
1800
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001801 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001802}
1803
Harald Welte99f3ca02018-06-14 13:40:29 +02001804/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1805/* See also https://www.osmocom.org/issues/3182 */
1806testcase TC_early_conn_fail() runs on test_CT {
1807 var RSL_Message rx_rsl;
1808 var DchanTuple dt;
1809
1810 f_init(1);
1811
1812 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001813 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001814
1815 /* BTS->BSC: simulate CONN FAIL IND */
1816 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1817
1818 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1819 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1820
1821 /* BTS<-BSC: respond with CHAN REL ACK */
1822 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1823
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001824 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001825}
1826
1827/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1828/* See also https://www.osmocom.org/issues/3182 */
1829testcase TC_late_conn_fail() runs on test_CT {
1830 var RSL_Message rx_rsl;
1831 var DchanTuple dt;
1832
1833 f_init(1);
1834
1835 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1836
1837 /* BSC<-MSC: Instruct BSC to clear connection */
1838 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1839
1840 /* BTS->BSC: expect BSC to deactivate SACCH */
1841 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1842
1843 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1844 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1845
1846 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1847 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1848 /* BTS->BSC: respond with CHAN REL ACK */
1849 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1850
1851 /* BSC->MSC: expect Clear Complete from BSC */
1852 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1853
1854 /* BSC<-MSC: MSC disconnects as requested. */
1855 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1856
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001857 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001858}
1859
Oliver Smithaf03bef2021-08-24 15:34:51 +02001860private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1861 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1862 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1863
1864 f_statsd_reset();
1865
1866 /* Establish SDCCH */
1867 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1868 f_establish_fully(ass_cmd, exp_fail);
1869
1870 /* Expect stats to be 0 */
1871 var StatsDExpects expect := {
1872 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1873 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1874 };
1875 f_statsd_expect(expect);
1876
1877 /* Simulate CONN FAIL IND on SDCCH */
1878 RSL.send(ts_ASP_RSL_UD(
1879 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1880 IPAC_PROTO_RSL_TRX0));
1881
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001882 f_sleep(1.0);
1883
Oliver Smithaf03bef2021-08-24 15:34:51 +02001884 /* Expect stats to be 1 */
1885 expect := {
1886 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1887 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1888 };
1889 f_statsd_expect(expect);
1890}
1891testcase TC_stats_conn_fail() runs on test_CT {
1892 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1893 var MSC_ConnHdlr vc_conn;
1894
1895 f_init(1, true);
1896 f_sleep(1.0);
1897
1898 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1899 vc_conn.done;
1900
1901 f_shutdown_helper();
1902}
1903
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001904function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001905 boolean expect_deact_sacch := true,
1906 boolean expect_rr_chan_rel := true,
1907 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001908 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001909 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001910 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001911 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001912
1913 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001914 var boolean got_deact_sacch := false;
1915 var boolean got_rr_chan_rel := false;
1916 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001917 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001918 var RSL_IE_Body l3_ie;
1919 var PDU_ML3_NW_MS l3;
1920 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001921 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1922 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001923 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001924 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001925 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001926 repeat;
1927 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001928 [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 +01001929 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001930
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001931 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1932 setverdict(fail, "cannot find L3");
1933 mtc.stop;
1934 }
1935 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1936
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001937 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001938 var CellSelIndValue cells := dec_CellSelIndValue(
1939 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1940
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001941 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1942 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001943 setverdict(pass);
1944 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001945 log("EXPECTED CELLS: ", expect_cells);
1946 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001947 }
1948 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001949
1950 if (not istemplatekind(expect_rr_cause, "omit")) {
1951 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1952 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1953 if (match(got_cause, expect_rr_cause)) {
1954 setverdict(pass);
1955 } else {
1956 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1957 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1958 }
1959 }
Harald Welte99787102019-02-04 10:41:36 +01001960 repeat;
1961 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001962 [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 +01001963 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001964
1965 if (not istemplatekind(expect_rr_cause, "omit")) {
1966 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1967 setverdict(fail, "cannot find L3");
1968 mtc.stop;
1969 }
1970 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1971
1972 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1973 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1974 if (match(got_cause, expect_rr_cause)) {
1975 setverdict(pass);
1976 } else {
1977 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1978 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1979 }
1980 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001981 repeat;
1982 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001983 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001984 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001985 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001986 if (handle_rll_rel) {
1987 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1988 }
Harald Welte91d54a52018-01-28 15:35:07 +01001989 repeat;
1990 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001991 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001992 /* respond with CHAN REL ACK */
1993 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1994 }
1995 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001996 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001997 repeat;
1998 }
1999 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002000
2001 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2002 " got_rll_rel_req=", got_rll_rel_req);
2003
2004 if (expect_deact_sacch != got_deact_sacch) {
2005 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2006 }
2007 if (expect_rr_chan_rel != got_rr_chan_rel) {
2008 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2009 }
2010 if (expect_rll_rel_req != got_rll_rel_req) {
2011 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2012 }
Harald Welte91d54a52018-01-28 15:35:07 +01002013}
2014
Harald Welte4003d112017-12-09 22:35:39 +01002015/* Test behavior of channel release after hard Clear Command from MSC */
2016testcase TC_chan_rel_hard_clear() runs on test_CT {
2017 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002018 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002019
Harald Welte89d42e82017-12-17 16:42:41 +01002020 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002021
2022 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2023
2024 /* Instruct BSC to clear channel */
2025 var BssmapCause cause := 0;
2026 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2027
2028 /* expect Clear Complete from BSC on A */
2029 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2030 /* release the SCCP connection */
2031 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2032 }
2033
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002034 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002035 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002036}
2037
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002038function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2039 var BSSAP_N_DATA_ind rx_di;
2040 var DchanTuple dt;
2041
2042 f_init(1);
2043
2044 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2045 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2046 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2047 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2048
2049 /* Instruct BSC to clear channel */
2050 var BssmapCause cause := 0;
2051 if (tx_csfb_ind) {
2052 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2053 } else {
2054 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2055 }
2056
2057 /* expect Clear Complete from BSC on A */
2058 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2059 /* release the SCCP connection */
2060 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2061 }
2062
2063 /* 1 neighbor is added by default in osmo-bts.cfg and
2064 SystemInformationConfig_default, use that: */
2065 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2066
2067 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2068 f_shutdown_helper();
2069}
2070
2071/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2072 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2073 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2074 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2075 Indicator or not shouldn't matter at all. */
2076testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2077 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2078}
2079
2080/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2081 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2082 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2083 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2084testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2085 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2086}
2087
2088/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2089 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2090 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2091 CSFB Indicator should not be used anymore, and hence, there should be no
2092 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2093 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002094testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2095 var BSSAP_N_DATA_ind rx_di;
2096 var DchanTuple dt;
2097
2098 f_init(1);
2099
2100 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2101
2102 /* Instruct BSC to clear channel */
2103 var BssmapCause cause := 0;
2104 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2105
2106 /* expect Clear Complete from BSC on A */
2107 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2108 /* release the SCCP connection */
2109 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2110 }
2111
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002112 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002113 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002114}
2115
Harald Welted8c36cd2017-12-09 23:05:31 +01002116/* Test behavior of channel release after hard RLSD from MSC */
2117testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002118 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002119
Harald Welte89d42e82017-12-17 16:42:41 +01002120 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002121
2122 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2123
2124 /* release the SCCP connection */
2125 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2126
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002127 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002128 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002129}
2130
Harald Welte550daf92018-06-11 19:22:13 +02002131/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2132testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2133 var DchanTuple dt;
2134
2135 f_init(1);
2136
2137 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2138
2139 /* release the SCCP connection */
2140 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2141
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002142 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002143 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002144}
2145
Harald Welte85804d42017-12-10 14:11:58 +01002146/* Test behavior of channel release after BSSMAP RESET from MSC */
2147testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002148 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002149
Harald Welte89d42e82017-12-17 16:42:41 +01002150 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002151
2152 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2153
2154 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2155 IPA_RSL[0].clear;
2156
2157 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002158 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 +01002159 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002160 [] 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 +01002161 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2162 }
2163
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002164 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002165 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002166}
2167
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002168/* Verify T(iar) triggers and releases the channel */
2169testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2170 var DchanTuple dt;
2171
2172 /* Set T(iar) in BSC low enough that it will trigger before other side
2173 has time to keep alive with a T(ias). Keep recommended ratio of
2174 T(iar) >= T(ias)*2 */
2175 g_bsc_sccp_timer_ias := 2;
2176 g_bsc_sccp_timer_iar := 5;
2177
2178 f_init(1);
2179
2180 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2181 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002182 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002183}
2184
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002185private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2186runs on test_CT
2187{
2188 var DchanTuple dt;
2189
2190 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2191 var BssmapCause cause := 0;
2192 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2193 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2194 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2195 }
2196
2197 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 +02002198}
2199
2200/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2201testcase TC_chan_rel_rr_cause() runs on test_CT {
2202 f_init(1);
2203
2204 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2205 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2206 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2207 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2208 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2209 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002210
2211 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002212}
2213
Harald Welte5cd20ed2017-12-13 21:03:20 +01002214/* Test behavior if RSL EST IND for non-active channel */
2215testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2216 timer T := 2.0;
2217
Harald Welte89d42e82017-12-17 16:42:41 +01002218 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002219
2220 var octetstring l3 := '00010203040506'O;
2221 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2222 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2223
2224 T.start;
2225 alt {
2226 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2227 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2228 }
2229 [] BSSAP.receive {}
2230 [] IPA_RSL[0].receive {}
2231 [] T.timeout {}
2232 }
2233
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002234 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002235}
2236
2237/* Test behavior if RSL EST IND for invalid SAPI */
2238testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2239 var RslChannelNr chan_nr;
2240
Harald Welte89d42e82017-12-17 16:42:41 +01002241 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002242
2243 chan_nr := f_chreq_act_ack()
2244
2245 var octetstring l3 := '00010203040506'O;
2246 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2247
2248 timer T := 2.0;
2249 T.start;
2250 alt {
2251 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2252 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2253 }
2254 [] BSSAP.receive { repeat; }
2255 [] IPA_RSL[0].receive { repeat; }
2256 [] T.timeout {}
2257 }
2258
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002259 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002260}
2261
2262/* Test behavior if RSL EST IND for invalid SAPI */
2263testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2264 timer T := 2.0;
2265
Harald Welte89d42e82017-12-17 16:42:41 +01002266 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002267
2268 var RslChannelNr chan_nr := f_chreq_act_ack();
2269
2270 var octetstring l3 := '00010203040506'O;
2271 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2272
2273 T.start;
2274 alt {
2275 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2276 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2277 }
2278 [] BSSAP.receive { repeat; }
2279 [] IPA_RSL[0].receive { repeat; }
2280 [] T.timeout {}
2281 }
2282
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002283 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002284}
2285
2286/* Test behavior if RSL EST IND for invalid SACCH */
2287testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2288 timer T := 2.0;
2289
Harald Welte89d42e82017-12-17 16:42:41 +01002290 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002291
2292 var RslChannelNr chan_nr := f_chreq_act_ack();
2293
2294 var octetstring l3 := '00010203040506'O;
2295 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2296
2297 T.start;
2298 alt {
2299 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2300 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2301 }
2302 [] BSSAP.receive { repeat; }
2303 [] IPA_RSL[0].receive { repeat; }
2304 [] T.timeout {}
2305 }
2306
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002307 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002308}
2309
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002310/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2311private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2312 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2313 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2314
2315 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2316 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2317
2318 f_establish_fully(ass_cmd, exp_compl);
2319
2320 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2321 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2322 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2323 BSSAP.receive(PDU_BSSAP:{
2324 discriminator := '1'B,
2325 spare := '0000000'B,
2326 dlci := 'C3'O,
2327 lengthIndicator := ?,
2328 pdu := { dtap := '0904'O }
2329 });
2330
2331 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2332 for (var integer i := 0; i < 32; i := i + 1) {
2333 var octetstring l3 := '09'O & f_rnd_octstring(14);
2334 var template (value) RslLinkId link_id;
2335 var template (value) OCT1 dlci;
2336
2337 if (i mod 2 == 0) {
2338 /* SAPI0 on FACCH or SDCCH */
2339 link_id := ts_RslLinkID_DCCH(0);
2340 dlci := '80'O;
2341 } else {
2342 /* SAPI3 on SACCH */
2343 link_id := ts_RslLinkID_SACCH(3);
2344 dlci := 'C3'O;
2345 }
2346
2347 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002348 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002349 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002350 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002351 }
2352}
2353testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2354 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2355 var MSC_ConnHdlr vc_conn;
2356
2357 f_init(1, true);
2358 f_sleep(1.0);
2359
2360 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2361 vc_conn.done;
2362
2363 f_shutdown_helper();
2364}
2365
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002366private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2367 template myBSSMAP_Cause cause := ?,
2368 float T_val := 2.0)
2369runs on test_CT {
2370 var BSSAP_N_DATA_ind rx_di;
2371 timer T;
2372
2373 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2374 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2375
2376 T.start(T_val);
2377 alt {
2378 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2379 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2380 if (not match(rx_cause, tr_cause)) {
2381 setverdict(fail, "Rx unexpected Cause IE: ",
2382 rx_cause, " vs expected ", tr_cause);
2383 }
2384 setverdict(pass);
2385 }
2386 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2387 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2388 }
2389 [] T.timeout {
2390 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2391 }
2392 }
2393}
2394
2395/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2396testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2397 var octetstring rnd_data := f_rnd_octstring(16);
2398 var RSL_Message rx_rsl;
2399 var DchanTuple dt;
2400
2401 f_init(1);
2402
2403 /* MS establishes a SAPI=0 link on DCCH */
2404 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2405
2406 /* MSC sends some data on (not yet established) SAPI=3 link */
2407 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2408 /* BSC attempts to establish a SAPI=3 link on DCCH */
2409 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2410
2411 /* MS sends unexpected RELease INDication on SAPI=3 */
2412 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2413 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2414 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2415
2416 /* Clean up the connection */
2417 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2418 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2419
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002420 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002421}
2422
2423/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2424testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2425 var octetstring rnd_data := f_rnd_octstring(16);
2426 var RSL_Message rx_rsl;
2427 var DchanTuple dt;
2428
2429 f_init(1);
2430
2431 /* MS establishes a SAPI=0 link on DCCH */
2432 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2433
2434 /* MSC sends some data on (not yet established) SAPI=3 link */
2435 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2436 /* BSC attempts to establish a SAPI=3 link on DCCH */
2437 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2438
2439 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2440 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2441 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2442 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2443
2444 /* Clean up the connection */
2445 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2446 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2447
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002448 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002449}
2450
2451/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2452testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2453 var octetstring rnd_data := f_rnd_octstring(16);
2454 var RSL_Message rx_rsl;
2455 var DchanTuple dt;
2456
2457 f_init(1);
2458
2459 /* MS establishes a SAPI=0 link on DCCH */
2460 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2461
2462 /* MSC sends some data on (not yet established) SAPI=3 link */
2463 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2464 /* BSC attempts to establish a SAPI=3 link on DCCH */
2465 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2466
2467 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2468 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2469
2470 /* Clean up the connection */
2471 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2472 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2473
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002474 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002475}
2476
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002477testcase TC_si_default() runs on test_CT {
2478 f_init(0);
2479 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002480 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002481}
Harald Welte4003d112017-12-09 22:35:39 +01002482
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002483/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2484 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2485private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2486{
2487 select (earfcn_index) {
2488 case (0) {
2489 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2490 return 111;
2491 }
2492 case (1) {
2493 return 1;
2494 }
2495 case (2) {
2496 return 0;
2497 }
2498 case (3) {
2499 return 65535;
2500 }
2501 case else {
2502 return 23 * (earfcn_index - 3);
2503 }
2504 }
2505}
2506
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002507function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2508 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002509
2510 f_init(0);
2511
2512 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2513 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002514 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2515 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002516 }
2517
2518 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2519
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002520 if (not istemplatekind(expect_cells, "omit")) {
2521 /* Also check that RR Channel Release contains these EARFCNs.
2522 * (copied code from TC_chan_rel_hard_clear_csfb) */
2523 var BSSAP_N_DATA_ind rx_di;
2524 var DchanTuple dt;
2525
2526 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002527 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2528 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2529 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002530
2531 /* Instruct BSC to clear channel */
2532 var BssmapCause cause := 0;
2533 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2534
2535 /* expect Clear Complete from BSC on A */
2536 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2537 /* release the SCCP connection */
2538 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2539 }
2540
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002541 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 +02002542 }
2543
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002544 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002545 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 +02002546 }
2547}
2548
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002549private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2550{
2551 var template SI2quaterRestOctetsList si2quater := {};
2552 var integer si2quater_count := (count + 2) / 3;
2553
2554 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002555 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002556 var integer index := i / 3;
2557 var integer earfcn_index := i mod 3;
2558 if (index >= lengthof(si2quater)) {
2559 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2560 }
2561 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);
2562 }
2563
2564 return si2quater;
2565}
2566
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002567private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2568{
2569 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2570
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002571 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002572 for (var integer i := 0; i < count; i := i + 1) {
2573 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002574 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002575 }
2576
2577 return tr_CellSelIndValue_EUTRAN(cells);
2578}
2579
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002580private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2581{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002582 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002583 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002584 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2585 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002586}
2587
2588testcase TC_si2quater_2_earfcns() runs on test_CT {
2589 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002590 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002591}
2592
2593testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002594 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002595 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002596}
2597
2598testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002599 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002600 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002601}
2602
2603testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002604 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002605 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002606}
2607
2608testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002609 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002610 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002611}
2612
2613testcase TC_si2quater_12_earfcns() runs on test_CT {
2614 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002615 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002616}
2617
2618testcase TC_si2quater_23_earfcns() runs on test_CT {
2619 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002620 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002621}
2622
2623testcase TC_si2quater_32_earfcns() runs on test_CT {
2624 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002625 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002626}
2627
2628testcase TC_si2quater_33_earfcns() runs on test_CT {
2629 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002630 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002631}
2632
2633testcase TC_si2quater_42_earfcns() runs on test_CT {
2634 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002635 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002636}
2637
2638testcase TC_si2quater_48_earfcns() runs on test_CT {
2639 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002640 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002641}
2642
2643/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2644 * 48 EARFCNs. */
2645testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002646 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002647 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2648 f_init(0);
2649
2650 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002651 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2652 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002653 }
2654
2655 /* The 49th EARFCN no longer fits, expect VTY error */
2656 f_vty_enter_cfg_bts(BSCVTY, 0);
2657 var charstring vty_error;
2658 vty_error := f_vty_transceive_ret(BSCVTY,
2659 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2660 f_vty_transceive(BSCVTY, "end");
2661
2662 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2663 log("Got expected VTY error: ", vty_error);
2664 setverdict(pass);
2665 } else {
2666 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2667 }
2668
2669 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2670
2671 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002672 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 +02002673 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002674 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002675}
2676
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002677private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2678{
2679 var uint8_t count := 0;
2680 for (var integer i := 5; i < 16; i := i + 1) {
2681 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2682 count := count + 1;
2683 }
2684 }
2685 return count;
2686}
2687
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002688private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2689{
2690 var ASP_RSL_Unitdata rx_rsl_ud;
2691 var SystemInformationType1 last_si1;
2692
2693 timer T := 30.0;
2694 T.start;
2695 alt {
2696 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2697 tr_RSL_BCCH_INFO,
2698 tr_RSL_NO_SACCH_FILL,
2699 tr_RSL_SACCH_FILL))
2700 ) -> value rx_rsl_ud {
2701 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2702 if (g_system_information[rsl_idx].si1 == omit) {
2703 repeat;
2704 }
2705 last_si1 := g_system_information[rsl_idx].si1;
2706 g_system_information[rsl_idx].si1 := omit;
2707 T.stop;
2708 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002709 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002710 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2711 }
2712 return last_si1;
2713}
2714
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002715/* verify ACC rotate feature */
2716testcase TC_si_acc_rotate() runs on test_CT {
2717 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002718 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002719 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002720 var uint8_t count;
2721 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2722
2723 f_init(0, guard_timeout := 60.0);
2724
2725 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2726 "access-control-class-rotate 3",
2727 "access-control-class-rotate-quantum 1"});
2728
2729 /* Init and get first sysinfo */
2730 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2731
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002732 for (var integer i:= 0; i < 20; i := i + 1) {
2733 last_si1 := f_recv_next_si1(0);
2734 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002735 count := f_acc09_count_allowed(acc);
2736 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2737
2738 if (count != 3) {
2739 log("RSL: EXPECTED SI ACC len=3");
2740 setverdict(fail, "received SI does not match expectations");
2741 break;
2742 }
2743
2744 for (var integer j := 0; j < 10; j := j + 1) {
2745 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2746 times_allowed[j] := times_allowed[j] + 1;
2747 }
2748 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002749 }
2750
2751 for (var integer j := 0; j < 10; j := j + 1) {
2752 log("ACC", j, " allowed ", times_allowed[j], " times" );
2753 if (j != 5 and times_allowed[j] < 3) {
2754 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2755 } else if (j == 5 and times_allowed[j] > 0) {
2756 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2757 }
2758 }
2759
2760 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2761 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002762 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002763}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002764
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002765/* verify ACC startup ramp+rotate feature */
2766testcase TC_si_acc_ramp_rotate() runs on test_CT {
2767 var template SystemInformationConfig sic := SystemInformationConfig_default;
2768 var SystemInformationType1 last_si1;
2769 var AccessControlClass acc;
2770 var ASP_RSL_Unitdata rx_rsl_ud;
2771 var uint8_t count;
2772 var uint8_t prev_count;
2773 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2774
2775 f_init(0, guard_timeout := 80.0);
2776
2777 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2778 "access-control-class-rotate 0",
2779 "access-control-class-rotate-quantum 1",
2780 "access-control-class-ramping",
2781 "access-control-class-ramping-step-interval 5",
2782 "access-control-class-ramping-step-size 5"});
2783
2784 /* Init and get first sysinfo */
2785 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2786 last_si1 := g_system_information[0].si1;
2787 acc := last_si1.rach_control.acc;
2788 count := f_acc09_count_allowed(acc);
2789 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2790 while (count > 0) {
2791 last_si1 := f_recv_next_si1(0);
2792 acc := last_si1.rach_control.acc;
2793 count := f_acc09_count_allowed(acc);
2794 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2795 }
2796
2797 /* Increase adm subset size, we should see ramping start up */
2798 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2799 prev_count := 0;
2800 while (true) {
2801 last_si1 := f_recv_next_si1(0);
2802 acc := last_si1.rach_control.acc;
2803 count := f_acc09_count_allowed(acc);
2804 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2805
2806 if (prev_count > count) {
2807 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2808 break;
2809 }
2810
2811 if (count == 9) {
2812 break; /* Maximum reached (10 - 1 perm barred), done here */
2813 }
2814
2815 prev_count := count;
2816 }
2817
2818 setverdict(pass);
2819
2820 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2821 "rach access-control-class 4 allowed",
2822 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002823 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002824}
2825
Harald Welte4003d112017-12-09 22:35:39 +01002826testcase TC_ctrl_msc_connection_status() runs on test_CT {
2827 var charstring ctrl_resp;
2828
Harald Welte89d42e82017-12-17 16:42:41 +01002829 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002830
2831 /* See https://osmocom.org/issues/2729 */
2832 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002833 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002834}
2835
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002836testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2837 var charstring ctrl_resp;
2838
2839 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002840
2841 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002842 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002843}
2844
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002845/* Verify correct stats on the number of configured and connected MSCs */
2846private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2847 g_pars := f_gen_test_hdlr_pars();
2848 var StatsDExpects expect := {
2849 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2850 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2851 };
2852 f_statsd_expect(expect);
2853}
2854
2855private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2856{
2857 var MSC_ConnHdlr vc_conn;
2858
2859 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2860 f_sleep(1.0);
2861 vc_conn := f_start_handler(tc_fn);
2862 vc_conn.done;
2863
2864 /* Also verify stat exposed on CTRL interface */
2865 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2866 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2867
2868 f_shutdown_helper();
2869}
2870
2871/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2872private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2873 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2874}
2875testcase TC_stat_num_msc_connected_1() runs on test_CT {
2876 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2877}
2878
2879/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2880private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2881 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2882}
2883testcase TC_stat_num_msc_connected_2() runs on test_CT {
2884 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2885}
2886
2887/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2888private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2889 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2890}
2891testcase TC_stat_num_msc_connected_3() runs on test_CT {
2892 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2893}
2894
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002895/* Verify correct stats on the number of configured and connected MSCs */
2896private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
2897 g_pars := f_gen_test_hdlr_pars();
2898 var StatsDExpects expect := {
2899 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
2900 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2901 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
2902 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2903 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
2904 };
2905 f_statsd_expect(expect);
2906}
2907
2908private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
2909 var MSC_ConnHdlr vc_conn;
2910
2911 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
2912 f_sleep(1.0);
2913 vc_conn := f_start_handler(tc_fn);
2914 vc_conn.done;
2915
2916 /* Also verify stat exposed on CTRL interface */
2917 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
2918 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
2919 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
2920 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
2921
Neels Hofmeyra41ae302021-09-06 22:06:02 +02002922 /* Verify rf_states exposed on CTRL interface */
2923 var charstring expect_net_rf_states := "";
2924 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
2925 var charstring expect_bts_rf_states := int2str(i) & ",0,";
2926 if (i < NUM_BTS) {
2927 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
2928 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
2929 } else {
2930 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
2931 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
2932 }
2933 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
2934 expect_bts_rf_states := expect_bts_rf_states & "on,";
2935 if (i < nr_bts) {
2936 /* For BTS where RSL is connected, the RSL state will be "up" */
2937 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
2938 } else {
2939 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
2940 }
2941
2942 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
2943 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
2944 }
2945 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
2946
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002947 f_shutdown_helper();
2948}
2949
2950/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
2951private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
2952 f_tc_stat_num_bts_connected_msc_connhdlr(1);
2953}
2954testcase TC_stat_num_bts_connected_1() runs on test_CT {
2955 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
2956}
2957
2958/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
2959private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
2960 f_tc_stat_num_bts_connected_msc_connhdlr(2);
2961}
2962testcase TC_stat_num_bts_connected_2() runs on test_CT {
2963 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
2964}
2965
2966/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
2967private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
2968 f_tc_stat_num_bts_connected_msc_connhdlr(3);
2969}
2970testcase TC_stat_num_bts_connected_3() runs on test_CT {
2971 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
2972}
2973
Harald Welte4003d112017-12-09 22:35:39 +01002974testcase TC_ctrl() runs on test_CT {
2975 var charstring ctrl_resp;
2976
Harald Welte89d42e82017-12-17 16:42:41 +01002977 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002978
2979 /* all below values must match the osmo-bsc.cfg config file used */
2980
Harald Welte6a129692018-03-17 17:30:14 +01002981 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2982 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002983 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002984
2985 var integer bts_nr := 0;
2986 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2987 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2988 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2989 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2990 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2991 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2992 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2993
2994 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2995 f_sleep(2.0);
2996 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2997 setverdict(fail, "oml-uptime not incrementing as expected");
2998 }
2999 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3000
3001 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3002
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003003 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003004}
3005
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003006/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3007 "location-state" over the SCCPlite IPA conn */
3008testcase TC_ctrl_location() runs on test_CT {
3009 var MSC_ConnHdlr vc_conn;
3010 var integer bts_nr := 0;
3011
3012 f_init(1, true);
3013 f_sleep(1.0);
3014
3015 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3016 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3017 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3018
3019 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3020 f_sleep(2.0);
3021
3022 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3023 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3024 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3025
3026 /* should match the one from config */
3027 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3028
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003029 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003030}
3031
Harald Welte6f521d82017-12-11 19:52:02 +01003032
3033/***********************************************************************
3034 * Paging Testing
3035 ***********************************************************************/
3036
3037type record Cell_Identity {
3038 GsmMcc mcc,
3039 GsmMnc mnc,
3040 GsmLac lac,
3041 GsmCellId ci
3042};
Harald Welte24135bd2018-03-17 19:27:53 +01003043private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003044private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003045
Harald Welte5d1a2202017-12-13 19:51:29 +01003046type set of integer BtsIdList;
3047
3048private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3049 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3050 if (bts_id == bts_ids[j]) {
3051 return true;
3052 }
3053 }
3054 return false;
3055}
Harald Welte6f521d82017-12-11 19:52:02 +01003056
3057/* core paging test helper function; used by most paging test cases */
3058private function f_pageing_helper(hexstring imsi,
3059 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003060 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003061 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003062 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003063{
3064 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003065 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003066 var RSL_Message rx_rsl;
3067 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003068 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003069
3070 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003071
3072 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003073 for (i := 0; i < NUM_BTS; i := i + 1) {
3074 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003075 }
Harald Welte6f521d82017-12-11 19:52:02 +01003076
3077 if (isvalue(rsl_chneed)) {
3078 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3079 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3080 } else {
3081 bssmap_chneed := omit;
3082 }
3083
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003084 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3085 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003086
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003087 if (not istemplatekind(tmsi, "omit")) {
3088 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003089 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003090 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003091 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003092
Harald Welte5d1a2202017-12-13 19:51:29 +01003093 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003094 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003095 /* check channel type, paging group */
3096 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3097 setverdict(fail, "Paging for wrong paging group");
3098 }
3099 if (ispresent(rsl_chneed) and
3100 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3101 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3102 }
Harald Welte6f521d82017-12-11 19:52:02 +01003103 }
Harald Welte2fccd982018-01-31 15:48:19 +01003104 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003105 /* do a quick check on all not-included BTSs if they received paging */
3106 for (i := 0; i < NUM_BTS; i := i + 1) {
3107 timer T := 0.1;
3108 if (f_bts_in_list(i, bts_ids)) {
3109 continue;
3110 }
3111 T.start;
3112 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003113 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003114 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3115 }
3116 [] IPA_RSL[i].receive { repeat; }
3117 [] T.timeout { }
3118 }
Harald Welte6f521d82017-12-11 19:52:02 +01003119 }
3120
3121 setverdict(pass);
3122}
3123
Harald Welte5d1a2202017-12-13 19:51:29 +01003124const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003125const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003126const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3127const BtsIdList c_BtsId_LAC2 := { 2 };
3128
Harald Welte6f521d82017-12-11 19:52:02 +01003129/* PAGING by IMSI + TMSI */
3130testcase TC_paging_imsi_nochan() runs on test_CT {
3131 var BSSMAP_FIELD_CellIdentificationList cid_list;
3132 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003133 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003134 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003135}
3136
3137/* PAGING by IMSI + TMSI */
3138testcase TC_paging_tmsi_nochan() runs on test_CT {
3139 var BSSMAP_FIELD_CellIdentificationList cid_list;
3140 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003141 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003142 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003143}
3144
3145/* Paging with different "channel needed' values */
3146testcase TC_paging_tmsi_any() runs on test_CT {
3147 var BSSMAP_FIELD_CellIdentificationList cid_list;
3148 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003149 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003150 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003151}
3152testcase TC_paging_tmsi_sdcch() runs on test_CT {
3153 var BSSMAP_FIELD_CellIdentificationList cid_list;
3154 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003155 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003156 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003157}
3158testcase TC_paging_tmsi_tch_f() runs on test_CT {
3159 var BSSMAP_FIELD_CellIdentificationList cid_list;
3160 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003161 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003162 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003163}
3164testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3165 var BSSMAP_FIELD_CellIdentificationList cid_list;
3166 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003167 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003168 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003169}
3170
3171/* Paging by CGI */
3172testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3173 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3174 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003175 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003176 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003177}
3178
3179/* Paging by LAC+CI */
3180testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3181 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3182 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003183 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003184 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003185}
3186
3187/* Paging by CI */
3188testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3189 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3190 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003191 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003192 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003193}
3194
3195/* Paging by LAI */
3196testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3197 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3198 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003199 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003200 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003201}
3202
3203/* Paging by LAC */
3204testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3205 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3206 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003207 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003208 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003209}
3210
3211/* Paging by "all in BSS" */
3212testcase TC_paging_imsi_nochan_all() runs on test_CT {
3213 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3214 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003215 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003216 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003217}
3218
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003219/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003220testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3221 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3222 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 +01003223 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003224 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003225}
Harald Welte6f521d82017-12-11 19:52:02 +01003226
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003227/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003228testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3229 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3230 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003231 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003232 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003233}
3234
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003235/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003236testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3237 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3238 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003239 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003240 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003241}
3242
Harald Welte6f521d82017-12-11 19:52:02 +01003243/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003244testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3245 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3246 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3247 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003248 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003249}
3250
3251/* Paging on empty list: Verify none of them page */
3252testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3253 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3254 cid_list := { cIl_LAC := { } };
3255 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003256 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003257}
3258
Stefan Sperling049a86e2018-03-20 15:51:00 +01003259/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3260testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3261 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3262 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3263 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3264 f_shutdown_helper();
3265}
3266
Harald Welte6f521d82017-12-11 19:52:02 +01003267/* Verify paging retransmission interval + count */
3268/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003269/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003270
Harald Weltee65d40e2017-12-13 00:09:06 +01003271/* Verify PCH load */
3272testcase TC_paging_imsi_load() runs on test_CT {
3273 var BSSMAP_FIELD_CellIdentificationList cid_list;
3274 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003275 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003276 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003277 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003278
3279 /* tell BSC there is no paging space anymore */
3280 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003281 f_sleep(0.2);
3282 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003283
3284 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3285 * there would be 8 retransmissions during 4 seconds */
3286 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003287 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003288 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003289 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003290 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003291 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003292 }
Harald Welte2caa1062018-03-17 18:19:05 +01003293 [] T_retrans.timeout {
3294 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3295 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3296 T_retrans.start;
3297 repeat;
3298 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003299 [] T.timeout {
3300 setverdict(pass);
3301 }
3302 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003303
3304 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003305}
3306
Harald Welte235ebf12017-12-15 14:18:16 +01003307/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003308testcase TC_paging_counter() runs on test_CT {
3309 var BSSMAP_FIELD_CellIdentificationList cid_list;
3310 timer T := 4.0;
3311 var integer i;
3312 var integer paging_attempted_bsc;
3313 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003314 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003315 var integer paging_expired_bts[NUM_BTS];
3316 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3317
3318 f_init();
3319
3320 /* read counters before paging */
3321 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003322 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3323 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3324 }
Harald Welte1ff69992017-12-14 12:31:17 +01003325 for (i := 0; i < NUM_BTS; i := i+1) {
3326 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3327 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3328 }
3329
3330 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3331
3332 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3333 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3334 for (i := 0; i < NUM_BTS; i := i+1) {
3335 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3336 paging_attempted_bts[i]+1);
3337 }
3338
3339 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3340 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003341 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3342 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3343 }
Harald Welte1ff69992017-12-14 12:31:17 +01003344 for (i := 0; i < NUM_BTS; i := i+1) {
3345 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3346 paging_expired_bts[i]+1);
3347 }
Harald Welte1ff69992017-12-14 12:31:17 +01003348
Philipp Maier282ca4b2018-02-27 17:17:00 +01003349 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003350}
3351
3352
Harald Welte10985002017-12-12 09:29:15 +01003353/* Verify paging stops after A-RESET */
3354testcase TC_paging_imsi_a_reset() runs on test_CT {
3355 var BSSMAP_FIELD_CellIdentificationList cid_list;
3356 timer T := 3.0;
3357 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003358 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003359
3360 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003361 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 +01003362 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003363 [] 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 +01003364 [] BSSAP.receive { repeat; }
3365 }
3366
Daniel Willmanncbef3982018-07-30 09:22:40 +02003367 /* Wait to avoid a possible race condition if a paging message is
3368 * received right before the reset ACK. */
3369 f_sleep(0.2);
3370
Harald Welte10985002017-12-12 09:29:15 +01003371 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003372 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3373 IPA_RSL[i].clear;
3374 }
Harald Welte10985002017-12-12 09:29:15 +01003375
3376 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3377 T.start;
3378 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003379 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003380 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003381 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003382 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003383 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003384 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003385 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003386 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003387 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003388 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003389 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003390 }
Harald Welte10985002017-12-12 09:29:15 +01003391 [] T.timeout {
3392 setverdict(pass);
3393 }
3394 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003395
3396 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003397}
Harald Welteae026692017-12-09 01:03:01 +01003398
Philipp Maierf45824a2019-08-14 14:44:10 +02003399/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3400 * paging response we can not know which MSC is in charge, so we will blindly
3401 * pick the first configured MSC. This behavior is required in order to make
3402 * MT-CSFB calls working because in those cases the BSC can not know that the
3403 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3404 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003405 */
3406testcase TC_paging_resp_unsol() runs on test_CT {
3407
3408 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003409 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003410
3411 var BSSAP_N_CONNECT_ind rx_c_ind;
3412 var DchanTuple dt;
3413 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003414 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003415
3416 /* Send CHAN RQD and wait for allocation; acknowledge it */
3417 dt.rsl_chan_nr := f_chreq_act_ack();
3418
3419 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3420 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3421
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003422
Philipp Maierf45824a2019-08-14 14:44:10 +02003423 /* Expevct a CR with a matching Paging response on the A-Interface */
3424 T.start;
3425 alt {
3426 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3427 setverdict(pass);
3428 }
3429 [] BSSAP.receive {
3430 setverdict(fail, "Received unexpected message on A-Interface!");
3431 }
3432 [] T.timeout {
3433 setverdict(fail, "Received nothing on A-Interface!");
3434 }
3435 }
3436
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003437 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003438}
3439
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003440/* Test RSL link drop causes counter increment */
3441testcase TC_rsl_drop_counter() runs on test_CT {
3442 var integer rsl_fail;
3443
Harald Welte89d42e82017-12-17 16:42:41 +01003444 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003445
3446 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3447
3448 bts[0].rsl.vc_IPA.stop;
3449
3450 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3451
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003452 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003453}
3454
3455/* TODO: Test OML link drop causes counter increment */
3456
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003457/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3458function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3459 timer T := 10.0;
3460
3461 bts[0].rsl.id := "IPA-0-RSL";
3462 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3463 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3464 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003465 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003466
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003467 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003468
3469 f_init_mgcp("VirtMSC");
3470
3471 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3472 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3473 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3474 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3475
3476 /* wait for IPA OML link to connect and then disconnect */
3477 T.start;
3478 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003479 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003480 T.stop;
3481 return true;
3482 }
3483 [] IPA_RSL[0].receive { repeat }
3484 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003485 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003486 }
3487 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003488 return false;
3489}
3490
3491/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3492testcase TC_rsl_unknown_unit_id() runs on test_CT {
3493 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3494 setverdict(pass);
3495 } else {
3496 setverdict(fail, "Timeout RSL waiting for connection to close");
3497 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003498 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003499}
3500
3501
3502/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3503testcase TC_oml_unknown_unit_id() runs on test_CT {
3504 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3505 setverdict(pass);
3506 } else {
3507 setverdict(fail, "Timeout OML waiting for connection to close");
3508 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003509 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003510}
3511
3512
Harald Weltec1a2fff2017-12-17 11:06:19 +01003513/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003514 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003515 ***********************************************************************/
3516
Harald Welte6811d102019-04-14 22:23:14 +02003517import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003518import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003519import from RSL_Emulation all;
3520import from MSC_ConnectionHandler all;
3521
3522type function void_fn(charstring id) runs on MSC_ConnHdlr;
3523
Harald Welte336820c2018-05-31 20:34:52 +02003524/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003525private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3526 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003527 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003528 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003529 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003530 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003531 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3532 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3533 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003534 if (isvalue(bts[2])) {
3535 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3536 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3537 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003538 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003539 if (mp_enable_lcs_tests) {
3540 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3541 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3542 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003543 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003544 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003545 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003546}
3547
Neels Hofmeyrda436782021-07-20 22:09:06 +02003548function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003549runs on test_CT return MSC_ConnHdlr {
3550 var charstring id := testcasename();
3551 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003552 var integer bssap_idx := 0;
3553 if (isvalue(pars)) {
3554 bssap_idx := valueof(pars).mscpool.bssap_idx;
3555 }
Harald Welte336820c2018-05-31 20:34:52 +02003556 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003557 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003558 return vc_conn;
3559}
3560
3561function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3562runs on test_CT return MSC_ConnHdlr {
3563 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003564 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003565 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003566 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003567 return vc_conn;
3568}
3569
Neels Hofmeyrda436782021-07-20 22:09:06 +02003570function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3571runs on test_CT return MSC_ConnHdlr {
3572 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3573}
3574
Harald Weltea0630032018-03-20 21:09:55 +01003575/* first function inside ConnHdlr component; sets g_pars + starts function */
3576private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3577runs on MSC_ConnHdlr {
3578 if (isvalue(pars)) {
3579 g_pars := valueof(pars);
3580 }
3581 fn.apply(id);
3582}
3583
Oliver Smith26a3db72021-07-09 13:51:29 +02003584private function f_vty_encryption_a5(charstring options) runs on test_CT {
3585 f_vty_transceive(BSCVTY, "configure terminal");
3586 f_vty_transceive(BSCVTY, "network");
3587 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3588 f_vty_transceive(BSCVTY, "exit");
3589 f_vty_transceive(BSCVTY, "exit");
3590}
3591
3592private function f_vty_encryption_a5_reset() runs on test_CT {
3593 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3594 f_vty_encryption_a5("0 1 3");
3595}
3596
Harald Welte3c86ea02018-05-10 22:28:05 +02003597/* Establish signalling channel (non-assignment case) followed by cipher mode */
3598private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003599 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3600 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003601 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003602 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3603 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3604 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3605 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003606
Philipp Maier23000732018-05-18 11:25:37 +02003607 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003608}
3609testcase TC_ciph_mode_a5_0() runs on test_CT {
3610 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003611 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003612 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3613
3614 f_init(1, true);
3615 f_sleep(1.0);
3616 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3617 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003618 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003619}
3620testcase TC_ciph_mode_a5_1() runs on test_CT {
3621 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003622 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003623 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3624
3625 f_init(1, true);
3626 f_sleep(1.0);
3627 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3628 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003629 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003630}
Oliver Smith50b98122021-07-09 15:00:28 +02003631/* OS#4975: verify that A5/2 is preferred over A5/0 */
3632testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3633 var MSC_ConnHdlr vc_conn;
3634 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3635
3636 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3637 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3638
3639 f_init(1, true);
3640 f_vty_encryption_a5("0 1 2 3");
3641 f_sleep(1.0);
3642 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3643 vc_conn.done;
3644 f_vty_encryption_a5_reset();
3645 f_shutdown_helper();
3646}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003647/* OS#4975: verify that A5/1 is preferred over A5/2 */
3648testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3649 var MSC_ConnHdlr vc_conn;
3650 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3651
3652 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3653 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3654
3655 f_init(1, true);
3656 f_vty_encryption_a5("1 2");
3657 f_sleep(1.0);
3658 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3659 vc_conn.done;
3660 f_vty_encryption_a5_reset();
3661 f_shutdown_helper();
3662}
Harald Welte3c86ea02018-05-10 22:28:05 +02003663testcase TC_ciph_mode_a5_3() runs on test_CT {
3664 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003665 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003666 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3667
3668 f_init(1, true);
3669 f_sleep(1.0);
3670 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3671 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003672 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003673}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003674/* Establish a Signalling channel with A5/4 encryption. */
3675testcase TC_ciph_mode_a5_4() runs on test_CT {
3676 var MSC_ConnHdlr vc_conn;
3677 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3678 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003679
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003680 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003681 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003682 f_sleep(1.0);
3683 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3684 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003685 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003686 f_shutdown_helper();
3687}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003688/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3689private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3690 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3691 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3692 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3693 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3694
3695 f_establish_fully(ass_cmd, exp_compl);
3696}
3697testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3698 var MSC_ConnHdlr vc_conn;
3699 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3700
3701 f_init(1, true);
3702 f_sleep(1.0);
3703 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3704 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003705 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003706}
3707
Harald Welte3c86ea02018-05-10 22:28:05 +02003708
3709/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003710private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003711 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3712 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003713
Harald Welte552620d2017-12-16 23:21:36 +01003714 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3715 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003716
Harald Weltea0630032018-03-20 21:09:55 +01003717 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003718}
Harald Welte552620d2017-12-16 23:21:36 +01003719testcase TC_assignment_fr_a5_0() runs on test_CT {
3720 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003721 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003722 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003723
Harald Welte89d42e82017-12-17 16:42:41 +01003724 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003725 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003726 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003727 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003728 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003729}
Harald Welte552620d2017-12-16 23:21:36 +01003730testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003731 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003732 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003733 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003734
Harald Welte89d42e82017-12-17 16:42:41 +01003735 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003736 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003737 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3738 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003739 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003740}
3741testcase TC_assignment_fr_a5_3() runs on test_CT {
3742 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003743 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003744 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003745
Harald Welte651fcdc2018-05-10 20:23:16 +02003746 f_init(1, true);
3747 f_sleep(1.0);
3748 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003749 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003750 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003751}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003752/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3753testcase TC_assignment_fr_a5_4() runs on test_CT {
3754 var MSC_ConnHdlr vc_conn;
3755 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3756 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3757
3758 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003759 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003760 f_sleep(1.0);
3761 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3762 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003763 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003764 f_shutdown_helper();
3765}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003766
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003767/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3768testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3769 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3770 var MSC_ConnHdlr vc_conn;
3771
3772 f_init(1, true);
3773 f_sleep(1.0);
3774
3775 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3776 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3777 vc_conn.done;
3778 f_shutdown_helper();
3779}
3780
Harald Welte552620d2017-12-16 23:21:36 +01003781/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3782private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003783 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003784 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003785 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003786
3787 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003788 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3789
Harald Weltea0630032018-03-20 21:09:55 +01003790 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003791}
Harald Welte552620d2017-12-16 23:21:36 +01003792testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3793 var MSC_ConnHdlr vc_conn;
3794
Harald Welte89d42e82017-12-17 16:42:41 +01003795 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003796 f_sleep(1.0);
3797
Harald Welte8863fa12018-05-10 20:15:27 +02003798 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003799 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003800 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003801}
3802
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003803private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3804 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3805 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003806
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003807 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3808 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3809
3810 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3811
3812 var BSSMAP_FIELD_CodecType codecType;
3813 timer T := 10.0;
3814
3815 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3816 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3817
3818 f_create_chan_and_exp();
3819 /* we should now have a COMPL_L3 at the MSC */
3820
3821 var template PDU_BSSAP exp_l3_compl;
3822 exp_l3_compl := tr_BSSMAP_ComplL3()
3823 if (g_pars.aoip == false) {
3824 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3825 } else {
3826 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3827 }
3828 T.start;
3829 alt {
3830 [] BSSAP.receive(exp_l3_compl);
3831 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3832 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3833 }
3834 [] T.timeout {
3835 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3836 }
3837 }
3838
3839 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003840 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003841}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003842testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3843 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003844 var MSC_ConnHdlr vc_conn;
3845
Harald Welte89d42e82017-12-17 16:42:41 +01003846 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003847 f_sleep(1.0);
3848
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003849 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003850 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003851 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003852 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003853}
3854
3855
Harald Welte4532e0a2017-12-23 02:05:44 +01003856private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003857 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003858 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003859 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003860 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003861
3862 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003863 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003864
3865 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003866 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3867 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003868 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3869 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3870 };
3871 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003872}
3873
3874testcase TC_assignment_sign() runs on test_CT {
3875 var MSC_ConnHdlr vc_conn;
3876
3877 f_init(1, true);
3878 f_sleep(1.0);
3879
Harald Welte8863fa12018-05-10 20:15:27 +02003880 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003881 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003882 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003883}
3884
Harald Welte60aa5762018-03-21 19:33:13 +01003885/***********************************************************************
3886 * Codec (list) testing
3887 ***********************************************************************/
3888
3889/* check if the given rsl_mode is compatible with the a_elem */
3890private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3891return boolean {
3892 select (a_elem.codecType) {
3893 case (GSM_FR) {
3894 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3895 return true;
3896 }
3897 }
3898 case (GSM_HR) {
3899 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3900 return true;
3901 }
3902 }
3903 case (GSM_EFR) {
3904 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3905 return true;
3906 }
3907 }
3908 case (FR_AMR) {
3909 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3910 return true;
3911 }
3912 }
3913 case (HR_AMR) {
3914 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3915 return true;
3916 }
3917 }
3918 case else { }
3919 }
3920 return false;
3921}
3922
3923/* check if the given rsl_mode is compatible with the a_list */
3924private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3925return boolean {
3926 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3927 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3928 return true;
3929 }
3930 }
3931 return false;
3932}
3933
3934/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003935function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003936return BSSMAP_IE_ChannelType {
3937 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3938 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3939 select (a_elem.codecType) {
3940 case (GSM_FR) {
3941 ret.channelRateAndType := ChRate_TCHF;
3942 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3943 }
3944 case (GSM_HR) {
3945 ret.channelRateAndType := ChRate_TCHH;
3946 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3947 }
3948 case (GSM_EFR) {
3949 ret.channelRateAndType := ChRate_TCHF;
3950 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3951 }
3952 case (FR_AMR) {
3953 ret.channelRateAndType := ChRate_TCHF;
3954 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3955 }
3956 case (HR_AMR) {
3957 ret.channelRateAndType := ChRate_TCHH;
3958 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3959 }
3960 case else {
3961 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003962 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003963 }
3964 }
3965 return ret;
3966}
3967
Harald Weltea63b9102018-03-22 20:36:16 +01003968private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3969return template RSL_IE_Body {
3970 var template RSL_IE_Body mode_ie := {
3971 chan_mode := {
3972 len := ?,
3973 reserved := ?,
3974 dtx_d := ?,
3975 dtx_u := ?,
3976 spd_ind := RSL_SPDI_SPEECH,
3977 ch_rate_type := -,
3978 coding_alg_rate := -
3979 }
3980 }
3981
3982 select (a_elem.codecType) {
3983 case (GSM_FR) {
3984 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3985 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3986 }
3987 case (GSM_HR) {
3988 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3989 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3990 }
3991 case (GSM_EFR) {
3992 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3993 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3994 }
3995 case (FR_AMR) {
3996 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3997 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3998 }
3999 case (HR_AMR) {
4000 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4001 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4002 }
4003 }
4004 return mode_ie;
4005}
4006
Harald Welte60aa5762018-03-21 19:33:13 +01004007type record CodecListTest {
4008 BSSMAP_IE_SpeechCodecList codec_list,
4009 charstring id
4010}
4011type record of CodecListTest CodecListTests
4012
4013private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004014 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
4015 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01004016
4017 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004018 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004019 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4020 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4021 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004022 if (isvalue(g_pars.expect_mr_s0_s7)) {
4023 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4024 g_pars.expect_mr_s0_s7;
4025 }
Harald Welte79f3f542018-05-25 20:02:37 +02004026 }
Harald Welte60aa5762018-03-21 19:33:13 +01004027 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4028 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004029 log("expecting ASS COMPL like this: ", exp_compl);
4030
4031 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004032
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004033 if (not g_pars.expect_channel_mode_modify) {
4034 /* Verify that the RSL-side activation actually matches our expectations */
4035 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004036
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004037 var RSL_IE_Body mode_ie;
4038 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4039 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004040 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004041 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004042 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4043 if (not match(mode_ie, t_mode_ie)) {
4044 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4045 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004046 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004047
4048 var RSL_IE_Body mr_conf;
4049 if (g_pars.expect_mr_conf_ie != omit) {
4050 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4051 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4052 mtc.stop;
4053 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004054 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004055
4056 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4057 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4058 g_pars.expect_mr_conf_ie);
4059 }
4060 } else {
4061 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4062 log("found RSL MR CONFIG IE: ", mr_conf);
4063 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4064 mtc.stop;
4065 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004066 }
4067 }
Harald Welte60aa5762018-03-21 19:33:13 +01004068}
4069
Philipp Maierd0e64b02019-03-13 14:15:23 +01004070private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4071
4072 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4073 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4074
4075 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004076 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004077 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4078 }
4079 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4080 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4081 log("expecting ASS FAIL like this: ", exp_fail);
4082
4083 f_establish_fully(ass_cmd, exp_fail);
4084}
4085
Harald Welte60aa5762018-03-21 19:33:13 +01004086testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004087 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004088 var MSC_ConnHdlr vc_conn;
4089
4090 f_init(1, true);
4091 f_sleep(1.0);
4092
4093 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004094 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004095 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004096 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004097}
4098
4099testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004100 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004101 var MSC_ConnHdlr vc_conn;
4102
4103 f_init(1, true);
4104 f_sleep(1.0);
4105
4106 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004107 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004108 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004109 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004110}
4111
4112testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004113 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004114 var MSC_ConnHdlr vc_conn;
4115
4116 f_init(1, true);
4117 f_sleep(1.0);
4118
4119 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004120 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004121 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004122 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004123}
4124
Philipp Maierd0e64b02019-03-13 14:15:23 +01004125/* Allow 5,90k only (current default config) */
4126private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004127 f_vty_cfg_msc(BSCVTY, 0, {
4128 "amr-config 12_2k forbidden",
4129 "amr-config 10_2k forbidden",
4130 "amr-config 7_95k forbidden",
4131 "amr-config 7_40k forbidden",
4132 "amr-config 6_70k forbidden",
4133 "amr-config 5_90k allowed",
4134 "amr-config 5_15k forbidden",
4135 "amr-config 4_75k forbidden"
4136 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004137}
4138
4139/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4140 * ("Config-NB-Code = 1") */
4141private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004142 f_vty_cfg_msc(BSCVTY, 0, {
4143 "amr-config 12_2k allowed",
4144 "amr-config 10_2k forbidden",
4145 "amr-config 7_95k forbidden",
4146 "amr-config 7_40k allowed",
4147 "amr-config 6_70k forbidden",
4148 "amr-config 5_90k allowed",
4149 "amr-config 5_15k forbidden",
4150 "amr-config 4_75k allowed"
4151 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004152}
4153
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004154private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4155 var charstring tch;
4156 if (fr) {
4157 tch := "tch-f";
4158 } else {
4159 tch := "tch-h";
4160 }
4161 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4162}
4163
4164/* Set the AMR start-mode for this TCH back to the default configuration. */
4165private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4166 f_vty_amr_start_mode_set(fr, "auto");
4167}
4168
Harald Welte60aa5762018-03-21 19:33:13 +01004169testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004170 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004171 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004172
4173 /* Note: This setups the codec configuration. The parameter payload in
4174 * mr_conf must be consistant with the parameter codecElements in pars
4175 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004176 var RSL_IE_Body mr_conf := {
4177 other := {
4178 len := 2,
4179 payload := '2804'O
4180 }
4181 };
Harald Welte60aa5762018-03-21 19:33:13 +01004182
Philipp Maier7695a0d2018-09-27 17:52:14 +02004183 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004184 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004185 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4186 pars.expect_mr_conf_ie := mr_conf;
4187
Harald Welte60aa5762018-03-21 19:33:13 +01004188 f_init(1, true);
4189 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004190 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004191
Harald Welte8863fa12018-05-10 20:15:27 +02004192 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004193 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004194
4195 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004196 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004197}
4198
4199testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004200 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004201 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004202
4203 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004204 var RSL_IE_Body mr_conf := {
4205 other := {
4206 len := 2,
4207 payload := '2804'O
4208 }
4209 };
Harald Welte60aa5762018-03-21 19:33:13 +01004210
Philipp Maier7695a0d2018-09-27 17:52:14 +02004211 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004212 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004213 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4214 pars.expect_mr_conf_ie := mr_conf;
4215
Harald Welte60aa5762018-03-21 19:33:13 +01004216 f_init(1, true);
4217 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004218 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004219
Harald Welte8863fa12018-05-10 20:15:27 +02004220 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004221 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004222
4223 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004224 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004225}
4226
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004227/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4228testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4229 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4230 var MSC_ConnHdlr vc_conn;
4231
4232 f_init(1, true);
4233 f_sleep(1.0);
4234
4235 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4236 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4237 * expecting a Channel Mode Modify if the channel type is compatible. */
4238 f_disable_all_sdcch();
4239 f_disable_all_tch_h();
4240
4241 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4242 pars.expect_channel_mode_modify := true;
4243 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4244 vc_conn.done;
4245
4246 f_enable_all_sdcch();
4247 f_enable_all_tch();
4248 f_shutdown_helper();
4249}
4250
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004251/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4252testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4253 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4254 var MSC_ConnHdlr vc_conn;
4255
4256 var RSL_IE_Body mr_conf := {
4257 other := {
4258 len := 2,
4259 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4260 }
4261 };
4262
4263 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4264 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4265 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4266 pars.expect_mr_conf_ie := mr_conf;
4267
4268 f_init(1, true);
4269 f_sleep(1.0);
4270
4271 /* First set nonzero start mode bits */
4272 f_vty_amr_start_mode_set(true, "4");
4273 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4274 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4275 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4276 f_vty_amr_start_mode_set(true, "auto");
4277
4278 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4279 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004280
4281 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4282 f_vty_amr_start_mode_set(true, "1");
4283 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004284 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004285}
4286
Neels Hofmeyr21863562020-11-26 00:34:33 +00004287function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4288 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004289runs on test_CT {
4290
4291 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4292 var MSC_ConnHdlr vc_conn;
4293
4294 /* See note above */
4295 var RSL_IE_Body mr_conf := {
4296 other := {
4297 len := lengthof(mrconf),
4298 payload := mrconf
4299 }
4300 };
4301
4302 if (fr) {
4303 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4304 } else {
4305 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4306 }
4307 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4308 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4309 pars.expect_mr_conf_ie := mr_conf;
4310 pars.expect_mr_s0_s7 := exp_s8_s0;
4311
4312 f_init(1, true);
4313 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004314 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004315 f_sleep(1.0);
4316
4317 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4318 vc_conn.done;
4319 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004320 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004321}
4322
4323function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4324runs on test_CT {
4325
4326 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4327 var MSC_ConnHdlr vc_conn;
4328
4329 if (fr) {
4330 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4331 } else {
4332 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4333 }
4334 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4335 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4336
4337 f_init(1, true);
4338 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004339 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004340 f_sleep(1.0);
4341
4342 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4343 vc_conn.done;
4344 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004345 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004346}
4347
4348
4349/* Set S1, we expect an AMR multirate configuration IE with all four rates
4350 * set. */
4351testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004352 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004353 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004354}
4355
4356/* Set S1, we expect an AMR multirate configuration IE with the lower three
4357 * rates set. */
4358testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004359 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004360 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004361}
4362
4363/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4364 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4365testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004366 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004367 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004368}
4369
4370/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4371 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4372testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004373 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004374 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004375}
4376
4377/* The following block of tests selects more and more rates until all four
4378 * possible rates are in the active set (full rate) */
4379testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004380 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004381 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004382}
4383
4384testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004385 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004386 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004387}
4388
4389testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004390 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004391 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004392}
4393
4394testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004395 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004396 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004397}
4398
4399/* The following block of tests selects more and more rates until all three
4400 * possible rates are in the active set (half rate) */
4401testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004402 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004403 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004404}
4405
4406testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004407 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004408 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004409}
4410
4411testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004412 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004413 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004414}
4415
4416/* The following block tests what happens when the MSC does offer rate
4417 * configurations that are not supported by the BSC. Normally such situations
4418 * should not happen because the MSC gets informed by the BSC in advance via
4419 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4420 * to offer rates that are not applicable anyway. */
4421
4422testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004423 /* Try to include 12,2k in into the active set even though the channel
4424 * is half rate only. The BSC is expected to remove the 12,0k */
4425 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004426 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004427}
4428
4429testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004430 /* See what happens when all rates are selected at once. Since then
4431 * Also S1 is selected, this setting will be prefered and we should
4432 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4433 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004434 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004435}
4436
4437testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004438 /* Same as above, but with S1 missing, the MSC is then expected to
4439 * select the currently supported rates, which are also 12.2k, 7,40k,
4440 * 5,90k, and 4,75k, into the active set. */
4441 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004442 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004443}
4444
4445testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004446 /* Try to select no rates at all */
4447 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004448 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004449}
4450
4451testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004452 /* Try to select only unsupported rates */
4453 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004454 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004455}
4456
4457testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004458 /* Try to select 12,2k for half rate */
4459 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004460 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004461}
4462
Neels Hofmeyr21863562020-11-26 00:34:33 +00004463testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4464 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4465 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004466 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004467}
4468
4469testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4470 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4471 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004472 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004473}
4474
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004475testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004476 /* "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 +00004477 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4478 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004479 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004480}
4481
4482testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004483 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4484 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004485 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004486 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004487}
4488
Philipp Maierac09bfc2019-01-08 13:41:39 +01004489private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004490 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4491 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4492 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4493 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004494}
4495
4496private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004497 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4498 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004499}
4500
4501private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004502 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4503 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4504 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4505 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4506 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4507 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004508}
4509
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004510private function f_disable_all_sdcch() runs on test_CT {
4511 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4512 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4513 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4514 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4515}
4516
4517private function f_enable_all_sdcch() runs on test_CT {
4518 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4519 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4520 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4521 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4522}
4523
Philipp Maierac09bfc2019-01-08 13:41:39 +01004524/* Allow HR only */
4525private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4526 g_pars := f_gen_test_hdlr_pars();
4527 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4528 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4529 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4530 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4531 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4532 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4533 f_establish_fully(ass_cmd, exp_compl);
4534}
4535
4536/* Allow FR only */
4537private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4538 g_pars := f_gen_test_hdlr_pars();
4539 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4540 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4541 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4542 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4543 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4544 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4545 f_establish_fully(ass_cmd, exp_compl);
4546}
4547
4548/* Allow HR only (expect assignment failure) */
4549private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4550 g_pars := f_gen_test_hdlr_pars();
4551 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4552 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4553 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4554 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4555 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4556 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4557 f_establish_fully(ass_cmd, exp_fail);
4558}
4559
4560/* Allow FR only (expect assignment failure) */
4561private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4562 g_pars := f_gen_test_hdlr_pars();
4563 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4564 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4565 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4566 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4567 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4568 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4569 f_establish_fully(ass_cmd, exp_fail);
4570}
4571
4572/* Allow FR and HR, but prefer FR */
4573private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4574 g_pars := f_gen_test_hdlr_pars();
4575 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4576 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4577 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4578 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4579 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4580 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4581 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4582 f_establish_fully(ass_cmd, exp_compl);
4583}
4584
4585/* Allow FR and HR, but prefer HR */
4586private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4587 g_pars := f_gen_test_hdlr_pars();
4588 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4589 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4590 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4591 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4592 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4593 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4594 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4595 f_establish_fully(ass_cmd, exp_compl);
4596}
4597
4598/* Allow FR and HR, but prefer FR */
4599private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4600 g_pars := f_gen_test_hdlr_pars();
4601 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4602 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4603 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4604 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4605 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4606 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4607 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4608 f_establish_fully(ass_cmd, exp_compl);
4609}
4610
4611/* Allow FR and HR, but prefer HR */
4612private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4613 g_pars := f_gen_test_hdlr_pars();
4614 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4615 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4616 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4617 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4618 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4619 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4620 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4621 f_establish_fully(ass_cmd, exp_compl);
4622}
4623
4624/* Request a HR channel while all FR channels are exhausted, this is expected
4625 * to work without conflicts */
4626testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4627 var MSC_ConnHdlr vc_conn;
4628 f_init(1, true);
4629 f_sleep(1.0);
4630 f_enable_all_tch();
4631 f_disable_all_tch_f();
4632 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4633 vc_conn.done;
4634 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004635 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004636}
4637
4638/* Request a FR channel while all FR channels are exhausted, this is expected
4639 * to fail. */
4640testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4641 var MSC_ConnHdlr vc_conn;
4642 f_init(1, true);
4643 f_sleep(1.0);
4644 f_enable_all_tch();
4645 f_disable_all_tch_f();
4646 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4647 vc_conn.done;
4648 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004649 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004650}
4651
4652/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4653 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4654testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4655 var MSC_ConnHdlr vc_conn;
4656 f_init(1, true);
4657 f_sleep(1.0);
4658 f_enable_all_tch();
4659 f_disable_all_tch_f();
4660 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4661 vc_conn.done;
4662 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004663 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004664}
4665
4666/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4667 * are exhausted, this is expected to work without conflicts. */
4668testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4669 var MSC_ConnHdlr vc_conn;
4670 f_init(1, true);
4671 f_sleep(1.0);
4672 f_enable_all_tch();
4673 f_disable_all_tch_f();
4674 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4675 vc_conn.done;
4676 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004677 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004678}
4679
4680/* Request a FR channel while all HR channels are exhausted, this is expected
4681 * to work without conflicts */
4682testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4683 var MSC_ConnHdlr vc_conn;
4684 f_init(1, true);
4685 f_sleep(1.0);
4686 f_enable_all_tch();
4687 f_disable_all_tch_h();
4688 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4689 vc_conn.done;
4690 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004691 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004692}
4693
4694/* Request a HR channel while all HR channels are exhausted, this is expected
4695 * to fail. */
4696testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4697 var MSC_ConnHdlr vc_conn;
4698 f_init(1, true);
4699 f_sleep(1.0);
4700 f_enable_all_tch();
4701 f_disable_all_tch_h();
4702 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4703 vc_conn.done;
4704 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004705 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004706}
4707
4708/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4709 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4710testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4711 var MSC_ConnHdlr vc_conn;
4712 f_init(1, true);
4713 f_sleep(1.0);
4714 f_enable_all_tch();
4715 f_disable_all_tch_h();
4716 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4717 vc_conn.done;
4718 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004719 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004720}
4721
4722/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4723 * are exhausted, this is expected to work without conflicts. */
4724testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4725 var MSC_ConnHdlr vc_conn;
4726 f_init(1, true);
4727 f_sleep(1.0);
4728 f_enable_all_tch();
4729 f_disable_all_tch_h();
4730 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4731 vc_conn.done;
4732 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004733 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004734}
4735
4736/* Allow FR and HR, but prefer HR */
4737private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4738 g_pars := f_gen_test_hdlr_pars();
4739 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4740 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4741 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4742 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4743 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4744 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4745 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4746 f_establish_fully(ass_cmd, exp_compl);
4747}
4748
4749/* Allow FR and HR, but prefer FR */
4750private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4751 g_pars := f_gen_test_hdlr_pars();
4752 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4753 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4754 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4755 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4756 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4757 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4758 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4759 f_establish_fully(ass_cmd, exp_compl);
4760}
4761
4762/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4763 * HR, which is the prefered type, is selected. */
4764testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4765 var MSC_ConnHdlr vc_conn;
4766 f_init(1, true);
4767 f_sleep(1.0);
4768 f_enable_all_tch();
4769 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4770 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004771 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004772}
4773
4774/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4775 * FR, which is the prefered type, is selected. */
4776testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4777 var MSC_ConnHdlr vc_conn;
4778 f_init(1, true);
4779 f_sleep(1.0);
4780 f_enable_all_tch();
4781 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4782 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004783 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004784}
4785
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004786/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4787private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4788 g_pars := f_gen_test_hdlr_pars();
4789 g_pars.ra := '02'O; /* RA containing reason=LU */
4790
4791 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4792 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4793 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4794 var template uint3_t tsc := ?;
4795
4796 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4797 f_create_bssmap_exp(l3_enc);
4798 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4799 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4800
4801 /* we should now have a COMPL_L3 at the MSC */
4802 timer T := 10.0;
4803 T.start;
4804 alt {
4805 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4806 [] T.timeout {
4807 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4808 }
4809 }
4810}
4811testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4812 var MSC_ConnHdlr vc_conn;
4813 f_init(1, true);
4814 f_sleep(1.0);
4815 f_disable_all_sdcch();
4816 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4817 vc_conn.done;
4818 f_enable_all_sdcch();
4819 f_shutdown_helper();
4820}
4821
4822/* Request a signalling channel with all SDCCH exhausted, it is
4823 expected that no TCH will be selected for signalling and assigment will fail
4824 because it's dictated by VTY config */
4825testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4826 var RSL_Message rsl_unused, rsl_msg;
4827 var GsmRrMessage rr;
4828 f_init(1, false);
4829 f_sleep(1.0);
4830 f_vty_allow_tch_for_signalling(false, 0);
4831 f_disable_all_sdcch();
4832
4833 /* RA containing reason=LU */
4834 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4835 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4836 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4837 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4838 setverdict(fail, "Expected reject");
4839 }
4840
4841 f_vty_allow_tch_for_signalling(true, 0);
4842 f_enable_all_sdcch();
4843 f_shutdown_helper();
4844}
4845
4846/* Request a voice channel with all SDCCH exhausted, it is
4847 * expected that TCH channel will be allocated since the VTY option is only
4848 * aimed at signalling requests */
4849private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4850 g_pars := f_gen_test_hdlr_pars();
4851 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4852
4853 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4854 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4855 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4856 var template uint3_t tsc := ?;
4857
4858 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4859 f_create_bssmap_exp(l3_enc);
4860 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4861 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4862
4863 /* we should now have a COMPL_L3 at the MSC */
4864 timer T := 10.0;
4865 T.start;
4866 alt {
4867 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4868 [] T.timeout {
4869 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4870 }
4871 }
4872}
4873testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4874 var MSC_ConnHdlr vc_conn;
4875 f_init(1, true);
4876 f_sleep(1.0);
4877 f_vty_allow_tch_for_signalling(false, 0);
4878 f_disable_all_sdcch();
4879
4880 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4881 vc_conn.done;
4882
4883 f_vty_allow_tch_for_signalling(true, 0);
4884 f_enable_all_sdcch();
4885 f_shutdown_helper();
4886}
4887
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004888testcase TC_assignment_osmux() runs on test_CT {
4889 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4890 var MSC_ConnHdlr vc_conn;
4891
4892 /* See note above */
4893 var RSL_IE_Body mr_conf := {
4894 other := {
4895 len := 2,
4896 payload := '2804'O
4897 }
4898 };
4899
4900 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4901 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4902 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4903 pars.expect_mr_conf_ie := mr_conf;
4904 pars.use_osmux := true;
4905
4906 f_init(1, true, true);
4907 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004908 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004909
4910 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4911 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004912
4913 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004914 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004915}
4916
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004917/* test the procedure of the MSC requesting a Classmark Update:
4918 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4919 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004920private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004921 g_pars := f_gen_test_hdlr_pars();
4922
Harald Weltea0630032018-03-20 21:09:55 +01004923 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004924 /* we should now have a COMPL_L3 at the MSC */
4925 BSSAP.receive(tr_BSSMAP_ComplL3);
4926
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004927 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4928 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4929
Harald Welte898113b2018-01-31 18:32:21 +01004930 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4931 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4932 setverdict(pass);
4933}
4934testcase TC_classmark() runs on test_CT {
4935 var MSC_ConnHdlr vc_conn;
4936 f_init(1, true);
4937 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004938 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004939 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004940 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004941}
4942
Harald Welteeddf0e92020-06-21 19:42:15 +02004943/* Send a CommonID from the simulated MSC and verify that the information is used to
4944 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4945private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4946 g_pars := f_gen_test_hdlr_pars();
4947 f_MscConnHdlr_init_vty();
4948
4949 f_create_chan_and_exp();
4950 /* we should now have a COMPL_L3 at the MSC */
4951 BSSAP.receive(tr_BSSMAP_ComplL3);
4952
4953 /* Send CommonID */
4954 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4955
4956 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4957 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4958 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4959
4960 setverdict(pass);
4961}
4962testcase TC_common_id() runs on test_CT {
4963 var MSC_ConnHdlr vc_conn;
4964 f_init(1, true);
4965 f_sleep(1.0);
4966 vc_conn := f_start_handler(refers(f_tc_common_id));
4967 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004968 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004969}
4970
Harald Weltee3bd6582018-01-31 22:51:25 +01004971private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004972 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004973 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004974 /* we should now have a COMPL_L3 at the MSC */
4975 BSSAP.receive(tr_BSSMAP_ComplL3);
4976
Harald Weltee3bd6582018-01-31 22:51:25 +01004977 /* send the single message we want to send */
4978 f_rsl_send_l3(l3);
4979}
4980
4981private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4982 timer T := sec;
4983 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004984 T.start;
4985 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004986 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4987 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004988 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004989 }
4990 [] T.timeout {
4991 setverdict(pass);
4992 }
4993 }
4994}
4995
Harald Weltee3bd6582018-01-31 22:51:25 +01004996/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4997private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4998 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4999 f_bssap_expect_nothing();
5000}
Harald Welte898113b2018-01-31 18:32:21 +01005001testcase TC_unsol_ass_fail() runs on test_CT {
5002 var MSC_ConnHdlr vc_conn;
5003 f_init(1, true);
5004 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005005 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005006 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005007 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005008}
Harald Welte552620d2017-12-16 23:21:36 +01005009
Harald Welteea99a002018-01-31 20:46:43 +01005010
5011/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5012private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005013 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5014 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01005015}
5016testcase TC_unsol_ass_compl() runs on test_CT {
5017 var MSC_ConnHdlr vc_conn;
5018 f_init(1, true);
5019 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005020 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005021 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005022 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005023}
5024
5025
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005026/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5027private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005028 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5029 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005030}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005031testcase TC_unsol_ho_fail() runs on test_CT {
5032 var MSC_ConnHdlr vc_conn;
5033 f_init(1, true);
5034 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005035 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005036 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005037 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005038}
5039
5040
Harald Weltee3bd6582018-01-31 22:51:25 +01005041/* short message from MS should be ignored */
5042private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005043 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005044 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005045 /* we should now have a COMPL_L3 at the MSC */
5046 BSSAP.receive(tr_BSSMAP_ComplL3);
5047
5048 /* send short message */
5049 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5050 f_bssap_expect_nothing();
5051}
5052testcase TC_err_82_short_msg() runs on test_CT {
5053 var MSC_ConnHdlr vc_conn;
5054 f_init(1, true);
5055 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005056 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005057 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005058 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005059}
5060
5061
Harald Weltee9e02e42018-01-31 23:36:25 +01005062/* 24.008 8.4 Unknown message must trigger RR STATUS */
5063private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5064 f_est_single_l3(ts_RRM_UL_REL('00'O));
5065 timer T := 3.0
5066 alt {
5067 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5068 setverdict(pass);
5069 }
5070 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005071 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005072 }
5073}
5074testcase TC_err_84_unknown_msg() runs on test_CT {
5075 var MSC_ConnHdlr vc_conn;
5076 f_init(1, true);
5077 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005078 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005079 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005080 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005081}
5082
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005083/***********************************************************************
5084 * Handover
5085 ***********************************************************************/
5086
Harald Welte94e0c342018-04-07 11:33:23 +02005087/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5088private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5089runs on test_CT {
5090 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5091 " timeslot "&int2str(ts_nr)&" ";
5092 f_vty_transceive(BSCVTY, cmd & suffix);
5093}
5094
Harald Welte261af4b2018-02-12 21:20:39 +01005095/* 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 +07005096private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5097 uint8_t bts_nr, uint8_t trx_nr,
5098 in RslChannelNr chan_nr)
5099{
Harald Welte261af4b2018-02-12 21:20:39 +01005100 /* FIXME: resolve those from component-global state */
5101 var integer ts_nr := chan_nr.tn;
5102 var integer ss_nr;
5103 if (ischosen(chan_nr.u.ch0)) {
5104 ss_nr := 0;
5105 } else if (ischosen(chan_nr.u.lm)) {
5106 ss_nr := chan_nr.u.lm.sub_chan;
5107 } else if (ischosen(chan_nr.u.sdcch4)) {
5108 ss_nr := chan_nr.u.sdcch4.sub_chan;
5109 } else if (ischosen(chan_nr.u.sdcch8)) {
5110 ss_nr := chan_nr.u.sdcch8.sub_chan;
5111 } else {
5112 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005113 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005114 }
5115
5116 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5117 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005118 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005119}
5120
Neels Hofmeyr91401012019-07-11 00:42:35 +02005121/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5122 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5123 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5124 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5125 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005126private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5127 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5128{
5129 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005130}
5131
5132/* intra-BSC hand-over between BTS0 and BTS1 */
5133private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005134 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5135 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005136
5137 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5138 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5139
Harald Weltea0630032018-03-20 21:09:55 +01005140 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005141 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005142
5143 var HandoverState hs := {
5144 rr_ho_cmpl_seen := false,
5145 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005146 old_chan_nr := -,
5147 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005148 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005149 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005150 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005151 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5152 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005153
5154 /* From the MGW perspective, a handover is is characterized by
5155 * performing one MDCX operation with the MGW. So we expect to see
5156 * one more MDCX during handover. */
5157 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5158
Harald Welte261af4b2018-02-12 21:20:39 +01005159 alt {
5160 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005161 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005162
Philipp Maier4dae0652018-11-12 12:03:26 +01005163 /* Since this is an internal handover we expect the BSC to inform the
5164 * MSC about the event */
5165 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5166
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005167 /* Check the amount of MGCP transactions is still consistant with the
5168 * test expectation */
5169 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005170
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005171 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5172
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005173 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5174 * 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 +02005175 f_verify_encr_info(chan_act);
5176
5177 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005178
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005179 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005180}
5181
5182testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005183 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005184 var MSC_ConnHdlr vc_conn;
5185 f_init(2, true);
5186 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005187
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005188 pars.expect_tsc := BTS_TSC[0];
5189
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005190 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005191
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005192 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005193 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005194
5195 /* from f_establish_fully() */
5196 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5197 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5198 /* from handover */
5199 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5200 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5201 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5202 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005203 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5204 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005205 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005206 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005207}
Harald Weltee9e02e42018-01-31 23:36:25 +01005208
Oliver Smith7eabd312021-07-12 14:18:56 +02005209function 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 +02005210 var MSC_ConnHdlr vc_conn;
5211 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5212 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5213
5214 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005215 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005216 f_sleep(1.0);
5217
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005218 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005219
5220 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5221 vc_conn.done;
5222
5223 /* from f_establish_fully() */
5224 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5225 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5226 /* from handover */
5227 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5228 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5229 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5230 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005231 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5232 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005233 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005234 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005235 f_shutdown_helper();
5236}
5237
5238testcase TC_ho_int_a5_0() runs on test_CT {
5239 f_tc_ho_int_a5('01'O);
5240}
5241
5242testcase TC_ho_int_a5_1() runs on test_CT {
5243 f_tc_ho_int_a5('02'O);
5244}
5245
5246testcase TC_ho_int_a5_3() runs on test_CT {
5247 f_tc_ho_int_a5('08'O);
5248}
5249
5250testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005251 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005252}
5253
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005254/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5255private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5256 g_pars := f_gen_test_hdlr_pars();
5257 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5258 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005259
5260 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5261 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5262
5263 f_establish_fully(ass_cmd, exp_compl);
5264 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5265
5266 var HandoverState hs := {
5267 rr_ho_cmpl_seen := false,
5268 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005269 old_chan_nr := -,
5270 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005271 };
5272 /* issue hand-over command on VTY */
5273 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5274 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5275 f_rslem_suspend(RSL1_PROC);
5276
5277 /* From the MGW perspective, a handover is is characterized by
5278 * performing one MDCX operation with the MGW. So we expect to see
5279 * one more MDCX during handover. */
5280 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5281
5282 var RSL_Message rsl;
5283 var PDU_ML3_NW_MS l3;
5284 var RslChannelNr new_chan_nr;
5285 var GsmArfcn arfcn;
5286 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5287 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5288 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5289 setverdict(fail, "Expected handoverCommand");
5290 mtc.stop;
5291 }
5292 }
5293 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5294 new_chan_nr, arfcn);
5295
5296 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5297
5298 /* resume processing of RSL DChan messages, which was temporarily suspended
5299 * before performing a hand-over */
5300 f_rslem_resume(RSL1_PROC);
5301 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5302
5303 f_sleep(1.0);
5304
5305 /* Handover fails because no HANDO DET appears on the new lchan,
5306 * and the old lchan reports a Radio Link Failure. */
5307 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5308
5309 var PDU_BSSAP rx_clear_request;
5310 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5311 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5312 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5313
5314 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5315
5316 var MgcpCommand mgcp;
5317 interleave {
5318 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5319 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005320 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005321 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005322 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005323 }
5324 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005325 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005326 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005327 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005328 }
5329 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5330 }
5331
5332 f_sleep(0.5);
5333 setverdict(pass);
5334}
5335testcase TC_ho_int_radio_link_failure() runs on test_CT {
5336 var MSC_ConnHdlr vc_conn;
5337 f_init(2, true);
5338 f_sleep(1.0);
5339
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005340 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005341
5342 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5343 vc_conn.done;
5344
5345 /* from f_establish_fully() */
5346 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5347 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5348 /* from handover */
5349 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5350 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5351 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5352 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005353 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5354 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005355 f_ctrs_bsc_and_bts_verify();
5356 f_shutdown_helper();
5357}
5358
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005359/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005360private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005361 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005362 var template MgcpResponse mgcp_resp;
5363 var MGCP_RecvFrom mrf;
5364 var template MgcpMessage msg_resp;
5365 var template MgcpMessage msg_dlcx := {
5366 command := tr_DLCX()
5367 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005368
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005369 if (g_pars.aoip) {
5370 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005371 log("Got first DLCX: ", mgcp);
5372 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005373 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005374
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005375 MGCP.receive(tr_DLCX()) -> value mgcp {
5376 log("Got second DLCX: ", mgcp);
5377 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5378 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005379 } else {
5380 /* For SCCPLite, BSC doesn't handle the MSC-side */
5381 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5382 log("Got first DLCX: ", mrf.msg.command);
5383 msg_resp := {
5384 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5385 }
5386 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5387 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005388 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005389}
5390
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005391private 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 +01005392
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005393 var NcellReports neighbor_rep := {
5394 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5395 };
5396 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5397 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5398 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005399
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005400 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005401
5402 f_sleep(0.5);
5403 /* The MSC negotiates Handover Request and Handover Request Ack with
5404 * the other BSS and comes back with a BSSMAP Handover Command
5405 * containing an RR Handover Command coming from the target BSS... */
5406
5407 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5408 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5409 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5410 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5411 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5412
5413 /* expect the Handover Command to go out on RR */
5414 var RSL_Message rsl_ho_cmd
5415 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5416 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5417 var RSL_IE_Body rsl_ho_cmd_l3;
5418 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5419 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5420 setverdict(fail);
5421 } else {
5422 log("Found L3 Info: ", rsl_ho_cmd_l3);
5423 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5424 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5425 setverdict(fail);
5426 } else {
5427 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5428 setverdict(pass);
5429 }
5430 }
5431
5432 /* When the other BSS has reported a completed handover, this side is
5433 * torn down. */
5434
5435 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5436 var BssmapCause cause := enum2int(cause_val);
5437 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5438
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005439 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005440
5441 interleave {
5442 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5443 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5444 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005445 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005446 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005447 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005448}
5449
5450private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5451 g_pars := f_gen_test_hdlr_pars();
5452 var PDU_BSSAP ass_req := f_gen_ass_req();
5453 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5454 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5455 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5456 f_establish_fully(ass_req, exp_compl);
5457
5458 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005459}
5460testcase TC_ho_out_of_this_bsc() runs on test_CT {
5461 var MSC_ConnHdlr vc_conn;
5462
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005463 f_init_vty();
5464 f_bts_0_cfg(BSCVTY,
5465 {"neighbor-list mode automatic",
5466 "handover 1",
5467 "handover algorithm 2",
5468 "handover2 window rxlev averaging 1",
5469 "neighbor lac 99 arfcn 123 bsic any"});
5470 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5471
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005472 f_init(1, true);
5473 f_sleep(1.0);
5474
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005475 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005476
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005477 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5478 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005479
5480 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5481 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5482 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5483 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5484 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5485 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5486 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005487 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005488}
5489
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005490private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5491 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005492 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005493 octetstring l3 := '0123456789'O)
5494runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005495 /* The old lchan and conn should still be active. See that arbitrary L3
5496 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005497 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005498 var template PDU_BSSAP exp_data := {
5499 discriminator := '1'B,
5500 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005501 dlci := dlci,
5502 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005503 pdu := {
5504 dtap := l3
5505 }
5506 };
5507 BSSAP.receive(exp_data);
5508 setverdict(pass);
5509}
5510
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005511private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5512 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005513 template (value) OCT1 dlci := '00'O,
5514 octetstring l3 := '0123456789'O)
5515runs on MSC_ConnHdlr {
5516 BSSAP.send(PDU_BSSAP:{
5517 discriminator := '1'B,
5518 spare := '0000000'B,
5519 dlci := dlci,
5520 lengthIndicator := lengthof(l3),
5521 pdu := {
5522 dtap := l3
5523 }
5524 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005525 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005526 setverdict(pass);
5527}
5528
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005529/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5530 * simply never sends a BSSMAP Handover Command. */
5531private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005532 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005533
5534 var PDU_BSSAP ass_req := f_gen_ass_req();
5535 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5536 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5537 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5538 f_establish_fully(ass_req, exp_compl);
5539
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005540 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005541 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5542
5543 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5544
5545 /* osmo-bsc should time out 10 seconds after the handover started.
5546 * Let's give it a bit extra. */
5547 f_sleep(15.0);
5548
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005549 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005550 f_sleep(1.0);
5551}
5552testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5553 var MSC_ConnHdlr vc_conn;
5554
5555 f_init(1, true);
5556 f_sleep(1.0);
5557
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005558 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005559
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005560 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5561 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005562
5563 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5564 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5565 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5566 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5567 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5568 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5569 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005570 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005571}
5572
5573/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5574 * RR Handover Failure. */
5575private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005576 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005577
5578 var PDU_BSSAP ass_req := f_gen_ass_req();
5579 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5580 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5581 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5582 f_establish_fully(ass_req, exp_compl);
5583
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005584 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005585 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5586
5587 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5588
5589 f_sleep(0.5);
5590 /* The MSC negotiates Handover Request and Handover Request Ack with
5591 * the other BSS and comes back with a BSSMAP Handover Command
5592 * containing an RR Handover Command coming from the target BSS... */
5593
5594 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5595 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5596 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5597 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5598 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5599
5600 /* expect the Handover Command to go out on RR */
5601 var RSL_Message rsl_ho_cmd
5602 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5603 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5604 var RSL_IE_Body rsl_ho_cmd_l3;
5605 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5606 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5607 setverdict(fail);
5608 } else {
5609 log("Found L3 Info: ", rsl_ho_cmd_l3);
5610 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5611 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5612 setverdict(fail);
5613 } else {
5614 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5615 setverdict(pass);
5616 }
5617 }
5618
5619 f_sleep(0.2);
5620 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5621
5622 /* Should tell the MSC about the failure */
5623 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5624
5625 f_sleep(1.0);
5626
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005627 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005628 f_sleep(1.0);
5629
5630 setverdict(pass);
5631 f_sleep(1.0);
5632}
5633testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5634 var MSC_ConnHdlr vc_conn;
5635
5636 f_init(1, true);
5637 f_sleep(1.0);
5638
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005639 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005640
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005641 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5642 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005643
5644 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5645 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5646 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5647 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5648 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5649 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5650 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005651 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005652}
5653
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005654/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5655 * (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 +02005656 * and the lchan is released. */
5657private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005658 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005659
5660 var PDU_BSSAP ass_req := f_gen_ass_req();
5661 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5662 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5663 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5664 f_establish_fully(ass_req, exp_compl);
5665
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005666 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005667 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5668
5669 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5670
5671 f_sleep(0.5);
5672 /* The MSC negotiates Handover Request and Handover Request Ack with
5673 * the other BSS and comes back with a BSSMAP Handover Command
5674 * containing an RR Handover Command coming from the target BSS... */
5675
5676 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5677 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5678 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5679 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5680 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5681
5682 /* expect the Handover Command to go out on RR */
5683 var RSL_Message rsl_ho_cmd
5684 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5685 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5686 var RSL_IE_Body rsl_ho_cmd_l3;
5687 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5688 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5689 setverdict(fail);
5690 } else {
5691 log("Found L3 Info: ", rsl_ho_cmd_l3);
5692 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5693 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5694 setverdict(fail);
5695 } else {
5696 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5697 setverdict(pass);
5698 }
5699 }
5700
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005701 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5702 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5703 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005704
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005705 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005706 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5707 log("Got BSSMAP Clear Request");
5708 /* Instruct BSC to clear channel */
5709 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5710 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5711
5712 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005713 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005714 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5715 log("Got Deact SACCH");
5716 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005717 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005718 log("Got RR Release");
5719 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005720 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005721 log("Got RF Chan Rel");
5722 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005723 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005724 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005725 }
5726
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005727 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005728 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005729
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005730 setverdict(pass);
5731 f_sleep(1.0);
5732}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005733testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005734 var MSC_ConnHdlr vc_conn;
5735
5736 f_init(1, true);
5737 f_sleep(1.0);
5738
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005739 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005740
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005741 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005742 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005743
5744 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5745 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5746 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5747 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5748 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5749 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5750 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005751 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005752}
5753
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005754private function f_ho_into_this_bsc(charstring id, template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005755 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5756 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5757 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5758 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5759 * before we get started. */
5760 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5761 f_rslem_register(0, new_chan_nr);
5762 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005763 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005764 f_sleep(1.0);
5765
5766 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5767 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5768 activate(as_Media());
5769
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005770 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005771 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005772 oldToNewBSSIEs := oldToNewBSSIEs,
5773 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005774 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005775
5776 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5777
5778 var PDU_BSSAP rx_bssap;
5779 var octetstring ho_command_str;
5780
5781 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005782
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005783 /* we're sure that the channel activation is done now, verify the parameters in it */
5784 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
5785 f_verify_encr_info(chan_act);
5786 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005787
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005788 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5789 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5790 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5791 log("L3 Info in HO Request Ack is ", ho_command);
5792
5793 var GsmArfcn arfcn;
5794 var RslChannelNr actual_new_chan_nr;
5795 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5796 actual_new_chan_nr, arfcn);
5797
5798 if (actual_new_chan_nr != new_chan_nr) {
5799 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5800 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5801 setverdict(fail);
5802 return;
5803 }
5804 log("Handover Command chan_nr is", actual_new_chan_nr);
5805
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005806 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
5807 if (not match(got_tsc, expect_target_tsc)) {
5808 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
5809 expect_target_tsc, " got ", got_tsc);
5810 mtc.stop;
5811 } else {
5812 log("handoverCommand: verified TSC = ", got_tsc);
5813 }
5814
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005815 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5816 * tells the MS to handover to the new lchan. Here comes the new MS on
5817 * the new lchan with a Handover RACH: */
5818
5819 /* send handover detect */
5820
5821 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5822
5823 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5824
5825 /* send handover complete over the new channel */
5826
5827 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5828 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5829 enc_PDU_ML3_MS_NW(l3_tx)));
5830
5831 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005832 setverdict(pass);
5833}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005834
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005835private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005836 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005837 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5838 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5839 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005840 }
5841 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005842 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005843 } else {
5844 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005845 }
5846 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005847 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005848 setverdict(pass);
5849}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005850function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005851 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005852
5853 f_init(1, true);
5854 f_sleep(1.0);
5855
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005856 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005857
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005858 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5859 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005860
5861 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5862 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005863
5864 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5865 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5866 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5867 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5868 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005869}
5870
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005871testcase TC_ho_into_this_bsc() runs on test_CT {
5872 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5873 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005874 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005875}
5876
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005877function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5878 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5879 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5880 f_tc_ho_into_this_bsc_main(pars);
5881 f_shutdown_helper();
5882}
5883
5884testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5885 f_tc_ho_into_this_bsc_a5('01'O);
5886}
5887
5888testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5889 f_tc_ho_into_this_bsc_a5('02'O);
5890}
5891
5892testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5893 f_tc_ho_into_this_bsc_a5('08'O);
5894}
5895
5896testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5897 f_tc_ho_into_this_bsc_a5('10'O);
5898}
5899
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005900testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5901 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5902 pars.host_aoip_tla := "::6";
5903 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005904 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005905}
5906
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005907/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005908 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005909 channel is later released (RR CHannel Release), should trigger inclusion of
5910 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5911 neighbors. */
5912testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5913 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5914 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005915 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005916 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005917
5918 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5919 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5920 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005921 f_shutdown_helper();
5922}
5923
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005924/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5925 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5926 list when the channel is released. */
5927testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5928 f_init_vty();
5929 f_vty_allow_srvcc_fast_return(true, 0)
5930
5931 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5932 pars.last_used_eutran_plmn := '323454'O;
5933 pars.exp_fast_return := false;
5934 f_tc_ho_into_this_bsc_main(pars);
5935 f_vty_allow_srvcc_fast_return(false, 0);
5936 f_shutdown_helper();
5937}
5938
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005939private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5940 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5941 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5942 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5943 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5944 setverdict(pass);
5945}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005946
5947private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5948 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005949 var MSC_ConnHdlr vc_conn;
5950 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5951
5952 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005953 if (disable_fast_return) {
5954 f_vty_allow_srvcc_fast_return(true, 0);
5955 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005956 f_sleep(1.0);
5957
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005958 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005959
5960 pars.last_used_eutran_plmn := '323454'O;
5961 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5962 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5963
5964 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5965 vc_conn.done;
5966
5967 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5968 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5969 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5970 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5971 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5972 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005973
5974 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5975 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005976 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005977
5978 if (disable_fast_return) {
5979 f_vty_allow_srvcc_fast_return(false, 0);
5980 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005981 f_shutdown_helper();
5982}
5983
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005984/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5985 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5986 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5987 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5988testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5989 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5990}
5991/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5992 * independently of fast-reture allowed/forbidden in local BTS */
5993testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5994 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5995}
5996
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005997private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5998 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5999 f_rslem_register(0, new_chan_nr);
6000 g_chan_nr := new_chan_nr;
6001 f_sleep(1.0);
6002
6003 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6004 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6005 activate(as_Media());
6006
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006007 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006008 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006009 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006010
6011 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6012
6013 var PDU_BSSAP rx_bssap;
6014 var octetstring ho_command_str;
6015
6016 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6017
6018 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6019 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6020 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6021 log("L3 Info in HO Request Ack is ", ho_command);
6022
6023 var GsmArfcn arfcn;
6024 var RslChannelNr actual_new_chan_nr;
6025 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6026 actual_new_chan_nr, arfcn);
6027
6028 if (actual_new_chan_nr != new_chan_nr) {
6029 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6030 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6031 setverdict(fail);
6032 return;
6033 }
6034 log("Handover Command chan_nr is", actual_new_chan_nr);
6035
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006036 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6037 f_sleep(1.0);
6038
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006039 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6040 * tells the MS to handover to the new lchan. In this case, the MS
6041 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6042 * Handover Failure to the MSC. The procedure according to 3GPP TS
6043 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6044 * BSSMAP Clear Command: */
6045
6046 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6047 var BssmapCause cause := enum2int(cause_val);
6048 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6049
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006050 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006051 BSSAP.receive(tr_BSSMAP_ClearComplete);
6052
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006053 setverdict(pass);
6054 f_sleep(1.0);
6055
6056 setverdict(pass);
6057}
6058testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6059 var MSC_ConnHdlr vc_conn;
6060 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6061
6062 f_init(1, true);
6063 f_sleep(1.0);
6064
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006065 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006066
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006067 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6068 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006069
6070 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6071 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006072
6073 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6074 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6075 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6076 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6077 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006078 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006079}
6080
6081private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6082 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6083 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6084 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6085 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6086 * before we get started. */
6087 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6088 f_rslem_register(0, new_chan_nr);
6089 g_chan_nr := new_chan_nr;
6090 f_sleep(1.0);
6091
6092 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6093 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6094 activate(as_Media());
6095
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006096 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006097 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006098 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006099
6100 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6101
6102 var PDU_BSSAP rx_bssap;
6103 var octetstring ho_command_str;
6104
6105 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6106
6107 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6108 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6109 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6110 log("L3 Info in HO Request Ack is ", ho_command);
6111
6112 var GsmArfcn arfcn;
6113 var RslChannelNr actual_new_chan_nr;
6114 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6115 actual_new_chan_nr, arfcn);
6116
6117 if (actual_new_chan_nr != new_chan_nr) {
6118 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6119 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6120 setverdict(fail);
6121 return;
6122 }
6123 log("Handover Command chan_nr is", actual_new_chan_nr);
6124
6125 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6126 * tells the MS to handover to the new lchan. Here comes the new MS on
6127 * the new lchan with a Handover RACH: */
6128
6129 /* send handover detect */
6130
6131 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6132
6133 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6134
6135 /* The MSC chooses to clear the connection now, maybe we got the
6136 * Handover RACH on the new cell but the MS still signaled Handover
6137 * Failure to the old BSS? */
6138
6139 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6140 var BssmapCause cause := enum2int(cause_val);
6141 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6142
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006143 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006144 BSSAP.receive(tr_BSSMAP_ClearComplete);
6145
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006146 f_sleep(1.0);
6147}
6148testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6149 var MSC_ConnHdlr vc_conn;
6150 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6151
6152 f_init(1, true);
6153 f_sleep(1.0);
6154
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006155 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006156
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006157 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6158 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006159
6160 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6161 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006162
6163 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6164 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6165 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6166 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6167 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006168 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006169}
6170
6171/* The new BSS's lchan times out before the MSC decides that handover failed. */
6172private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6173 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6174 f_rslem_register(0, new_chan_nr);
6175 g_chan_nr := new_chan_nr;
6176 f_sleep(1.0);
6177
6178 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6179 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6180 activate(as_Media());
6181
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006182 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006183 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006184 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006185
6186 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6187
6188 var PDU_BSSAP rx_bssap;
6189 var octetstring ho_command_str;
6190
6191 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6192
6193 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6194 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6195 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6196 log("L3 Info in HO Request Ack is ", ho_command);
6197
6198 var GsmArfcn arfcn;
6199 var RslChannelNr actual_new_chan_nr;
6200 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6201 actual_new_chan_nr, arfcn);
6202
6203 if (actual_new_chan_nr != new_chan_nr) {
6204 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6205 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6206 setverdict(fail);
6207 return;
6208 }
6209 log("Handover Command chan_nr is", actual_new_chan_nr);
6210
6211 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6212 * tells the MS to handover to the new lchan. But the MS never shows up
6213 * on the new lchan. */
6214
6215 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6216
6217 /* Did osmo-bsc also send a Clear Request? */
6218 timer T := 0.5;
6219 T.start;
6220 alt {
6221 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6222 [] T.timeout { }
6223 }
6224
6225 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6226 * asked for it, this is a Handover Failure after all). */
6227
6228 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6229 var BssmapCause cause := enum2int(cause_val);
6230 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6231
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006232 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006233 BSSAP.receive(tr_BSSMAP_ClearComplete);
6234
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006235 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006236}
6237testcase TC_ho_in_fail_no_detect() runs on test_CT {
6238 var MSC_ConnHdlr vc_conn;
6239 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6240
6241 f_init(1, true);
6242 f_sleep(1.0);
6243
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006244 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006245
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006246 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6247 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006248
6249 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6250 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006251
6252 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6253 f_ctrs_bsc_and_bts_add(0, "handover:error");
6254 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6255 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6256 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006257 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006258}
6259
6260/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6261private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6262 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6263 f_rslem_register(0, new_chan_nr);
6264 g_chan_nr := new_chan_nr;
6265 f_sleep(1.0);
6266
6267 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6268 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6269 activate(as_Media());
6270
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006271 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006272 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006273 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006274
6275 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6276
6277 var PDU_BSSAP rx_bssap;
6278 var octetstring ho_command_str;
6279
6280 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6281
6282 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6283 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6284 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6285 log("L3 Info in HO Request Ack is ", ho_command);
6286
6287 var GsmArfcn arfcn;
6288 var RslChannelNr actual_new_chan_nr;
6289 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6290 actual_new_chan_nr, arfcn);
6291
6292 if (actual_new_chan_nr != new_chan_nr) {
6293 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6294 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6295 setverdict(fail);
6296 return;
6297 }
6298 log("Handover Command chan_nr is", actual_new_chan_nr);
6299
6300 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6301 * tells the MS to handover to the new lchan. But the MS never shows up
6302 * on the new lchan. */
6303
6304 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6305
6306 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006307 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006308
6309 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006310 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6311 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6312 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006313 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006314 BSSAP.receive(tr_BSSMAP_ClearComplete);
6315
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006316 f_sleep(1.0);
6317}
6318testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6319 var MSC_ConnHdlr vc_conn;
6320 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6321
6322 f_init(1, true);
6323 f_sleep(1.0);
6324
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006325 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006326
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006327 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6328 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006329
6330 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6331 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006332
6333 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6334 f_ctrs_bsc_and_bts_add(0, "handover:error");
6335 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6336 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6337 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006338 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006339}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006340
Neels Hofmeyr91401012019-07-11 00:42:35 +02006341type record of charstring Commands;
6342
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006343private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006344{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006345 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006346 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006347 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006348 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006349 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006350}
6351
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006352private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6353{
6354 f_vty_enter_cfg_cs7_inst(pt, 0);
6355 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6356 f_vty_transceive(pt, cmds[i]);
6357 }
6358 f_vty_transceive(pt, "end");
6359}
6360
Neels Hofmeyr91401012019-07-11 00:42:35 +02006361private function f_probe_for_handover(charstring log_label,
6362 charstring log_descr,
6363 charstring handover_vty_cmd,
6364 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006365 boolean is_inter_bsc_handover := false,
6366 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006367runs on MSC_ConnHdlr
6368{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006369 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6370 * lchans to be established on bts 1 or bts 2. */
6371 f_rslem_suspend(RSL1_PROC);
6372 f_rslem_suspend(RSL2_PROC);
6373
Neels Hofmeyr91401012019-07-11 00:42:35 +02006374 var RSL_Message rsl;
6375
6376 var charstring log_msg := " (expecting handover)"
6377 if (not expect_handover) {
6378 log_msg := " (expecting NO handover)";
6379 }
6380 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6381 f_vty_transceive(BSCVTY, handover_vty_cmd);
6382
Neels Hofmeyr91401012019-07-11 00:42:35 +02006383 timer T := 2.0;
6384 T.start;
6385
6386 alt {
6387 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6388 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6389 log("Rx L3 from net: ", l3);
6390 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6391 var RslChannelNr new_chan_nr;
6392 var GsmArfcn arfcn;
6393 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6394 new_chan_nr, arfcn);
6395 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6396 log(l3.msgs.rrm.handoverCommand);
6397
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006398 /* Verify correct TSC in handoverCommand */
6399 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6400 if (not match(got_tsc, expect_target_tsc)) {
6401 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6402 expect_target_tsc, " got ", got_tsc);
6403 mtc.stop;
6404 } else {
6405 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6406 expect_target_tsc, ")");
6407 }
6408
Neels Hofmeyr91401012019-07-11 00:42:35 +02006409 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6410 * matter on which BTS it really is, we're not going to follow through an entire handover
6411 * anyway. */
6412 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6413 f_rslem_resume(RSL1_PROC);
6414 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6415 f_rslem_resume(RSL2_PROC);
6416
6417 if (expect_handover and not is_inter_bsc_handover) {
6418 setverdict(pass);
6419 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6420 } else {
6421 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6422 & log_label & ": " & log_descr);
6423 }
6424
6425 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6426 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6427 * Handover Failure. */
6428 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6429
6430 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6431 f_sleep(0.5);
6432 RSL1.clear;
6433 RSL2.clear;
6434 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6435 break;
6436 } else {
6437 repeat;
6438 }
6439 }
6440 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6441 if (expect_handover and is_inter_bsc_handover) {
6442 setverdict(pass);
6443 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6444 } else {
6445 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6446 & log_label & ": " & log_descr);
6447 }
6448
6449 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6450
6451 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6452 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6453 * setting a short timeout and waiting is the only way. */
6454 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6455 f_sleep(1.5);
6456 log("f_probe_for_handover(" & log_label & "): ...done");
6457
6458 break;
6459 }
6460 [] T.timeout {
6461 if (expect_handover) {
6462 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6463 & log_label & ": " & log_descr);
6464 } else {
6465 setverdict(pass);
6466 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6467 }
6468 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6469 break;
6470 }
6471 }
6472
6473 f_rslem_resume(RSL1_PROC);
6474 f_rslem_resume(RSL2_PROC);
6475 f_sleep(3.0);
6476 RSL.clear;
6477
6478 log("f_probe_for_handover(" & log_label & "): done clearing");
6479}
6480
6481/* Test the effect of various neighbor configuration scenarios:
6482 *
6483 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6484 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6485 */
6486private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6487 g_pars := f_gen_test_hdlr_pars();
6488 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6489 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006490
6491 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6492 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6493
6494 /* Establish lchan at bts 0 */
6495 f_establish_fully(ass_cmd, exp_compl);
6496
6497 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6498 f_vty_enter_cfg_network(BSCVTY);
6499 f_vty_transceive(BSCVTY, "timer T7 1");
6500 f_vty_transceive(BSCVTY, "end");
6501}
6502
6503private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6504 f_tc_ho_neighbor_config_start();
6505
6506 /*
6507 * bts 0 ARFCN 871 BSIC 10
6508 * bts 1 ARFCN 871 BSIC 11
6509 * bts 2 ARFCN 871 BSIC 12
6510 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6511 */
6512
6513 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006514 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006515 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6516 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006517 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006518
6519 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6520 "handover any to arfcn 13 bsic 39",
6521 false);
6522
6523 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6524 "handover any to arfcn 871 bsic 12",
6525 false);
6526
6527 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6528 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006529 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006530}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006531testcase TC_ho_neighbor_config_1() runs on test_CT {
6532 var MSC_ConnHdlr vc_conn;
6533 f_init(3, true, guard_timeout := 60.0);
6534 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006535 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006536 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6537 vc_conn.done;
6538
6539 /* f_tc_ho_neighbor_config_start() */
6540 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6541 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6542
6543 /* 1.a */
6544 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6545 * handover quickly by sending a Handover Failure message. */
6546 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6547 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6548 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6549 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006550 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6551 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006552
6553 /* 1.b */
6554 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6555 f_ctrs_bsc_and_bts_add(0, "handover:error");
6556
6557 /* 1.c */
6558 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6559 f_ctrs_bsc_and_bts_add(0, "handover:error");
6560
6561 /* 1.d */
6562 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6563 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6564 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6565 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006566 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6567 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006568
6569 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006570 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006571}
6572
Neels Hofmeyr91401012019-07-11 00:42:35 +02006573private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6574 f_tc_ho_neighbor_config_start();
6575
6576 /*
6577 * bts 0 ARFCN 871 BSIC 10
6578 * bts 1 ARFCN 871 BSIC 11
6579 * bts 2 ARFCN 871 BSIC 12
6580 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6581 */
6582
6583 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006584 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006585 f_sleep(0.5);
6586
6587 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6588 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006589 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006590
6591 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6592 "handover any to arfcn 871 bsic 12",
6593 false);
6594}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006595testcase TC_ho_neighbor_config_2() runs on test_CT {
6596 var MSC_ConnHdlr vc_conn;
6597 f_init(3, true, guard_timeout := 50.0);
6598 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006599 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006600 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6601 vc_conn.done;
6602
6603 /* f_tc_ho_neighbor_config_start() */
6604 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6605 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6606
6607 /* 2.a */
6608 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6609 * handover quickly by sending a Handover Failure message. */
6610 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6611 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6612 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6613 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006614 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6615 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006616
6617 /* 2.b */
6618 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6619 f_ctrs_bsc_and_bts_add(0, "handover:error");
6620
6621 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006622 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006623}
6624
Neels Hofmeyr91401012019-07-11 00:42:35 +02006625private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6626 f_tc_ho_neighbor_config_start();
6627
6628 /*
6629 * bts 0 ARFCN 871 BSIC 10
6630 * bts 1 ARFCN 871 BSIC 11
6631 * bts 2 ARFCN 871 BSIC 12
6632 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6633 */
6634
6635 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006636 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006637 f_sleep(0.5);
6638
6639 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6640 "handover any to arfcn 871 bsic 11",
6641 false);
6642 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",
6643 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006644 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006645}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006646testcase TC_ho_neighbor_config_3() runs on test_CT {
6647 var MSC_ConnHdlr vc_conn;
6648 f_init(3, true, guard_timeout := 50.0);
6649 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006650 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006651 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6652 vc_conn.done;
6653
6654 /* f_tc_ho_neighbor_config_start() */
6655 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6656 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6657
6658 /* 3.a */
6659 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6660 f_ctrs_bsc_and_bts_add(0, "handover:error");
6661
6662 /* 3.b */
6663 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6664 * handover quickly by sending a Handover Failure message. */
6665 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6666 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6667 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6668 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006669 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
6670 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006671
6672 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006673 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006674}
6675
Neels Hofmeyr91401012019-07-11 00:42:35 +02006676private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6677 f_tc_ho_neighbor_config_start();
6678
6679 /*
6680 * bts 0 ARFCN 871 BSIC 10
6681 * bts 1 ARFCN 871 BSIC 11
6682 * bts 2 ARFCN 871 BSIC 12
6683 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6684 */
6685
6686 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006687 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006688 f_sleep(0.5);
6689
6690 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6691 "handover any to arfcn 871 bsic 11",
6692 false);
6693 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6694 "handover any to arfcn 871 bsic 12",
6695 false);
6696 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6697 "handover any to arfcn 123 bsic 45",
6698 true, true);
6699}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006700testcase TC_ho_neighbor_config_4() runs on test_CT {
6701 var MSC_ConnHdlr vc_conn;
6702 f_init(3, true, guard_timeout := 50.0);
6703 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006704 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006705 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6706 vc_conn.done;
6707
6708 /* f_tc_ho_neighbor_config_start() */
6709 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6710 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6711
6712 /* 4.a */
6713 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6714 f_ctrs_bsc_and_bts_add(0, "handover:error");
6715
6716 /* 4.b */
6717 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6718 f_ctrs_bsc_and_bts_add(0, "handover:error");
6719
6720 /* 4.c */
6721 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6722 * handover quickly by timing out after the Handover Required message */
6723 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6724 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6725 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6726 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6727
6728 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006729 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006730}
6731
Neels Hofmeyr91401012019-07-11 00:42:35 +02006732private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6733 f_tc_ho_neighbor_config_start();
6734
6735 /*
6736 * bts 0 ARFCN 871 BSIC 10
6737 * bts 1 ARFCN 871 BSIC 11
6738 * bts 2 ARFCN 871 BSIC 12
6739 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6740 */
6741
6742 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 +02006743 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006744 f_sleep(0.5);
6745
6746 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6747 "handover any to arfcn 871 bsic 12",
6748 true, true);
6749}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006750testcase TC_ho_neighbor_config_5() runs on test_CT {
6751 var MSC_ConnHdlr vc_conn;
6752 f_init(3, true);
6753 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006754 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006755 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6756 vc_conn.done;
6757
6758 /* f_tc_ho_neighbor_config_start() */
6759 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6760 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6761
6762 /* 5 */
6763 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6764 * handover quickly by timing out after the Handover Required message */
6765 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6766 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6767 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6768 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6769
6770 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006771 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006772}
6773
Neels Hofmeyr91401012019-07-11 00:42:35 +02006774private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6775 f_tc_ho_neighbor_config_start();
6776
6777 /*
6778 * bts 0 ARFCN 871 BSIC 10
6779 * bts 1 ARFCN 871 BSIC 11
6780 * bts 2 ARFCN 871 BSIC 12
6781 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6782 */
6783
6784 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6785 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006786 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006787 f_sleep(0.5);
6788
6789 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6790 "handover any to arfcn 871 bsic 12",
6791 false);
6792}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006793testcase TC_ho_neighbor_config_6() runs on test_CT {
6794 var MSC_ConnHdlr vc_conn;
6795 f_init(3, true);
6796 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006797 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006798 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6799 vc_conn.done;
6800
6801 /* f_tc_ho_neighbor_config_start() */
6802 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6803 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6804
6805 /* 6.a */
6806 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6807 * handover quickly by timing out after the Handover Required message */
6808 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6809 f_ctrs_bsc_and_bts_add(0, "handover:error");
6810
6811 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006812 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006813}
6814
Neels Hofmeyr91401012019-07-11 00:42:35 +02006815private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6816 f_tc_ho_neighbor_config_start();
6817
6818 /*
6819 * bts 0 ARFCN 871 BSIC 10
6820 * bts 1 ARFCN 871 BSIC 11
6821 * bts 2 ARFCN 871 BSIC 12
6822 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6823 */
6824
6825 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6826 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006827 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006828 f_sleep(0.5);
6829
6830 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6831 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006832 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006833 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6834 "handover any to arfcn 123 bsic 45",
6835 true, true);
6836}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006837testcase TC_ho_neighbor_config_7() runs on test_CT {
6838 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006839 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006840 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006841 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006842 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6843 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006844
6845 /* f_tc_ho_neighbor_config_start() */
6846 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6847 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6848
6849 /* 7.a */
6850 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6851 * handover quickly by sending a Handover Failure message. */
6852 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6853 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6854 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6855 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006856 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
6857 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006858
6859 /* 7.b */
6860 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6861 * handover quickly by timing out after the Handover Required message */
6862 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6863 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6864 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6865 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6866
6867 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006868 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006869}
6870
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006871/* OS#3041: Open and close N connections in a normal fashion, and expect no
6872 * BSSMAP Reset just because of that. */
6873testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6874 var default d;
6875 var integer i;
6876 var DchanTuple dt;
6877
6878 f_init();
6879
6880 /* Wait for initial BSSMAP Reset to pass */
6881 f_sleep(4.0);
6882
6883 d := activate(no_bssmap_reset());
6884
6885 /* Setup up a number of connections and RLSD them again from the MSC
6886 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6887 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006888 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006889 /* Since we're doing a lot of runs, give each one a fresh
6890 * T_guard from the top. */
6891 T_guard.start;
6892
6893 /* Setup a BSSAP connection and clear it right away. This is
6894 * the MSC telling the BSC about a planned release, it's not an
6895 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006896 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006897
6898 /* MSC disconnects (RLSD). */
6899 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6900 }
6901
6902 /* In the buggy behavior, a timeout of 2 seconds happens between above
6903 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6904 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6905 f_sleep(4.0);
6906
6907 deactivate(d);
6908 f_shutdown_helper();
6909}
Harald Welte552620d2017-12-16 23:21:36 +01006910
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006911/* OS#3041: Open and close N connections in a normal fashion, and expect no
6912 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6913 * the MSC. */
6914testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6915 var default d;
6916 var integer i;
6917 var DchanTuple dt;
6918 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006919 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6920 var BssmapCause cause := enum2int(cause_val);
6921
6922 f_init();
6923
6924 /* Wait for initial BSSMAP Reset to pass */
6925 f_sleep(4.0);
6926
6927 d := activate(no_bssmap_reset());
6928
6929 /* Setup up a number of connections and RLSD them again from the MSC
6930 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6931 * Let's do it some more times for good measure. */
6932 for (i := 0; i < 8; i := i+1) {
6933 /* Since we're doing a lot of runs, give each one a fresh
6934 * T_guard from the top. */
6935 T_guard.start;
6936
6937 /* Setup a BSSAP connection and clear it right away. This is
6938 * the MSC telling the BSC about a planned release, it's not an
6939 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006940 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006941
6942 /* Instruct BSC to clear channel */
6943 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6944
6945 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006946 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006947 }
6948
6949 /* In the buggy behavior, a timeout of 2 seconds happens between above
6950 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6951 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6952 f_sleep(4.0);
6953
6954 deactivate(d);
6955 f_shutdown_helper();
6956}
6957
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006958/* OS#3041: Open and close N connections in a normal fashion, and expect no
6959 * BSSMAP Reset just because of that. Close connections from the MS side with a
6960 * Release Ind on RSL. */
6961testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6962 var default d;
6963 var integer i;
6964 var DchanTuple dt;
6965 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006966 var integer j;
6967
6968 f_init();
6969
6970 /* Wait for initial BSSMAP Reset to pass */
6971 f_sleep(4.0);
6972
6973 d := activate(no_bssmap_reset());
6974
6975 /* Setup up a number of connections and RLSD them again from the MSC
6976 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6977 * Let's do it some more times for good measure. */
6978 for (i := 0; i < 8; i := i+1) {
6979 /* Since we're doing a lot of runs, give each one a fresh
6980 * T_guard from the top. */
6981 T_guard.start;
6982
6983 /* Setup a BSSAP connection and clear it right away. This is
6984 * the MSC telling the BSC about a planned release, it's not an
6985 * erratic loss of a connection. */
6986 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6987
6988 /* simulate RLL REL IND */
6989 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6990
6991 /* expect Clear Request on MSC side */
6992 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6993
6994 /* Instruct BSC to clear channel */
6995 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6996 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6997
6998 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006999 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007000 }
7001
7002 /* In the buggy behavior, a timeout of 2 seconds happens between above
7003 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7004 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7005 f_sleep(4.0);
7006
7007 deactivate(d);
7008 f_shutdown_helper();
7009}
7010
Harald Welte94e0c342018-04-07 11:33:23 +02007011/***********************************************************************
7012 * IPA style dynamic PDCH
7013 ***********************************************************************/
7014
7015private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7016 template (omit) RSL_Cause nack := omit)
7017runs on test_CT {
7018 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7019 var RSL_Message rsl_unused;
7020 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7021 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7022 /* expect the BSC to issue the related RSL command */
7023 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7024 if (istemplatekind(nack, "omit")) {
7025 /* respond with a related acknowledgement */
7026 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7027 } else {
7028 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
7029 }
7030}
7031
7032private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7033 template (omit) RSL_Cause nack := omit)
7034runs on test_CT {
7035 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7036 var RSL_Message rsl_unused;
7037 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7038 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7039 /* expect the BSC to issue the related RSL command */
7040 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
7041 if (istemplatekind(nack, "omit")) {
7042 /* respond with a related acknowledgement */
7043 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
7044 } else {
7045 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
7046 }
7047}
7048
7049private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7050runs on test_CT return charstring {
7051 var charstring cmd, resp;
7052 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007053 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007054}
7055
7056private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7057 template charstring exp)
7058runs on test_CT {
7059 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7060 if (not match(mode, exp)) {
7061 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007062 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007063 }
7064}
7065
7066private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7067runs on test_CT {
7068 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7069 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7070 f_vty_transceive(BSCVTY, "end");
7071}
7072
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007073
7074private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7075 var integer i;
7076 for (i := 0; i < 8; i := i + 1) {
7077 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7078 }
7079}
7080
Harald Welte94e0c342018-04-07 11:33:23 +02007081private const charstring TCHF_MODE := "TCH/F mode";
7082private const charstring TCHH_MODE := "TCH/H mode";
7083private const charstring PDCH_MODE := "PDCH mode";
7084private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007085private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007086
7087/* Test IPA PDCH activation / deactivation triggered by VTY */
7088testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7089 var RSL_Message rsl_unused;
7090
7091 /* change Timeslot 6 before f_init() starts RSL */
7092 f_init_vty();
7093 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7094 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7095
7096 f_init(1, false);
7097 f_sleep(1.0);
7098
7099 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7100
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007101 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007102 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7103 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7104 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7105 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7106 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007107 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007108 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7109
7110 /* De-activate it via VTY */
7111 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7112 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007113 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007114 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7115
7116 /* re-activate it via VTY */
7117 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7118 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007119 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007120 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7121
7122 /* and finally de-activate it again */
7123 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7124 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007125 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007126 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7127
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007128 /* clean up config */
7129 f_ts_set_chcomb(0, 0, 6, "PDCH");
7130
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007131 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007132}
7133
7134/* Test IPA PDCH activation NACK */
7135testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7136 var RSL_Message rsl_unused;
7137
7138 /* change Timeslot 6 before f_init() starts RSL */
7139 f_init_vty();
7140 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7141 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7142
7143 f_init(1, false);
7144 f_sleep(1.0);
7145
7146 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7147
7148 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7149 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7150 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7151 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7152 f_sleep(1.0);
7153 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7154
7155 /* De-activate it via VTY */
7156 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7157 f_sleep(1.0);
7158 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7159
7160 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7161 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7162 f_sleep(1.0);
7163 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7164
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007165 /* clean up config */
7166 f_ts_set_chcomb(0, 0, 6, "PDCH");
7167
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007168 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007169}
7170
7171
7172/***********************************************************************
7173 * Osmocom style dynamic PDCH
7174 ***********************************************************************/
7175
7176private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7177 template (omit) RSL_Cause nack := omit)
7178runs on test_CT {
7179 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7180 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007181 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007182 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7183 /* expect the BSC to issue the related RSL command */
7184 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7185 if (istemplatekind(nack, "omit")) {
7186 /* respond with a related acknowledgement */
7187 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7188 } else {
7189 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7190 }
7191}
7192
7193private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7194 template (omit) RSL_Cause nack := omit)
7195runs on test_CT {
7196 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7197 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007198 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007199 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7200 /* expect the BSC to issue the related RSL command */
7201 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7202 if (istemplatekind(nack, "omit")) {
7203 /* respond with a related acknowledgement */
7204 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7205 } else {
7206 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7207 }
7208}
7209
7210/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7211testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7212 var RSL_Message rsl_unused;
7213
7214 /* change Timeslot 6 before f_init() starts RSL */
7215 f_init_vty();
7216 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7217 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7218
7219 f_init(1, false);
7220 f_sleep(1.0);
7221
7222 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7223
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007224 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007225 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7226 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7227 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7228
7229 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7230 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007231 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 +02007232 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7233
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007234 /* clean up config */
7235 f_ts_set_chcomb(0, 0, 6, "PDCH");
7236
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007237 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007238}
7239
7240/* Test Osmocom dyn PDCH activation NACK behavior */
7241testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7242 var RSL_Message rsl_unused;
7243
7244 /* change Timeslot 6 before f_init() starts RSL */
7245 f_init_vty();
7246 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7247 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7248
7249 f_init(1, false);
7250 f_sleep(1.0);
7251
7252 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7253
7254 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7255 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7256 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7257
7258 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7259 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7260 f_sleep(1.0);
7261 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7262
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007263 /* clean up config */
7264 f_ts_set_chcomb(0, 0, 6, "PDCH");
7265
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007266 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007267}
7268
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007269/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7270testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7271 var RSL_Message rsl_unused, rsl_msg;
7272 var DchanTuple dt;
7273 var BSSAP_N_CONNECT_ind rx_c_ind;
7274
7275 /* change Timeslot 6 before f_init() starts RSL */
7276 f_init_vty();
7277 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7278 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7279
7280 f_init(1, false);
7281 f_sleep(1.0);
7282
7283 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7284
7285 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7286 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7287 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7288 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7289
7290 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7291 f_sleep(1.0);
7292 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7293 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7294
7295 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7296 * on CCCH+SDCCH4+CBCH) */
7297 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007298 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007299 dt := f_est_dchan('23'O, i, '00010203040506'O);
7300 }
7301
7302 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7303 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7304 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7305 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7306
7307 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7308 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7309
7310 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7311 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7312 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7313 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7314
7315 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7316 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7317 dt.sccp_conn_id := rx_c_ind.connectionId;
7318 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7319
7320 /* Instruct BSC to clear channel */
7321 var BssmapCause cause := 0;
7322 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7323 f_exp_chan_rel_and_clear(dt, 0);
7324
7325 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7326 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7327 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7328 f_sleep(1.0);
7329 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7330
7331 /* clean up config */
7332 f_ts_set_chcomb(0, 0, 6, "PDCH");
7333
7334 f_shutdown_helper();
7335}
7336
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007337/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7338testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7339 var ASP_RSL_Unitdata rsl_ud;
7340 var integer i;
7341 var integer chreq_total, chreq_nochan;
7342
7343 f_init_vty();
7344 for (i := 1; i < 8; i := i + 1) {
7345 if (i == 2) {
7346 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7347 } else {
7348 f_ts_set_chcomb(0, 0, i, "PDCH");
7349 }
7350 }
7351 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7352
7353 f_init(1);
7354
7355 /* The dyn TS want to activate PDCH mode, ACK that. */
7356 var RslChannelNr chan_nr;
7357 chan_nr := valueof(t_RslChanNr_PDCH(2));
7358 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7359 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7360
7361 f_sleep(1.0);
7362
7363 /* Exhaust all dedicated SDCCH lchans.
7364 /* GSM 44.018 Table 9.1.8.2:
7365 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7366 */
7367 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
7368 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7369 }
7370
7371 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
7372 f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7373 /* Also occupy the seven other SDCCH of the dyn TS */
7374 for (i := 0; i < 7; i := i+1) {
7375 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7376 }
7377
7378 /* clean up config */
7379 f_ts_reset_chcomb(0);
7380
7381 f_shutdown_helper();
7382}
7383
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007384/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7385 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7386 it as TCH directly instead. SYS#5309. */
7387testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7388 var RSL_Message rsl_unused, rsl_msg;
7389 var DchanTuple dt;
7390 var BSSAP_N_CONNECT_ind rx_c_ind;
7391 var integer i;
7392
7393 /* change Timeslot 6 before f_init() starts RSL */
7394 f_init_vty();
7395 for (i := 1; i < 8; i := i + 1) {
7396 if (i == 6) {
7397 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7398 } else {
7399 f_ts_set_chcomb(0, 0, i, "PDCH");
7400 }
7401 }
7402 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7403
7404 f_init(1, false);
7405 f_sleep(1.0);
7406
7407 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7408
7409 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7410 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7411 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7412 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7413
7414 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7415 f_sleep(1.0);
7416 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7417 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7418
7419 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7420 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007421 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007422 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007423 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007424 }
7425
7426 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007427 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007428 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7429 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7430
7431 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7432 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7433
7434 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7435 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7436 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7437 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7438
7439 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7440 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7441 dt.sccp_conn_id := rx_c_ind.connectionId;
7442 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7443
7444 /* Instruct BSC to clear channel */
7445 var BssmapCause cause := 0;
7446 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7447 f_exp_chan_rel_and_clear(dt, 0);
7448
7449 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7450 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7451 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7452 f_sleep(1.0);
7453 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7454
7455 /* clean up config */
7456 f_ts_reset_chcomb(0);
7457 /* TODO: clean up other channels? */
7458
7459 f_shutdown_helper();
7460}
7461
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007462/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7463testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7464 var RSL_Message rsl_unused, rsl_msg;
7465 var DchanTuple dt;
7466 var BSSAP_N_CONNECT_ind rx_c_ind;
7467 var GsmRrMessage rr;
7468
7469 /* change Timeslot 6 before f_init() starts RSL */
7470 f_init_vty();
7471 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7472 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7473
7474 f_init(1, false);
7475 f_sleep(1.0);
7476
7477 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7478
7479 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7480 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7481 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7482 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7483
7484 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7485 f_sleep(1.0);
7486 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7487 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7488
7489 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7490 * on CCCH+SDCCH4+CBCH) */
7491 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007492 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007493 dt := f_est_dchan('23'O, i, '00010203040506'O);
7494 }
7495
7496 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7497 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7498 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7499 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7500
7501 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7502 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7503
7504 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7505 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7506 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7507 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7508 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7509 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7510 }
7511
7512 /* FIXME? Currently the TS stays in state BORKEN: */
7513
7514 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7515 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7516 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7517 * f_sleep(1.0);
7518 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7519 */
7520
7521 /* clean up config */
7522 f_ts_set_chcomb(0, 0, 6, "PDCH");
7523
7524 f_shutdown_helper();
7525}
7526
Stefan Sperling0796a822018-10-05 13:01:39 +02007527testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007528 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007529 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7530 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7531 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007532 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007533}
7534
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007535testcase TC_chopped_ipa_payload() runs on test_CT {
7536 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7537 /* TODO: mp_bsc_ctrl_port does not work yet */};
7538 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7539 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7540 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007541 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007542}
7543
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007544/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7545 the BTS does autonomous MS power control loop */
7546testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7547 var MSC_ConnHdlr vc_conn;
7548 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7549 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7550 pars.exp_ms_power_params := true;
7551
7552 f_init(1, true);
7553 f_sleep(1.0);
7554 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7555 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007556 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007557}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007558
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007559/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7560testcase TC_c0_power_red_mode() runs on test_CT {
7561 f_init(1);
7562
7563 for (var integer red := 6; red >= 0; red := red - 2) {
7564 /* Configure BCCH carrier power reduction mode via the VTY */
7565 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7566
7567 /* Expect Osmocom specific BS Power Control message on the RSL */
7568 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7569 chan_nr := t_RslChanNr_BCCH(0),
7570 bs_power := tr_RSL_IE_BS_Power(red / 2));
7571 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7572 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7573
7574 /* Additionally verify the applied value over the CTRL interface */
7575 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7576 if (cred != int2str(red)) {
7577 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7578 cred, " (expected ", red, ")");
7579 }
7580 }
7581
7582 f_shutdown_helper();
7583}
7584
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007585/***********************************************************************
7586 * MSC Pooling
7587 ***********************************************************************/
7588
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007589template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007590 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 +02007591
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007592private 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 +02007593runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007594 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007595 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007596 f_logp(BSCVTY, "Got RSL RR Release");
7597 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007598 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007599 f_logp(BSCVTY, "Got RSL Deact SACCH");
7600 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007601 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007602 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007603 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7604 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007605 break;
7606 }
7607 }
7608}
7609
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007610friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7611 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007612runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007613 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007614 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7615 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007616 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007617 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007618 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007619 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007620 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007621 }
7622 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007623 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007624 /* Also drop the SCCP connection */
7625 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7626 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007627 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007628 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007629 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7630 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007631 }
7632 }
7633}
7634
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007635private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7636 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007637runs on MSC_ConnHdlr {
7638 timer T := 10.0;
7639 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7640
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007641 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007642 f_create_bssmap_exp(l3_enc);
7643
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007644 /* RSL_Emulation.f_chan_est() on rsl_pt:
7645 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007646 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7647 */
7648 var RSL_Message rx_rsl;
7649 var GsmRrMessage rr;
7650
7651 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007652 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007653 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007654 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007655 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7656 */
7657 timer Tt := 10.0;
7658
7659 /* request a channel to be established */
7660 Tt.start;
7661 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007662 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007663 Tt.stop;
7664 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007665 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007666 setverdict(fail, "Unexpected RSL message on DCHAN");
7667 mtc.stop;
7668 }
7669 [] Tt.timeout {
7670 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7671 mtc.stop;
7672 }
7673 }
7674 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7675 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007676 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007677
7678
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007679 if (expect_bssmap_l3) {
7680 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7681 var template PDU_BSSAP exp_l3_compl;
7682 exp_l3_compl := tr_BSSMAP_ComplL3()
7683 if (g_pars.aoip == false) {
7684 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7685 } else {
7686 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7687 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007688
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007689 var PDU_BSSAP bssap;
7690 T.start;
7691 alt {
7692 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7693 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7694 log("rx exp_l3_compl = ", bssap);
7695 }
7696 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7697 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7698 }
7699 [] T.timeout {
7700 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7701 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007702 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007703
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007704 /* start ciphering, if requested */
7705 if (ispresent(g_pars.encr)) {
7706 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007707 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007708 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007709 }
7710
7711 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007712 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007713 }
7714 setverdict(pass);
7715 f_sleep(1.0);
7716}
7717
7718private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7719 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7720 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007721 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007722 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007723 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007724 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007725 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007726 }
7727}
7728
7729/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7730private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7731 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007732 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7733 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7734 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7735 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 +02007736}
7737testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7738
7739 f_init(1, true);
7740 f_sleep(1.0);
7741 var MSC_ConnHdlr vc_conn;
7742 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007743
7744 f_ctrs_msc_init();
7745
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007746 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7747 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007748
7749 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007750 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007751}
7752
7753/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7754/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7755 * just as well using only RSL. */
7756testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7757
7758 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7759 f_sleep(1.0);
7760
7761 /* Control which MSC gets chosen next by the round-robin, otherwise
7762 * would be randomly affected by which other tests ran before this. */
7763 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7764
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007765 f_ctrs_msc_init();
7766
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007767 var MSC_ConnHdlr vc_conn1;
7768 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7769 pars1.mscpool.rsl_idx := 0;
7770 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7771 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7772 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007773 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007774
7775 var MSC_ConnHdlr vc_conn2;
7776 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7777 pars2.mscpool.rsl_idx := 1;
7778 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7779 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7780 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007781 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007782
7783 /* Test round-robin wrap to the first MSC */
7784 var MSC_ConnHdlr vc_conn3;
7785 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7786 pars3.mscpool.rsl_idx := 2;
7787 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7788 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7789 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007790 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007791 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007792}
7793
7794/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7795 * (configured in osmo-bsc.cfg). */
7796/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7797 * just as well using only RSL. */
7798testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7799
7800 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7801 f_sleep(1.0);
7802
7803 /* Control which MSC gets chosen next by the round-robin, otherwise
7804 * would be randomly affected by which other tests ran before this. */
7805 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7806
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007807 f_ctrs_msc_init();
7808
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007809 var MSC_ConnHdlr vc_conn1;
7810 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7811 pars1.mscpool.rsl_idx := 0;
7812 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7813 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7814 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007815 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007816
7817 var MSC_ConnHdlr vc_conn2;
7818 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7819 pars2.mscpool.rsl_idx := 1;
7820 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7821 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7822 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007823 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007824
7825 /* Test round-robin wrap to the first MSC */
7826 var MSC_ConnHdlr vc_conn3;
7827 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7828 pars3.mscpool.rsl_idx := 2;
7829 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7830 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7831 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007832 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007833 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007834}
7835
7836/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7837 * (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
7838 * NULL-NRI setting is stronger than that. */
7839/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7840 * just as well using only RSL. */
7841testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7842
7843 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7844 f_sleep(1.0);
7845
7846 /* Control which MSC gets chosen next by the round-robin, otherwise
7847 * would be randomly affected by which other tests ran before this. */
7848 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7849
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007850 f_ctrs_msc_init();
7851
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007852 var MSC_ConnHdlr vc_conn1;
7853 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7854 pars1.mscpool.rsl_idx := 0;
7855 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7856 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7857 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007858 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007859
7860 var MSC_ConnHdlr vc_conn2;
7861 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7862 pars2.mscpool.rsl_idx := 1;
7863 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7864 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7865 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007866 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007867
7868 /* Test round-robin wrap to the first MSC */
7869 var MSC_ConnHdlr vc_conn3;
7870 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7871 pars3.mscpool.rsl_idx := 2;
7872 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7873 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7874 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007875 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007876 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007877}
7878
7879/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7880 * assigned to any MSC (configured in osmo-bsc.cfg). */
7881/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7882 * just as well using only RSL. */
7883testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7884
7885 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7886 f_sleep(1.0);
7887
7888 /* Control which MSC gets chosen next by the round-robin, otherwise
7889 * would be randomly affected by which other tests ran before this. */
7890 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7891
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007892 f_ctrs_msc_init();
7893
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007894 var MSC_ConnHdlr vc_conn1;
7895 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7896 pars1.mscpool.rsl_idx := 0;
7897 /* An NRI that is not assigned to any MSC */
7898 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7899 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7900 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007901 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007902
7903 var MSC_ConnHdlr vc_conn2;
7904 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7905 pars2.mscpool.rsl_idx := 1;
7906 /* An NRI that is not assigned to any MSC */
7907 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7908 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7909 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007910 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007911
7912 /* Test round-robin wrap to the first MSC */
7913 var MSC_ConnHdlr vc_conn3;
7914 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7915 pars3.mscpool.rsl_idx := 2;
7916 /* An NRI that is not assigned to any MSC */
7917 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7918 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7919 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007920 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007921 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007922}
7923
7924/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7925 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7926/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7927 * just as well using only RSL. */
7928testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7929
7930 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7931 f_sleep(1.0);
7932
7933 /* Control which MSC gets chosen next by the round-robin, otherwise
7934 * would be randomly affected by which other tests ran before this. */
7935 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7936
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007937 f_ctrs_msc_init();
7938
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007939 var MSC_ConnHdlr vc_conn1;
7940 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7941 pars1.mscpool.rsl_idx := 0;
7942 /* An NRI that is assigned to an unconnected MSC */
7943 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7944 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7945 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007946 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7947 f_ctrs_msc_add(0, "mscpool:subscr:new");
7948 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007949
7950 var MSC_ConnHdlr vc_conn2;
7951 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7952 pars2.mscpool.rsl_idx := 1;
7953 /* An NRI that is assigned to an unconnected MSC */
7954 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7955 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7956 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007957 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7958 f_ctrs_msc_add(1, "mscpool:subscr:new");
7959 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007960
7961 /* Test round-robin wrap to the first MSC */
7962 var MSC_ConnHdlr vc_conn3;
7963 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7964 pars3.mscpool.rsl_idx := 2;
7965 /* An NRI that is assigned to an unconnected MSC */
7966 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7967 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7968 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007969 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7970 f_ctrs_msc_add(0, "mscpool:subscr:new");
7971 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007972 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007973}
7974
7975/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7976 * osmo-bsc.cfg). */
7977/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7978 * just as well using only RSL. */
7979testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7980
7981 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7982 f_sleep(1.0);
7983
7984 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7985 * this is not using round-robin. */
7986 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7987
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007988 f_ctrs_msc_init();
7989
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007990 var MSC_ConnHdlr vc_conn1;
7991 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7992 pars1.mscpool.rsl_idx := 0;
7993 /* An NRI of the second MSC's range (256-511) */
7994 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7995 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7996 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007997 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007998
7999 var MSC_ConnHdlr vc_conn2;
8000 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8001 pars2.mscpool.rsl_idx := 1;
8002 /* An NRI of the second MSC's range (256-511) */
8003 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8004 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8005 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008006 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008007
8008 var MSC_ConnHdlr vc_conn3;
8009 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8010 pars3.mscpool.rsl_idx := 2;
8011 /* An NRI of the second MSC's range (256-511) */
8012 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8013 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8014 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008015 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008016 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008017}
8018
8019/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8020 * while a round-robin remains unaffected by that. */
8021/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8022 * just as well using only RSL. */
8023testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8024
8025 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8026 f_sleep(1.0);
8027
8028 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8029 * this is not using round-robin. */
8030 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8031
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008032 f_ctrs_msc_init();
8033
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008034 var MSC_ConnHdlr vc_conn1;
8035 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8036 pars1.mscpool.rsl_idx := 0;
8037 /* An NRI of the third MSC's range (512-767) */
8038 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8039 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8040 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008041 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008042
8043 var MSC_ConnHdlr vc_conn2;
8044 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8045 pars2.mscpool.rsl_idx := 1;
8046 /* An NRI of the third MSC's range (512-767) */
8047 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8048 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8049 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008050 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008051
8052 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8053 var MSC_ConnHdlr vc_conn3;
8054 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8055 pars3.mscpool.rsl_idx := 2;
8056 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8057 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8058 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008059 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008060 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008061}
8062
8063/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8064/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8065 * just as well using only RSL. */
8066testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8067
8068 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8069 f_sleep(1.0);
8070
8071 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8072 * instead, and hits msc 0. */
8073 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8074
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008075 f_ctrs_msc_init();
8076
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008077 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8078 var MSC_ConnHdlr vc_conn1;
8079 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8080 pars1.mscpool.rsl_idx := 0;
8081 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8082 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8083 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008084 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008085
8086 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8087 var MSC_ConnHdlr vc_conn2;
8088 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8089 pars2.mscpool.rsl_idx := 1;
8090 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8091 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8092 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008093 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008094 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008095}
8096
8097/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8098 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8099private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8100 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8101 //cid_list := { cIl_allInBSS := ''O };
8102 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8103 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8104 var BSSAP_N_UNITDATA_req paging;
8105 var hexstring imsi := '001010000000123'H;
8106
8107 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8108
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008109 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008110 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8111 BSSAP.send(paging);
8112
8113 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8114 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8115 * channel number is picked here. */
8116 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8117 f_rslem_register(0, new_chan_nr);
8118 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8119 f_rslem_unregister(0, new_chan_nr);
8120
8121 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8122 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008123 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008124 f_sleep(1.0);
8125}
8126testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8127 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8128 f_sleep(1.0);
8129
8130 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8131 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8132 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8133
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008134 f_ctrs_msc_init();
8135
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008136 var MSC_ConnHdlr vc_conn1;
8137 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8138 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008139 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8140 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008141 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8142 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008143 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008144 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008145}
8146
8147/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8148 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8149private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8150 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8151 //cid_list := { cIl_allInBSS := ''O };
8152 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8153 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8154 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008155 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008156 var BSSAP_N_UNITDATA_req paging;
8157
8158 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8159
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008160 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008161 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8162 BSSAP.send(paging);
8163
8164 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8165 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8166 * channel number is picked here. */
8167 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8168 f_rslem_register(0, new_chan_nr);
8169 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8170 f_rslem_unregister(0, new_chan_nr);
8171
8172 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8173 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8174 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008175 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 +02008176 f_sleep(1.0);
8177}
8178testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8179 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8180 f_sleep(1.0);
8181
8182 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8183 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8184 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8185
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008186 f_ctrs_msc_init();
8187
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008188 var MSC_ConnHdlr vc_conn1;
8189 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8190 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008191 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8192 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008193 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8194 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008195 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008196 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008197}
8198
8199/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8200/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8201 * just as well using only RSL. */
8202testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8203
8204 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8205 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008206 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8207 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008208
8209 /* Control which MSC gets chosen next by the round-robin, otherwise
8210 * would be randomly affected by which other tests ran before this. */
8211 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8212
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008213 f_ctrs_msc_init();
8214
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008215 var MSC_ConnHdlr vc_conn1;
8216 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8217 pars1.mscpool.rsl_idx := 0;
8218 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8219 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8220 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008221 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008222
8223 var MSC_ConnHdlr vc_conn2;
8224 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8225 pars2.mscpool.rsl_idx := 1;
8226 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8227 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8228 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008229 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008230
8231 var MSC_ConnHdlr vc_conn3;
8232 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8233 pars3.mscpool.rsl_idx := 2;
8234 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8235 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8236 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008237 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008238 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008239}
8240
8241/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8242 * TMSI NRI. */
8243testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8244
8245 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8246 f_sleep(1.0);
8247
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008248 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8249 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8250
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008251 /* Control which MSC gets chosen next by the round-robin, otherwise
8252 * would be randomly affected by which other tests ran before this. */
8253 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8254
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008255 f_ctrs_msc_init();
8256
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008257 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8258 var MSC_ConnHdlr vc_conn1;
8259 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8260 pars1.mscpool.rsl_idx := 0;
8261 /* An NRI of the second MSC's range (256-511) */
8262 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8263 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8264 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008265 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008266
8267 var MSC_ConnHdlr vc_conn2;
8268 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8269 pars2.mscpool.rsl_idx := 1;
8270 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8271 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8272 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008273 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008274
8275 var MSC_ConnHdlr vc_conn3;
8276 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8277 pars3.mscpool.rsl_idx := 2;
8278 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8279 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8280 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008281 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008282 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008283}
8284
Philipp Maier783681c2020-07-16 16:47:06 +02008285/* Allow/Deny emergency calls globally via VTY */
8286private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8287 f_vty_enter_cfg_msc(BSCVTY, 0);
8288 if (allow) {
8289 f_vty_transceive(BSCVTY, "allow-emergency allow");
8290 } else {
8291 f_vty_transceive(BSCVTY, "allow-emergency deny");
8292 }
8293 f_vty_transceive(BSCVTY, "exit");
8294 f_vty_transceive(BSCVTY, "exit");
8295}
8296
8297/* Allow/Deny emergency calls per BTS via VTY */
8298private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8299 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8300 if (allow) {
8301 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8302 } else {
8303 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8304 }
8305 f_vty_transceive(BSCVTY, "exit");
8306 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008307 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008308}
8309
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008310/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8311private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8312 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8313 if (allow) {
8314 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8315 } else {
8316 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8317 }
8318 f_vty_transceive(BSCVTY, "exit");
8319 f_vty_transceive(BSCVTY, "exit");
8320 f_vty_transceive(BSCVTY, "exit");
8321}
8322
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008323/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8324private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8325 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8326 if (allow) {
8327 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8328 } else {
8329 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8330 }
8331 f_vty_transceive(BSCVTY, "exit");
8332 f_vty_transceive(BSCVTY, "exit");
8333 f_vty_transceive(BSCVTY, "exit");
8334}
8335
Philipp Maier783681c2020-07-16 16:47:06 +02008336/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8337private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8338 var PDU_ML3_MS_NW emerg_setup;
8339 var octetstring emerg_setup_enc;
8340 var RSL_Message emerg_setup_data_ind;
8341
8342 f_establish_fully(omit, omit);
8343
8344 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8345 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8346 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8347
8348 RSL.send(emerg_setup_data_ind);
8349}
8350
8351/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8352 * CALLS are permitted by the BSC config. */
8353private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8354 var PDU_BSSAP emerg_setup_data_ind_bssap;
8355 var PDU_ML3_MS_NW emerg_setup;
8356 timer T := 3.0;
8357
8358 f_assignment_emerg_setup()
8359
8360 T.start;
8361 alt {
8362 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8363 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8364 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8365 setverdict(fail, "no emergency setup");
8366 }
8367 }
8368 [] BSSAP.receive {
8369 setverdict(fail, "unexpected BSSAP message!");
8370 }
8371 [] T.timeout {
8372 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8373 }
8374 }
8375
8376 setverdict(pass);
8377}
8378
8379/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8380 * forbidden by the BSC config. */
8381private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8382 var PDU_BSSAP emerg_setup_data_ind_bssap;
8383 timer T := 3.0;
8384
8385 f_assignment_emerg_setup()
8386
8387 T.start;
8388 alt {
8389 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8390 setverdict(pass);
8391 }
8392 [] RSL.receive {
8393 setverdict(fail, "unexpected RSL message!");
8394 }
8395 [] T.timeout {
8396 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8397 }
8398 }
8399}
8400
8401/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8402testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8403 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8404 var MSC_ConnHdlr vc_conn;
8405
8406 f_init(1, true);
8407 f_sleep(1.0);
8408
8409 f_vty_allow_emerg_msc(true);
8410 f_vty_allow_emerg_bts(true, 0);
8411 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8412 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008413 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008414}
8415
8416/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8417testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8418 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8419 var MSC_ConnHdlr vc_conn;
8420
8421 f_init(1, true);
8422 f_sleep(1.0);
8423
8424 f_vty_allow_emerg_msc(false);
8425 f_vty_allow_emerg_bts(true, 0);
8426 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8427 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008428 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008429}
8430
8431/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8432testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8433 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8434 var MSC_ConnHdlr vc_conn;
8435
8436 /* Note: This simulates a spec violation by the MS, correct MS
8437 * implementations would not try to establish an emergency call because
8438 * the system information tells in advance that emergency calls are
8439 * not forbidden */
8440
8441 f_init(1, true);
8442 f_sleep(1.0);
8443
8444 f_vty_allow_emerg_msc(true);
8445 f_vty_allow_emerg_bts(false, 0);
8446 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8447 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008448 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008449}
8450
Philipp Maier82812002020-08-13 18:48:27 +02008451/* Test what happens when an emergency call arrives while all TCH channels are
8452 * busy, the BSC is expected to terminate one call in favor of the incoming
8453 * emergency call */
8454testcase TC_emerg_premption() runs on test_CT {
8455 var ASP_RSL_Unitdata rsl_ud;
8456 var integer i;
8457 var integer chreq_total, chreq_nochan;
8458 var RSL_Message rx_rsl;
8459 var RslChannelNr chan_nr;
8460
8461 f_init(1);
8462 f_sleep(1.0);
8463
8464 f_vty_allow_emerg_msc(true);
8465 f_vty_allow_emerg_bts(true, 0);
8466
8467 /* Fill up all channels on the BTS */
8468 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8469 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8470 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8471 chan_nr := f_chreq_act_ack('33'O, i);
8472 }
8473 IPA_RSL[0].clear;
8474 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8475 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8476
8477 /* Send Channel request for emegergency call */
8478 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8479
8480 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8481 chan_nr := valueof(t_RslChanNr_Bm(1));
8482 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8483
8484 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8485 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8486 chan_nr := rx_rsl.ies[0].body.chan_nr;
8487 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8488 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008489
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008490 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008491}
8492
8493/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008494private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008495private type record FHParamsTs {
8496 boolean enabled,
8497 uint6_t hsn,
8498 uint6_t maio,
8499 ArfcnList ma
8500};
8501
8502/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008503private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02008504 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008505 FHParamsTs ts[8]
8506};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008507
8508/* Randomly generate the hopping parameters for the given timeslot numbers */
8509private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8510runs on test_CT return FHParamsTrx {
8511 var FHParamsTrx fhp;
8512
Philipp Maier798d8952021-10-19 14:43:19 +02008513 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
8514 * fall in the GSM900 band. */
8515 fhp.arfcn.arfcn := f_rnd_int(3);
8516 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008517
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008518 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8519 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008520 fhp.ts[tn].enabled := false;
8521 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008522 continue;
8523 }
8524
8525 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008526 fhp.ts[tn].hsn := f_rnd_int(64);
8527 fhp.ts[tn].maio := f_rnd_int(64);
8528 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008529
8530 /* Random Mobile Allocation (hopping channels) */
8531 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8532 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8533 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008534 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008535 }
8536
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008537 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008538 }
8539
8540 log("f_TC_fh_params_gen(): ", fhp);
8541 return fhp;
8542}
8543
8544/* Make sure that the given Channel Description IE matches the hopping configuration */
8545private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8546{
8547 var template (present) ChannelDescription tr_cd;
8548 var template (present) MaioHsn tr_maio_hsn;
8549 var uint3_t tn := cd.chan_nr.tn;
8550
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008551 if (fhp.ts[tn].enabled) {
8552 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008553 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8554 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02008555 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008556 }
8557
8558 if (not match(cd, tr_cd)) {
8559 setverdict(fail, "Channel Description IE does not match: ",
8560 cd, " vs expected ", tr_cd);
8561 }
8562}
8563
8564/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8565private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8566 in MobileAllocationLV ma)
8567{
8568 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8569
8570 if (not match(ma, tr_ma)) {
8571 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8572 tn, "): ", ma, " vs expected: ", tr_ma);
8573 } else {
8574 setverdict(pass);
8575 }
8576}
8577
8578private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8579 in MobileAllocationLV ma)
8580return template MobileAllocationLV {
8581 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008582 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008583 return { len := 0, ma := ''B };
8584 }
8585
8586 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8587 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8588 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008589
8590 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008591 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8592 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8593 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008594 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008595 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008596 }
8597 }
8598
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008599 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02008600 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008601
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008602 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008603 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8604 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008605 }
8606
8607 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008608 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008609 if (full_mask[i] != '1'B)
8610 { continue; }
8611
8612 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8613 if (slot_mask[i] == '1'B) {
8614 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008615 } else {
8616 ma_mask := ma_mask & '0'B;
8617 }
8618 }
8619
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008620 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8621 if (full_mask[0] == '1'B) {
8622 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8623 if (slot_mask[0] == '1'B) {
8624 ma_mask := ma_mask & '1'B;
8625 } else {
8626 ma_mask := ma_mask & '0'B;
8627 }
8628 }
8629
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008630 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008631 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008632 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8633
8634 return { len := ma_mask_len, ma := ma_mask };
8635}
8636
Philipp Maier798d8952021-10-19 14:43:19 +02008637/* Configure the appropriate band for a given arfcn, exc */
8638private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
8639{
8640 var charstring band;
8641 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
8642
8643 select (arfcn_) {
8644 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
8645 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
8646 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
8647 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
8648 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
8649 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
8650 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
8651 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
8652 case else { return; }
8653 }
8654
8655 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8656 f_vty_transceive(BSCVTY, "band " & band);
8657 f_vty_transceive(BSCVTY, "end");
8658}
8659
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008660/* Configure the hopping parameters in accordance with the given record */
8661private function f_TC_fh_params_set(in FHParamsTrx fhp,
8662 uint8_t bts_nr := 0,
8663 uint8_t trx_nr := 0)
8664runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008665
8666 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
8667
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008668 /* Enter the configuration node for the given BTS/TRX numbers */
8669 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8670
Philipp Maier798d8952021-10-19 14:43:19 +02008671 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008672
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008673 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008674 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8675
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008676 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008677 f_vty_transceive(BSCVTY, "hopping enabled 0");
8678 f_vty_transceive(BSCVTY, "exit"); /* go back */
8679 continue;
8680 }
8681
8682 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008683 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8684 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008685
8686 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008687 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8688 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008689 }
8690
8691 f_vty_transceive(BSCVTY, "hopping enabled 1");
8692 f_vty_transceive(BSCVTY, "exit"); /* go back */
8693 }
8694
8695 f_vty_transceive(BSCVTY, "end");
8696}
8697
8698/* Disable frequency hopping on all timeslots */
8699private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8700 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008701 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02008702 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008703runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008704
8705 f_TC_set_band_by_arfcn(bts_nr, arfcn);
8706
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008707 /* Enter the configuration node for the given BTS/TRX numbers */
8708 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8709
Philipp Maier798d8952021-10-19 14:43:19 +02008710 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008711
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008712 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008713 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8714
8715 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008716 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8717 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008718 }
8719
8720 f_vty_transceive(BSCVTY, "hopping enabled 0");
8721 f_vty_transceive(BSCVTY, "exit"); /* go back */
8722 }
8723
8724 f_vty_transceive(BSCVTY, "end");
8725 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8726}
8727
8728/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8729 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8730testcase TC_fh_params_chan_activ() runs on test_CT {
8731 var FHParamsTrx fhp := f_TC_fh_params_gen();
8732 var RSL_Message rsl_msg;
8733 var RSL_IE_Body ie;
8734
8735 f_init_vty();
8736
8737 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8738 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8739
8740 f_init(1);
8741
8742 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8743 for (var integer i := 0; i < 9; i := i + 1) {
8744 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8745 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8746
8747 /* Make sure that Channel Identification IE is present */
8748 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8749 setverdict(fail, "RSL Channel Identification IE is absent");
8750 continue;
8751 }
8752
8753 /* Make sure that hopping parameters (HSN/MAIO) match */
8754 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8755
8756 /* "Mobile Allocation shall be included but empty" - let's check this */
8757 if (ie.chan_ident.ma.v.len != 0) {
8758 setverdict(fail, "Mobile Allocation IE is not empty: ",
8759 ie.chan_ident.ma, ", despite it shall be");
8760 continue;
8761 }
8762 }
8763
8764 /* Disable frequency hopping */
8765 f_TC_fh_params_unset(fhp);
8766
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008767 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008768}
8769
8770/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8771testcase TC_fh_params_imm_ass() runs on test_CT {
8772 var FHParamsTrx fhp := f_TC_fh_params_gen();
8773 var RSL_Message rsl_msg;
8774 var RSL_IE_Body ie;
8775
8776 f_init_vty();
8777
8778 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8779 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8780
8781 f_init(1);
8782
8783 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8784 for (var integer i := 0; i < 9; i := i + 1) {
8785 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8786 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8787
8788 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8789 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8790
8791 /* Make sure that Full Immediate Assign Info IE is present */
8792 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8793 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8794 continue;
8795 }
8796
8797 /* Decode the actual Immediate Assignment message */
8798 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8799 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8800 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8801 continue;
8802 }
8803
8804 /* Make sure that hopping parameters (HSN/MAIO) match */
8805 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8806
8807 /* Make sure that the Mobile Allocation IE matches */
8808 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8809 rr_msg.payload.imm_ass.mobile_allocation);
8810 }
8811
8812 /* Disable frequency hopping */
8813 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008814
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008815 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008816}
8817
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008818/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8819testcase TC_fh_params_assignment_cmd() runs on test_CT {
8820 var FHParamsTrx fhp := f_TC_fh_params_gen();
8821 var RSL_Message rsl_msg;
8822 var RSL_IE_Body ie;
8823
8824 f_init_vty();
8825
8826 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8827 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8828
8829 f_init(1);
8830
8831 /* HACK: work around "Couldn't find Expect for CRCX" */
8832 vc_MGCP.stop;
8833
8834 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8835 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8836
8837 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8838 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8839 for (var integer i := 0; i < 3; i := i + 1) {
8840 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8841 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8842
8843 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8844 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8845 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8846
8847 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8848 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8849 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8850
8851 /* Make sure that L3 Information IE is present */
8852 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8853 setverdict(fail, "RSL L3 Information IE is absent");
8854 continue;
8855 }
8856
8857 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8858 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8859 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8860 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8861 continue;
8862 }
8863
8864 /* Make sure that hopping parameters (HSN/MAIO) match */
8865 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8866 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8867
8868 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8869 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008870 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008871 continue;
8872 }
8873
8874 /* Make sure that the Mobile Allocation IE matches (if present) */
8875 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8876 if (chan_desc.h and ma_present) {
8877 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8878 l3_msg.payload.ass_cmd.mobile_allocation.v);
8879 } else if (chan_desc.h and not ma_present) {
8880 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8881 continue;
8882 } else if (not chan_desc.h and ma_present) {
8883 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8884 continue;
8885 }
8886 }
8887
8888 /* Give the IUT some time to release all channels */
8889 f_sleep(3.0);
8890
8891 /* Disable frequency hopping */
8892 f_TC_fh_params_unset(fhp);
8893
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008894 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008895}
8896
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008897/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8898private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8899runs on test_CT {
8900 var RSL_Message rsl_msg;
8901 var RSL_IE_Body ie;
8902 var DchanTuple dt;
8903
8904 /* Establish a dedicated channel, so we can trigger handover */
8905 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03008906 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008907
8908 /* Trigger handover from BTS0 to BTS1 */
8909 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8910 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8911
8912 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8913 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8914
8915 /* ACKnowledge channel activation and expect (RR) Handover Command */
8916 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8917 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8918
8919 /* Make sure that L3 Information IE is present */
8920 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8921 setverdict(fail, "RSL L3 Information IE is absent");
8922 return;
8923 }
8924
8925 /* Decode the L3 message and make sure it is (RR) Handover Command */
8926 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8927 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8928 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8929 return;
8930 }
8931
8932 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8933 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8934 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8935 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8936 return;
8937 }
8938
8939 /* Make sure that hopping parameters (HSN/MAIO) match */
8940 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8941
8942 /* Make sure that Cell Channel Description IE is present */
8943 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8944 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8945 return;
8946 }
8947
8948 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8949 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8950 if (ma_present) {
8951 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8952 l3_msg.payload.ho_cmd.mobile_allocation.v);
8953 } else {
8954 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8955 return;
8956 }
8957}
8958testcase TC_fh_params_handover_cmd() runs on test_CT {
8959 var FHParamsTrx fhp := f_TC_fh_params_gen();
8960
8961 f_init_vty();
8962
8963 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8964 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8965
8966 f_vty_transceive(BSCVTY, "timeslot 0");
8967 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8968 f_vty_transceive(BSCVTY, "exit"); /* go back */
8969
8970 f_vty_transceive(BSCVTY, "timeslot 1");
8971 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8972 f_vty_transceive(BSCVTY, "end"); /* we're done */
8973
8974 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8975 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8976
8977 f_init(2);
8978
8979 f_TC_fh_params_handover_cmd(fhp);
8980
8981 /* Disable frequency hopping on BTS1 */
8982 f_TC_fh_params_unset(fhp, 1);
8983
8984 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8985 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8986
8987 f_vty_transceive(BSCVTY, "timeslot 0");
8988 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8989 f_vty_transceive(BSCVTY, "exit"); /* go back */
8990
8991 f_vty_transceive(BSCVTY, "timeslot 1");
8992 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8993 f_vty_transceive(BSCVTY, "end"); /* we're done */
8994
8995 f_shutdown_helper();
8996}
8997
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008998/* Verify the hopping parameters in System Information Type 4 */
8999testcase TC_fh_params_si4_cbch() runs on test_CT {
9000 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9001 var ASP_RSL_Unitdata rx_rsl_ud;
9002 timer T := 5.0;
9003
9004 f_init_vty();
9005
9006 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9007 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9008
9009 f_vty_transceive(BSCVTY, "timeslot 0");
9010 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9011 f_vty_transceive(BSCVTY, "exit"); /* go back */
9012
9013 f_vty_transceive(BSCVTY, "timeslot 1");
9014 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9015 f_vty_transceive(BSCVTY, "end"); /* we're done */
9016
9017 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9018 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9019
9020 f_init(1);
9021
9022 T.start;
9023 alt {
9024 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
9025 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9026 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9027
9028 /* Make sure that what we decoded is System Information Type 4 */
9029 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9030 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9031 repeat;
9032 }
9033
9034 /* Make sure that CBCH Channel Description IE is present */
9035 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9036 setverdict(fail, "CBCH Channel Description IE is absent");
9037 break;
9038 }
9039
9040 /* Finally, check the hopping parameters (HSN, MAIO) */
9041 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9042 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9043
9044 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9045 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9046 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9047 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9048 break;
9049 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9050 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9051 si.payload.si4.cbch_mobile_alloc.v);
9052 }
9053 }
9054 [] IPA_RSL[0].receive { repeat; }
9055 [] T.timeout {
9056 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9057 }
9058 }
9059
9060 /* Disable frequency hopping */
9061 f_TC_fh_params_unset(fhp);
9062
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009063 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009064 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9065
9066 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009067 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009068 f_vty_transceive(BSCVTY, "exit"); /* go back */
9069
9070 f_vty_transceive(BSCVTY, "timeslot 1");
9071 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9072 f_vty_transceive(BSCVTY, "end"); /* we're done */
9073
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009074 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009075}
9076
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009077template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9078 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9079
9080private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9081 template (present) BSSLAP_PDU expect_bsslap)
9082{
9083 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9084 if (not match(bsslap, expect_bsslap)) {
9085 log("EXPECTING BSSLAP: ", expect_bsslap);
9086 log("GOT BSSLAP: ", bsslap);
9087 setverdict(fail, "BSSLAP is not as expected");
9088 mtc.stop;
9089 }
9090 setverdict(pass);
9091}
9092
9093/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9094const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9095
9096private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9097 var PDU_BSSAP_LE rx_bsslap;
9098 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9099 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9100}
9101
9102/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9103 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9104private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9105 f_sleep(1.0);
9106
9107 f_establish_fully(omit, omit);
9108 f_bssap_le_register_imsi(g_pars.imsi, omit);
9109
9110 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9111 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9112
9113 var PDU_BSSAP_LE plr;
9114 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9115
9116 if (not do_ta_request) {
9117 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9118 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9119 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9120 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9121 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9122 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9123 mtc.stop;
9124 }
9125 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9126 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9127 if (not match(bsslap, expect_ta_layer3)) {
9128 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9129 log("GOT BSSLAP: ", bsslap);
9130 setverdict(fail, "BSSLAP is not as expected");
9131 mtc.stop;
9132 }
9133 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9134 * has no need to request the TA from the BSC and directly responds. */
9135 } else {
9136 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9137 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9138 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9139 }
9140
9141 /* SMLC got the TA from the BSC, now responds with geo information data. */
9142 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9143 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9144 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9145
9146 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9147 f_mo_l3_transceive();
9148
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009149 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009150
9151 f_sleep(2.0);
9152 setverdict(pass);
9153}
9154
9155/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9156 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9157private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9158 f_lcs_loc_req_for_active_ms(false);
9159}
9160testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9161 var MSC_ConnHdlr vc_conn;
9162 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9163
9164 f_init(1, true);
9165 f_sleep(1.0);
9166 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9167 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009168 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009169}
9170
9171/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9172 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9173private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9174 f_lcs_loc_req_for_active_ms(true);
9175}
9176testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9177 var MSC_ConnHdlr vc_conn;
9178 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9179
9180 f_init(1, true);
9181 f_sleep(1.0);
9182 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9183 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009184 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009185}
9186
9187/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9188 * conn without an active lchan. */
9189private function f_clear_A_conn() runs on MSC_ConnHdlr
9190{
9191 var BssmapCause cause := 0;
9192 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9193 BSSAP.receive(tr_BSSMAP_ClearComplete);
9194 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9195
9196 timer no_more_bssap := 5.0;
9197 no_more_bssap.start;
9198 alt {
9199 [] no_more_bssap.timeout { break; }
9200 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9201 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9202 mtc.stop;
9203 }
9204 }
9205 setverdict(pass);
9206}
9207
9208/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9209 * for LCS, for cases where there is only an A conn without an active lchan. */
9210private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9211{
9212 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9213
9214 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9215 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9216 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9217 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9218 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9219 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9220
9221 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9222 f_clear_A_conn();
9223 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9224 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9225}
9226
9227/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9228 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9229 */
9230private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9231 f_sleep(1.0);
9232
9233 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9234 f_bssap_le_register_imsi(g_pars.imsi, omit);
9235
9236 /* Register to receive the Paging Command */
9237 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9238 g_chan_nr := new_chan_nr;
9239 f_rslem_register(0, g_chan_nr);
9240
9241 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9242 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9243 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9244 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9245
9246 var PDU_BSSAP_LE plr;
9247 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9248
9249 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9250 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9251
9252 /* OsmoBSC needs to Page */
9253 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9254 f_logp(BSCVTY, "got Paging Command");
9255
9256 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9257 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009258 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);
9259 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009260
9261 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9262
9263 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9264
9265 /* SMLC got the TA from the BSC, now responds with geo information data. */
9266 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9267 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9268
9269 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9270
9271 /* The lchan is gone, the A-interface conn was created for the LCS only.
9272 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9273 f_verify_active_A_conn_and_clear();
9274
9275 f_sleep(2.0);
9276 setverdict(pass);
9277}
9278testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9279 var MSC_ConnHdlr vc_conn;
9280 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9281
9282 f_init(1, true);
9283 f_sleep(1.0);
9284
9285 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9286 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9287
9288 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9289 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009290 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009291}
9292
9293/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9294 */
9295private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9296 f_sleep(1.0);
9297
9298 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9299 f_bssap_le_register_imsi(g_pars.imsi, omit);
9300
9301 /* provoke an abort by omitting both IMSI and IMEI */
9302 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9303 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9304 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9305 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9306
9307 /* BSC tells MSC about failure */
9308 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9309 locationEstimate := omit, positioningData := omit,
9310 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9311
9312 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9313 f_verify_active_A_conn_and_clear();
9314
9315 f_sleep(2.0);
9316 setverdict(pass);
9317}
9318testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9319 var MSC_ConnHdlr vc_conn;
9320 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9321
9322 f_init(1, true);
9323 f_sleep(1.0);
9324
9325 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9326 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9327
9328 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9329 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009330 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009331}
9332
9333/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9334 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9335private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9336 f_sleep(1.0);
9337
9338 f_establish_fully(omit, omit);
9339 f_bssap_le_register_imsi(g_pars.imsi, omit);
9340
9341 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9342 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9343
9344 var PDU_BSSAP_LE plr;
9345 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9346
9347 if (do_ta) {
9348 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9349 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9350 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9351 }
9352
9353 /* SMLC fails to respond, BSC runs into timeout */
9354 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9355 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9356
9357 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9358 locationEstimate := omit, positioningData := omit,
9359 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9360
9361 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9362 f_verify_active_A_conn_and_clear();
9363
9364 f_sleep(2.0);
9365 setverdict(pass);
9366}
9367
9368/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9369 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9370private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9371 f_lcs_loc_req_for_active_ms_le_timeout(false);
9372}
9373
9374testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9375 var MSC_ConnHdlr vc_conn;
9376 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9377
9378 f_init(1, true);
9379 f_sleep(1.0);
9380 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9381 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009382 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009383}
9384
9385/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9386 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9387private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9388 f_lcs_loc_req_for_active_ms_le_timeout(true);
9389}
9390
9391testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9392 var MSC_ConnHdlr vc_conn;
9393 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9394
9395 f_init(1, true);
9396 f_sleep(1.0);
9397 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9398 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009399 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009400}
9401
9402/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9403private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9404 f_sleep(1.0);
9405
9406 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9407 f_bssap_le_register_imsi(g_pars.imsi, omit);
9408
9409 /* Register to receive the Paging Command */
9410 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9411 g_chan_nr := new_chan_nr;
9412 f_rslem_register(0, g_chan_nr);
9413
9414 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9415 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9416 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9417 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9418
9419 var PDU_BSSAP_LE plr;
9420 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9421
9422 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9423 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9424
9425 /* OsmoBSC needs to Page */
9426 var PDU_BSSAP_LE rx_bsslap;
9427 alt {
9428 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9429 f_logp(BSCVTY, "got Paging Command");
9430 repeat;
9431 }
9432 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9433 /* MS does not respond to Paging, TA Req runs into timeout. */
9434 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9435 }
9436 }
9437
9438 /* SMLC responds with failure */
9439 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9440 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9441
9442 /* BSC tells MSC about failure */
9443 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9444 locationEstimate := omit, positioningData := omit,
9445 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9446
9447 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9448 f_verify_active_A_conn_and_clear();
9449
9450 f_sleep(2.0);
9451 setverdict(pass);
9452}
9453testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9454 var MSC_ConnHdlr vc_conn;
9455 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9456
9457 f_init(1, true);
9458 f_sleep(1.0);
9459
9460 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9461 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9462
9463 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9464 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009465 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009466}
9467
9468/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9469 * over. */
9470private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9471 f_sleep(1.0);
9472
9473 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9474 f_bssap_le_register_imsi(g_pars.imsi, omit);
9475
9476 /* Register to receive the Paging Command */
9477 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9478 g_chan_nr := new_chan_nr;
9479 f_rslem_register(0, g_chan_nr);
9480
9481 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9482 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9483 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9484 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9485
9486 var PDU_BSSAP_LE plr;
9487 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9488
9489 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9490 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009491 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 +02009492 do_clear := false, expect_bssmap_l3 := true);
9493
9494 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9495 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9496
9497 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9498 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9499
9500 /* SMLC got the TA from the BSC, now responds with geo information data. */
9501 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9502 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9503 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9504
9505 /* The lchan should still exist, it was from a CM Service Request. */
9506 f_mo_l3_transceive();
9507
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009508 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009509
9510 f_sleep(2.0);
9511 setverdict(pass);
9512}
9513testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9514 var MSC_ConnHdlr vc_conn;
9515 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9516
9517 f_init(1, true);
9518 f_sleep(1.0);
9519
9520 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9521 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9522
9523 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9524 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009525 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009526}
9527
9528/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9529 * the new lchan after handover. */
9530private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9531 f_sleep(1.0);
9532
9533 f_establish_fully(omit, omit);
9534 f_bssap_le_register_imsi(g_pars.imsi, omit);
9535
9536 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9537 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9538
9539 var PDU_BSSAP_LE plr;
9540 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9541
9542 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9543 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9544
9545 var HandoverState hs := {
9546 rr_ho_cmpl_seen := false,
9547 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02009548 old_chan_nr := -,
9549 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009550 };
9551 /* issue hand-over command on VTY */
9552 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9553 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9554 f_rslem_suspend(RSL1_PROC);
9555
9556 /* From the MGW perspective, a handover is is characterized by
9557 * performing one MDCX operation with the MGW. So we expect to see
9558 * one more MDCX during handover. */
9559 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9560
9561 alt {
9562 [] as_handover(hs);
9563 }
9564
9565 var PDU_BSSAP_LE rx_bsslap;
9566
9567 interleave {
9568 /* Expect the BSC to inform the MSC about the handover */
9569 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9570
9571 /* Expect the BSC to inform the SMLC about the handover */
9572 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9573 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9574 }
9575 }
9576
9577 /* SMLC now responds with geo information data. */
9578 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9579 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9580 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9581
9582 /* lchan still active */
9583 f_mo_l3_transceive(RSL1);
9584
9585 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009586 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009587
9588 f_sleep(2.0);
9589 setverdict(pass);
9590}
9591testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9592 var MSC_ConnHdlr vc_conn;
9593 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9594
9595 f_init(2, true);
9596 f_sleep(1.0);
9597 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9598 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009599 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009600}
9601
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009602/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9603private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9604 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9605
9606 /* Also disable attach for the single connected MSC */
9607 f_vty_msc_allow_attach(BSCVTY, { false });
9608
9609 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) ));
9610 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9611
9612 /* No MSC is found, expecting a proper release on RSL */
9613 interleave {
9614 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9615 f_logp(BSCVTY, "Got RSL RR Release");
9616 }
9617 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9618 f_logp(BSCVTY, "Got RSL Deact SACCH");
9619 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009620 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009621 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9622 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009623 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009624 }
9625 }
9626 setverdict(pass);
9627}
9628testcase TC_no_msc() runs on test_CT {
9629
9630 f_init(1, true);
9631 f_sleep(1.0);
9632 var MSC_ConnHdlr vc_conn;
9633 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9634
9635 f_ctrs_bsc_init(counternames_bsc_mscpool);
9636
9637 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9638 vc_conn.done;
9639
9640 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9641 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009642 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009643}
9644
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009645/* Dyn PDCH todo:
9646 * activate OSMO as TCH/F
9647 * activate OSMO as TCH/H
9648 * does the BSC-located PCU socket get the updated INFO?
9649 * what if no PCU is connected at the time?
9650 * is the info correct on delayed PCU (re)connect?
9651 */
Harald Welte94e0c342018-04-07 11:33:23 +02009652
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009653private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9654 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9655 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9656
9657 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9658 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9659 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9660 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9661 g_pars.ass_codec_list.codecElements[0];
9662 if (isvalue(g_pars.expect_mr_s0_s7)) {
9663 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9664 g_pars.expect_mr_s0_s7;
9665 }
9666 }
9667 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9668 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9669 log("expecting ASS COMPL like this: ", exp_compl);
9670
9671 f_establish_fully(ass_cmd, exp_compl);
9672
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009673 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 +00009674
9675 var RSL_Message rsl;
9676
9677 timer T := 5.0;
9678 T.start;
9679 alt {
9680 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9681 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9682 log("Rx L3 from net: ", l3);
9683 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9684 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9685 mtc.stop;
9686 }
9687 }
9688 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9689 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9690 mtc.stop;
9691 }
9692 [] T.timeout {
9693 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9694 setverdict(pass);
9695 }
9696 }
9697 T.stop;
9698}
9699
9700/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9701 * osmo-bsc. */
9702testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9703 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9704 var MSC_ConnHdlr vc_conn;
9705
9706 f_init(1, true);
9707 f_sleep(1.0);
9708
9709 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9710 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9711 vc_conn.done;
9712 f_shutdown_helper();
9713}
9714
9715/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9716 */
9717testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9718 f_init_vty();
9719
9720 f_init(1, false);
9721 f_sleep(1.0);
9722
9723 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9724
9725 var ASP_RSL_Unitdata rx_rsl_ud;
9726 timer T := 5.0;
9727
9728 T.start;
9729 alt {
9730 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9731 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9732 T.stop;
9733 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9734 mtc.stop;
9735 }
9736 repeat;
9737 }
9738 [] T.timeout {
9739 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9740 setverdict(pass);
9741 }
9742 }
9743}
9744
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009745private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9746 /* First fully set up a speech lchan */
9747 f_TC_assignment_codec(id);
9748
9749 /* Trigger re-assignment to another lchan */
9750 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9751
9752 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9753 * one MDCX on MGCP. */
9754 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9755
9756 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9757 * as the old lchan used. */
9758 g_media.bts.ipa_crcx_seen := false;
9759 g_media.bts.ipa_mdcx_seen := false;
9760
9761 /* Send different BTS side RTP port number for the new lchan */
9762 g_media.bts.bts.port_nr := 4223;
9763
9764 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9765
9766 /* Trigger re-assignment. */
9767 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9768
9769 timer T := 5.0;
9770 T.start;
9771 alt {
9772 [] as_assignment(assignment_st);
9773 [] as_Media();
9774 [] T.timeout {
9775 break;
9776 }
9777 }
9778
9779 if (not assignment_st.assignment_done) {
9780 setverdict(fail, "Assignment did not complete");
9781 mtc.stop;
9782 }
9783
9784 f_check_mgcp_expectations()
9785 setverdict(pass);
9786
9787 f_sleep(2.0);
9788 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9789
9790 /* Instruct BSC to clear channel */
9791 var BssmapCause cause := 0;
9792 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9793 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009794 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9795 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009796 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009797 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009798 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009799 }
9800 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9801 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9802 }
9803 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +02009804 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009805
9806 f_sleep(0.5);
9807}
9808
9809testcase TC_reassignment_fr() runs on test_CT {
9810 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9811 var MSC_ConnHdlr vc_conn;
9812
9813 f_init(1, true);
9814 f_sleep(1.0);
9815
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01009816 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009817
9818 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9819 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9820 vc_conn.done;
9821
9822 /* from f_establish_fully() */
9823 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9824 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9825 /* from re-assignment */
9826 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9827 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9828 f_ctrs_bsc_and_bts_verify();
9829 f_shutdown_helper();
9830}
9831
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009832const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9833const charstring REEST_CLEAR := "REEST_CLEAR";
9834const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9835
9836/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9837 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9838 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9839 * the MSC as the CM Re-Establishment is handled.
9840 *
9841 * MS bts0 bts1 bsc msc test-component
9842 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9843 * | | _1 wait a bit, to settle down
9844 * |<-x x--| | _1 "lose connection"
9845 * | | REEST_LOST_CONNECTION
9846 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9847 * | | REEST_CLEAR
9848 * | |<-0---| _1 Clear Command on first A-conn
9849 * | |--0-->| _1 Clear Complete
9850 * | |<----------------->| | _1 Release first channel
9851 * | | REEST_CLEAR_DONE
9852 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9853 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9854 *
9855 */
9856private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9857 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9858 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9859
9860 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9861 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9862
9863 f_establish_fully(ass_cmd, exp_compl);
9864
9865 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9866 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9867 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9868 f_sleep(2.0);
9869 COORD.send(REEST_LOST_CONNECTION);
9870
9871 alt {
9872 [] COORD.receive(REEST_CLEAR);
9873 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9874 setverdict(fail, "Unexpected channel release");
9875 mtc.stop;
9876 }
9877 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9878 setverdict(fail, "Unexpected channel release");
9879 mtc.stop;
9880 }
9881 }
9882 f_perform_clear()
9883 f_expect_dlcx_conns();
Neels Hofmeyr969abd02021-09-23 22:24:08 +02009884 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009885 COORD.send(REEST_CLEAR_DONE);
9886}
9887
9888private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9889 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9890
9891 /* The MS lost the connection on the first channel, now establishes another one */
9892 COORD.receive(REEST_LOST_CONNECTION);
9893
9894 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9895 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9896 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9897
9898 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009899 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 +02009900 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9901
9902 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9903 COORD.send(REEST_CLEAR);
9904 COORD.receive(REEST_CLEAR_DONE);
9905
9906 f_sleep(2.0);
9907
9908 /* Answer the CM Re-Establishment with an Assignment Command. */
9909 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9910 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9911 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9912 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9913
9914 var AssignmentState st := valueof(ts_AssignmentStateInit);
9915 st.voice_call := true;
9916 st.is_assignment := true;
9917
9918 var ExpectCriteria mgcpcrit := {
9919 connid := omit,
9920 endpoint := omit,
9921 transid := omit
9922 };
9923 f_create_mgcp_expect(mgcpcrit);
9924
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009925 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009926
9927 BSSAP.send(ass_cmd);
9928
9929 var PDU_BSSAP bssap;
9930
9931 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009932 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9933 [] as_Media_ipacc(RSL1, RSL2);
9934 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009935 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9936 break;
9937 }
9938 }
9939
9940 f_sleep(3.0);
9941
9942 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009943 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009944 f_expect_dlcx_conns();
9945}
9946
9947testcase TC_cm_reestablishment() runs on test_CT {
9948 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9949 var MSC_ConnHdlr vc_conn1;
9950
9951 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9952 var MSC_ConnHdlr vc_conn2;
9953 pars2.imsi := pars1.imsi;
9954 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +02009955 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009956
9957 f_init(2, true, guard_timeout := 40.0);
9958 f_sleep(1.0);
9959
9960 vc_conn1 := f_start_handler_create(pars1);
9961 vc_conn2 := f_start_handler_create(pars2);
9962 connect(vc_conn1:COORD, vc_conn2:COORD);
9963 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9964 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9965 vc_conn1.done;
9966 vc_conn2.done;
9967
9968 f_shutdown_helper();
9969}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009970
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009971function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9972 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9973runs on test_CT return template (omit) RSL_Message {
9974 var ASP_RSL_Unitdata rx_rsl_ud;
9975 timer T := t_secs;
9976
9977 T.start;
9978 alt {
9979 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9980 T.stop;
9981 }
9982 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9983 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9984 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9985 T.stop;
9986 return omit;
9987 }
9988 [] T.timeout {
9989 return omit;
9990 }
9991 }
9992 return rx_rsl_ud.rsl;
9993}
9994
9995private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9996 f_vty_enter_cfg_bts(pt, bts_nr);
9997 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9998 f_vty_transceive(pt, "exit");
9999 f_vty_transceive(pt, "exit");
10000 f_vty_transceive(pt, "exit");
10001}
10002
10003private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010004 template RslChannelNr chan_nr := ?,
10005 template (present) uint12_t arfcn := ?,
10006 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010007{
10008 var RSL_IE_Body full_imm_ass_info;
10009 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10010 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10011 mtc.stop;
10012 }
10013
10014 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10015 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10016 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010017 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010018 page_mode := ?);
10019 if (not match(rr_imm_ass, expect_imm_ass)) {
10020 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10021 setverdict(fail, "Failed to match Immediate Assignment");
10022 mtc.stop;
10023 }
10024}
10025
10026testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10027 var RSL_Message chan_act;
10028 var RSL_Message imm_ass;
10029
10030 f_init(1, false);
10031 f_sleep(1.0);
10032
10033 /* (should be the default anyway, just to make things clear) */
10034 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10035
10036 /* RA containing reason=LU */
10037 var GsmFrameNumber fn := 2342;
10038 var uint8_t ra := 2;
10039 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10040
10041 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10042
10043 /* First send the Chan Act ACK */
10044 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010045 var RSL_IE_Body chan_ident_ie;
10046 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10047 setverdict(fail, "RSL Channel Identification IE is absent");
10048 mtc.stop;
10049 }
10050
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010051 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
10052
10053 /* Then expect the Immediate Assignment, after we ACKed the chan act */
10054 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10055
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010056 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10057 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010058
10059 /* Check that the lchan is working */
10060 var octetstring l3 := '00010203040506'O;
10061 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10062
10063 var BSSAP_N_CONNECT_ind rx_c_ind;
10064 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10065 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10066
10067 f_sleep(1.0);
10068 f_shutdown_helper();
10069}
10070
10071testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10072 var RSL_Message chan_act;
10073 var RSL_Message imm_ass;
10074
10075 f_init(1, false);
10076 f_sleep(1.0);
10077
10078 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10079
10080 /* RA containing reason=LU */
10081 var GsmFrameNumber fn := 2342;
10082 var uint8_t ra := 2;
10083 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10084
10085 /* (set bts 0 cfg back to default) */
10086 f_vty_set_imm_ass(BSCVTY);
10087
10088 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10089 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010090 var RSL_IE_Body chan_ident_ie;
10091 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10092 setverdict(fail, "RSL Channel Identification IE is absent");
10093 mtc.stop;
10094 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010095
10096 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10097 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010098 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10099 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010100
10101 /* Only now send the Chan Act ACK */
10102 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10103
10104 /* Check that the lchan is working */
10105 var octetstring l3 := '00010203040506'O;
10106 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10107
10108 var BSSAP_N_CONNECT_ind rx_c_ind;
10109 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10110 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10111
10112 f_sleep(1.0);
10113 f_shutdown_helper();
10114}
10115
Neels Hofmeyr23158742021-09-07 19:08:07 +020010116testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10117 var RSL_Message chan_act;
10118 var RSL_Message imm_ass;
10119
10120 f_init(1, false);
10121 f_sleep(1.0);
10122
10123 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10124
10125 /* RA containing reason=LU */
10126 var GsmFrameNumber fn := 2342;
10127 var uint8_t ra := 2;
10128 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10129
10130 /* (set bts 0 cfg back to default) */
10131 f_vty_set_imm_ass(BSCVTY);
10132
10133 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10134 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
10135 var RSL_IE_Body chan_ident_ie;
10136 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10137 setverdict(fail, "RSL Channel Identification IE is absent");
10138 mtc.stop;
10139 }
10140
10141 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10142 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10143 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10144 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10145
10146 /* Only now send the Chan Act ACK */
10147 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10148
10149 /* Check that the lchan is working */
10150 var octetstring l3 := '00010203040506'O;
10151 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10152
10153 var BSSAP_N_CONNECT_ind rx_c_ind;
10154 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10155 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10156
10157 f_sleep(1.0);
10158 f_shutdown_helper();
10159}
10160
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010161testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10162 /* change Timeslot 6 before f_init() starts RSL */
10163 f_init_vty();
10164 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10165 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10166
10167 f_init(1, false);
10168 f_sleep(1.0);
10169
10170 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10171 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10172 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10173 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10174
10175 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10176 f_ts_set_chcomb(0, 0, 6, "PDCH");
10177
10178 /* block all static timeslots so that the dyn TS will be used */
10179 f_disable_all_tch_f();
10180 f_disable_all_tch_h();
10181 f_disable_all_sdcch();
10182
10183 var RSL_Message chan_act;
10184 var RSL_Message imm_ass;
10185
10186 f_init(1, false);
10187 f_sleep(1.0);
10188
10189 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10190
10191 /* RA containing reason=LU */
10192 var GsmFrameNumber fn := 2342;
10193 var uint8_t ra := 2;
10194 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10195
10196 /* (set bts 0 cfg back to default) */
10197 f_vty_set_imm_ass(BSCVTY);
10198
10199 /* Expect the dyn TS to deactivate PDCH first */
10200 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10201 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10202
10203 /* Now activation as SDCCH8 */
10204 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10205
10206 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010207 var RSL_IE_Body chan_ident_ie;
10208 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10209 setverdict(fail, "RSL Channel Identification IE is absent");
10210 mtc.stop;
10211 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010212
10213 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10214 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010215 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10216 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010217
10218 /* Only now send the Chan Act ACK */
10219 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10220
10221 /* Check that the lchan is working */
10222 var octetstring l3 := '00010203040506'O;
10223 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10224
10225 var BSSAP_N_CONNECT_ind rx_c_ind;
10226 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10227 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10228
10229 f_sleep(1.0);
10230 f_shutdown_helper();
10231}
10232
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010233testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10234 /* change Timeslot 6 before f_init() starts RSL */
10235 f_init_vty();
10236 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10237 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10238
10239 f_init(1, false);
10240 f_sleep(1.0);
10241
10242 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10243 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10244 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10245 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10246
10247 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10248 f_ts_set_chcomb(0, 0, 6, "PDCH");
10249
10250 /* block all static timeslots so that the dyn TS will be used */
10251 f_disable_all_tch_f();
10252 f_disable_all_tch_h();
10253 f_disable_all_sdcch();
10254
10255 var RSL_Message chan_act;
10256 var RSL_Message imm_ass;
10257
10258 f_init(1, false);
10259 f_sleep(1.0);
10260
10261 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10262
10263 /* RA containing reason=LU */
10264 var GsmFrameNumber fn := 2342;
10265 var uint8_t ra := 2;
10266 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10267
10268 /* (set bts 0 cfg back to default) */
10269 f_vty_set_imm_ass(BSCVTY);
10270
10271 /* Expect the dyn TS to deactivate PDCH first */
10272 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10273
10274 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10275 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10276
10277 /* continue the Osmo style PDCH Deact (usual chan rel) */
10278 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10279
10280 /* Now activation as SDCCH8 */
10281 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10282
10283 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010284 var RSL_IE_Body chan_ident_ie;
10285 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10286 setverdict(fail, "RSL Channel Identification IE is absent");
10287 mtc.stop;
10288 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010289 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10290
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010291 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10292 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010293
10294 /* Check that the lchan is working */
10295 var octetstring l3 := '00010203040506'O;
10296 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10297
10298 var BSSAP_N_CONNECT_ind rx_c_ind;
10299 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10300 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10301
10302 f_sleep(1.0);
10303 f_shutdown_helper();
10304}
10305
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010306/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10307testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10308 var MSC_ConnHdlr vc_conn;
10309
10310 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10311 f_sleep(1.0);
10312
10313 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10314 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10315 "0,0,operational,unlocked,on,rsl-up;" &
10316 "1,0,operational,unlocked,on,rsl-up;" &
10317 "2,0,operational,unlocked,on,rsl-down;" &
10318 "3,0,inoperational,locked,on,rsl-down;");
10319
10320 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10321 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10322 /* give it a moment to settle the FSM status */
10323 f_sleep(1.0);
10324
10325 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10326 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10327 * of "off"? But that's for a future patch if at all. */
10328 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10329 "0,0,operational,unlocked,on,rsl-up;" &
10330 "1,0,operational,locked,on,rsl-up;" &
10331 "2,0,operational,unlocked,on,rsl-down;" &
10332 "3,0,inoperational,locked,on,rsl-down;");
10333
10334 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10335 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10336 f_sleep(1.0);
10337 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10338 "0,0,operational,unlocked,on,rsl-up;" &
10339 "1,0,operational,locked,on,rsl-up;" &
10340 "2,0,operational,unlocked,on,rsl-down;" &
10341 "3,0,inoperational,locked,on,rsl-down;");
10342
10343 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10344 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10345 f_sleep(1.0);
10346 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10347 "0,0,operational,unlocked,on,rsl-up;" &
10348 "1,0,operational,unlocked,on,rsl-up;" &
10349 "2,0,operational,unlocked,on,rsl-down;" &
10350 "3,0,inoperational,locked,on,rsl-down;");
10351
10352 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10353 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10354 f_sleep(1.0);
10355 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10356 "0,0,operational,unlocked,on,rsl-up;" &
10357 "1,0,operational,unlocked,on,rsl-up;" &
10358 "2,0,operational,unlocked,on,rsl-down;" &
10359 "3,0,inoperational,locked,on,rsl-down;");
10360
10361 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10362 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10363 f_sleep(1.0);
10364 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10365 "0,0,operational,unlocked,on,rsl-up;" &
10366 "1,0,operational,unlocked,on,rsl-up;" &
10367 "2,0,operational,unlocked,on,rsl-down;" &
10368 "3,0,inoperational,locked,on,rsl-down;");
10369
10370 f_shutdown_helper();
10371}
10372
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010373const CounterNameVals counternames_cm_serv_rej := {
10374 { "cm_serv_rej", 0 },
10375 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
10376 { "cm_serv_rej:illegal_ms", 0 },
10377 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
10378 { "cm_serv_rej:imei_not_accepted", 0 },
10379 { "cm_serv_rej:illegal_me", 0 },
10380 { "cm_serv_rej:plmn_not_allowed", 0 },
10381 { "cm_serv_rej:loc_not_allowed", 0 },
10382 { "cm_serv_rej:roaming_not_allowed", 0 },
10383 { "cm_serv_rej:network_failure", 0 },
10384 { "cm_serv_rej:synch_failure", 0 },
10385 { "cm_serv_rej:congestion", 0 },
10386 { "cm_serv_rej:srv_opt_not_supported", 0 },
10387 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
10388 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
10389 { "cm_serv_rej:call_can_not_be_identified", 0 },
10390 { "cm_serv_rej:incorrect_message", 0 },
10391 { "cm_serv_rej:invalid_mandantory_inf", 0 },
10392 { "cm_serv_rej:msg_type_not_implemented", 0 },
10393 { "cm_serv_rej:msg_type_not_compatible", 0 },
10394 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
10395 { "cm_serv_rej:condtional_ie_error", 0 },
10396 { "cm_serv_rej:msg_not_compatible", 0 },
10397 { "cm_serv_rej:protocol_error", 0 },
10398 { "cm_serv_rej:retry_in_new_cell", 0 }
10399};
10400
10401private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
10402{
10403 f_create_chan_and_exp();
10404 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010405 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010406}
10407testcase TC_cm_serv_rej() runs on test_CT {
10408 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10409 var MSC_ConnHdlr vc_conn;
10410
10411 f_init(1, true);
10412 f_sleep(1.0);
10413
10414 f_ctrs_bts_init(1, counternames_cm_serv_rej);
10415
10416 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
10417 vc_conn.done;
10418
10419 f_ctrs_bts_add(0, "cm_serv_rej", 1);
10420 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
10421 f_ctrs_bts_verify();
10422
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010423 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010424 f_shutdown_helper();
10425}
10426
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010427/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10428 * Activ Ack (SYS#5627). */
10429private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10430 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030010431
10432 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10433 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010434
10435 var BSSMAP_FIELD_CodecType codecType;
10436 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
10437
10438 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
10439
10440 /* First establish a signalling lchan */
10441 f_create_chan_and_exp();
10442 f_rslem_dchan_queue_enable();
10443
10444 /* we should now have a COMPL_L3 at the MSC */
10445 var template PDU_BSSAP exp_l3_compl;
10446 exp_l3_compl := tr_BSSMAP_ComplL3()
10447 if (g_pars.aoip == false) {
10448 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
10449 } else {
10450 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
10451 }
10452 timer T := 10.0;
10453 T.start;
10454 alt {
10455 [] BSSAP.receive(exp_l3_compl);
10456 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
10457 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
10458 }
10459 [] T.timeout {
10460 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
10461 }
10462 }
10463
10464 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
10465 activate(as_Media_mgw());
10466
10467 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
10468 f_rslem_register(0, chan_nr);
10469
10470 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
10471 BSSAP.send(ass_cmd);
10472
10473
10474 /* Wait for the Channel Activ for the TCH channel */
10475 var ASP_RSL_Unitdata rx_rsl_ud;
10476 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
10477
10478 /* make the original SDCCH disappear */
10479 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10480
10481 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
10482 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
10483
10484 interleave {
10485 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
10486 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
10487 }
10488
10489 BSSAP.send(ts_BSSMAP_ClearCommand(0));
10490 BSSAP.receive(tr_BSSMAP_ClearComplete);
10491 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10492
10493 var MgcpCommand mgcp;
10494 MGCP.receive(tr_DLCX()) -> value mgcp {
10495 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
10496 };
10497
10498 f_sleep(0.5);
10499}
10500testcase TC_lost_sdcch_during_assignment() runs on test_CT {
10501 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10502 var MSC_ConnHdlr vc_conn;
10503
10504 f_init(1, true);
10505 f_sleep(1.0);
10506
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010507 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
10508 vc_conn.done;
10509
10510 f_shutdown_helper();
10511}
10512
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010513const CounterNameVals counternames_bsc_bts_all_available_allocated := {
10514 { "all_allocated:sdcch", 0 },
10515 { "all_allocated:static_sdcch", 0 },
10516 { "all_allocated:tch", 0 },
10517 { "all_allocated:static_tch", 0 }
10518}
10519
10520private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
10521{
10522 /* Make sure counters settle first */
10523 f_sleep(1.0);
10524
10525 /* Take a baseline of counters */
10526 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
10527
10528 /* Elapse some time so that we see changes in counters, hopefully where expected */
10529 f_sleep(2.0);
10530
10531 /* Get new counters */
10532 var charstring_list all_changed := {};
10533 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
10534 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
10535
10536 /* Compare with expectations */
10537 var charstring_list all_expect_changed := {};
10538 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
10539 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
10540 }
10541 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
10542}
10543
10544testcase TC_ratectr_all_available_allocated() runs on test_CT {
10545 var ASP_RSL_Unitdata rsl_ud;
10546 var integer i;
10547 var integer chreq_total, chreq_nochan;
10548
10549 f_init(1);
10550 f_sleep(1.0);
10551
10552 /* Exhaust all dedicated SDCCH lchans.
10553 /* GSM 44.018 Table 9.1.8.2:
10554 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10555 */
10556 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10557 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10558 }
10559
10560 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
10561 * level.
10562 * All SDCCH are now occupied. */
10563 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10564
10565 /* Also fill up all remaining (TCH) channels */
10566 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
10567 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10568 }
10569
10570 /* All TCH are now also occupied */
10571 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10572 "all_allocated:tch", "all_allocated:static_tch"});
10573
10574 f_shutdown_helper();
10575}
10576
10577testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
10578 var ASP_RSL_Unitdata rsl_ud;
10579 var integer i;
10580 var integer chreq_total, chreq_nochan;
10581
10582 f_init_vty();
10583 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
10584 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10585 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
10586
10587 f_init(1, guard_timeout := 60.0);
10588 f_sleep(1.0);
10589
10590 /* The dyn TS wants to activate PDCH mode, ACK that. */
10591 var RslChannelNr chan_nr;
10592 chan_nr := valueof(t_RslChanNr_PDCH(2));
10593 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10594 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10595
10596 /* Exhaust all dedicated SDCCH lchans.
10597 /* GSM 44.018 Table 9.1.8.2:
10598 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10599 */
10600 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10601 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10602 }
10603
10604 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
10605 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
10606 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
10607
10608 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
10609 * Will release them later, so remember all the DchanTuples. */
10610 var DchanTuples dyn_sddch := {};
10611 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10612
10613 /* Also occupy the seven other SDCCH of the dyn TS */
10614 for (i := 0; i < 7; i := i+1) {
10615 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10616 }
10617
10618 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
10619 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10620
10621 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
10622 for (i := 0; i < 5; i := i+1) {
10623 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10624 }
10625
10626 /* All TCH lchans are now also occupied, both static and dynamic */
10627 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10628 "all_allocated:tch", "all_allocated:static_tch"});
10629
10630 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
10631 * incrementing. */
10632 var BssmapCause cause := 0;
10633 var DchanTuple dt := dyn_sddch[0];
10634 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10635 f_exp_chan_rel_and_clear(dt, 0);
10636
10637 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
10638 * count as occupied, so those still both increment. */
10639 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
10640 "all_allocated:tch", "all_allocated:static_tch"});
10641
10642 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
10643 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
10644 dt := dyn_sddch[i];
10645 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10646 f_exp_chan_rel_and_clear(dt, 0);
10647 }
10648
10649 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
10650 chan_nr := valueof(t_RslChanNr_PDCH(2));
10651 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10652 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10653
10654 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
10655 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
10656
10657 /* clean up config */
10658 f_ts_reset_chcomb(0);
10659
10660 f_shutdown_helper();
10661}
10662
Harald Welte28d943e2017-11-25 15:00:50 +010010663control {
Harald Welte898113b2018-01-31 18:32:21 +010010664 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010665 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010666 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020010667 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
10668 * these in the AoIP test suite. */
10669 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10670 execute( TC_stat_num_msc_connected_1() );
10671 execute( TC_stat_num_msc_connected_2() );
10672 execute( TC_stat_num_msc_connected_3() );
10673 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020010674 execute( TC_stat_num_bts_connected_1() );
10675 execute( TC_stat_num_bts_connected_2() );
10676 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010677 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010678 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010679 execute( TC_ctrl_location() );
10680 }
Harald Welte898113b2018-01-31 18:32:21 +010010681
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010682 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010683 execute( TC_si2quater_2_earfcns() );
10684 execute( TC_si2quater_3_earfcns() );
10685 execute( TC_si2quater_4_earfcns() );
10686 execute( TC_si2quater_5_earfcns() );
10687 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010688 execute( TC_si2quater_12_earfcns() );
10689 execute( TC_si2quater_23_earfcns() );
10690 execute( TC_si2quater_32_earfcns() );
10691 execute( TC_si2quater_33_earfcns() );
10692 execute( TC_si2quater_42_earfcns() );
10693 execute( TC_si2quater_48_earfcns() );
10694 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010695 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010696 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010697
Harald Welte898113b2018-01-31 18:32:21 +010010698 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010699 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010700 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010701 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010702 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010703 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010704 execute( TC_chan_act_ack_est_ind_noreply() );
10705 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010706 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010707 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010708 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010709 execute( TC_chan_rel_rll_rel_ind() );
10710 execute( TC_chan_rel_conn_fail() );
10711 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010712 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10713 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010714 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010715 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010716 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010717 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010718 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010719 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010720
Harald Weltecfe2c962017-12-15 12:09:32 +010010721 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010722
10723 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010724 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010725 execute( TC_assignment_csd() );
10726 execute( TC_assignment_ctm() );
10727 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010728 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10729 execute( TC_assignment_aoip_tla_v6() );
10730 }
Harald Welte235ebf12017-12-15 14:18:16 +010010731 execute( TC_assignment_fr_a5_0() );
10732 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010733 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010734 execute( TC_assignment_fr_a5_1_codec_missing() );
10735 }
Harald Welte235ebf12017-12-15 14:18:16 +010010736 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010737 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010738 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010739 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010740 execute( TC_ciph_mode_a5_0() );
10741 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010742 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010743 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010744 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010745 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010746
Harald Welte60aa5762018-03-21 19:33:13 +010010747 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010748 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010749 execute( TC_assignment_codec_hr() );
10750 execute( TC_assignment_codec_efr() );
10751 execute( TC_assignment_codec_amr_f() );
10752 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010753
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010754 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010755 execute( TC_assignment_codec_amr_f_S1() );
10756 execute( TC_assignment_codec_amr_h_S1() );
10757 execute( TC_assignment_codec_amr_f_S124() );
10758 execute( TC_assignment_codec_amr_h_S124() );
10759 execute( TC_assignment_codec_amr_f_S0() );
10760 execute( TC_assignment_codec_amr_f_S02() );
10761 execute( TC_assignment_codec_amr_f_S024() );
10762 execute( TC_assignment_codec_amr_f_S0247() );
10763 execute( TC_assignment_codec_amr_h_S0() );
10764 execute( TC_assignment_codec_amr_h_S02() );
10765 execute( TC_assignment_codec_amr_h_S024() );
10766 execute( TC_assignment_codec_amr_h_S0247() );
10767 execute( TC_assignment_codec_amr_f_S01234567() );
10768 execute( TC_assignment_codec_amr_f_S0234567() );
10769 execute( TC_assignment_codec_amr_f_zero() );
10770 execute( TC_assignment_codec_amr_f_unsupp() );
10771 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010772 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10773 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010774 execute( TC_assignment_codec_amr_f_start_mode_4() );
10775 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010776 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010777 }
Harald Welte60aa5762018-03-21 19:33:13 +010010778
Philipp Maierac09bfc2019-01-08 13:41:39 +010010779 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10780 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10781 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10782 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10783 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10784 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10785 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10786 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10787 execute( TC_assignment_codec_req_hr_fr() );
10788 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010789 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10790 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10791 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010792
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010793 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010794
Harald Welte898113b2018-01-31 18:32:21 +010010795 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010796 execute( TC_rll_est_ind_inact_lchan() );
10797 execute( TC_rll_est_ind_inval_sapi1() );
10798 execute( TC_rll_est_ind_inval_sapi3() );
10799 execute( TC_rll_est_ind_inval_sacch() );
10800
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010801 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10802 execute( TC_tch_dlci_link_id_sapi() );
10803
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010804 /* SAPI N Reject triggered by RLL establishment failures */
10805 execute( TC_rll_rel_ind_sapi_n_reject() );
10806 execute( TC_rll_err_ind_sapi_n_reject() );
10807 execute( TC_rll_timeout_sapi_n_reject() );
10808
Harald Welte898113b2018-01-31 18:32:21 +010010809 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010810 execute( TC_paging_imsi_nochan() );
10811 execute( TC_paging_tmsi_nochan() );
10812 execute( TC_paging_tmsi_any() );
10813 execute( TC_paging_tmsi_sdcch() );
10814 execute( TC_paging_tmsi_tch_f() );
10815 execute( TC_paging_tmsi_tch_hf() );
10816 execute( TC_paging_imsi_nochan_cgi() );
10817 execute( TC_paging_imsi_nochan_lac_ci() );
10818 execute( TC_paging_imsi_nochan_ci() );
10819 execute( TC_paging_imsi_nochan_lai() );
10820 execute( TC_paging_imsi_nochan_lac() );
10821 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010822 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10823 execute( TC_paging_imsi_nochan_rnc() );
10824 execute( TC_paging_imsi_nochan_lac_rnc() );
10825 execute( TC_paging_imsi_nochan_lacs() );
10826 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010827 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010828 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010829 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010830 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010831 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010832
10833 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010834 execute( TC_rsl_unknown_unit_id() );
10835
10836 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010837
10838 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010839 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010840 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010841 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010842 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010843 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010844 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010845
Harald Welte261af4b2018-02-12 21:20:39 +010010846 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010847 execute( TC_ho_int_a5_0() );
10848 execute( TC_ho_int_a5_1() );
10849 execute( TC_ho_int_a5_3() );
10850 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010851 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010852
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010010853 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010854 execute( TC_ho_out_fail_no_msc_response() );
10855 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010856 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010857
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010858 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010859 execute( TC_ho_into_this_bsc_a5_0() );
10860 execute( TC_ho_into_this_bsc_a5_1() );
10861 execute( TC_ho_into_this_bsc_a5_3() );
10862 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010863 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10864 execute( TC_ho_into_this_bsc_tla_v6() );
10865 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010866 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010867 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010868 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10869 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010870 execute( TC_ho_in_fail_msc_clears() );
10871 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10872 execute( TC_ho_in_fail_no_detect() );
10873 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010874
Neels Hofmeyr91401012019-07-11 00:42:35 +020010875 execute( TC_ho_neighbor_config_1() );
10876 execute( TC_ho_neighbor_config_2() );
10877 execute( TC_ho_neighbor_config_3() );
10878 execute( TC_ho_neighbor_config_4() );
10879 execute( TC_ho_neighbor_config_5() );
10880 execute( TC_ho_neighbor_config_6() );
10881 execute( TC_ho_neighbor_config_7() );
10882
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010883 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010884 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010885 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010886
10887 execute( TC_dyn_pdch_ipa_act_deact() );
10888 execute( TC_dyn_pdch_ipa_act_nack() );
10889 execute( TC_dyn_pdch_osmo_act_deact() );
10890 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010010891 execute( TC_dyn_ts_sdcch8_act_deact() );
10892 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
10893 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
10894 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010895
Stefan Sperling0796a822018-10-05 13:01:39 +020010896 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010897 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010898
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010899 /* Power control related */
10900 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010901 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010902
10903 /* MSC pooling */
10904 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10905 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10906 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10907 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10908 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10909 execute( TC_mscpool_L3Compl_on_1_msc() );
10910 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10911 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10912 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10913 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10914 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10915 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10916 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10917 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10918 execute( TC_mscpool_paging_and_response_imsi() );
10919 execute( TC_mscpool_paging_and_response_tmsi() );
10920 execute( TC_mscpool_no_allow_attach_round_robin() );
10921 execute( TC_mscpool_no_allow_attach_valid_nri() );
10922 }
10923
Harald Welte99f3ca02018-06-14 13:40:29 +020010924 execute( TC_early_conn_fail() );
10925 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010926 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010927
Philipp Maier783681c2020-07-16 16:47:06 +020010928 /* Emergency call handling (deny / allow) */
10929 execute( TC_assignment_emerg_setup_allow() );
10930 execute( TC_assignment_emerg_setup_deny_msc() );
10931 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010932 execute( TC_emerg_premption() );
10933
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010934 /* Frequency hopping parameters handling */
10935 execute( TC_fh_params_chan_activ() );
10936 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010937 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010938 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010939 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010940
10941 if (mp_enable_lcs_tests) {
10942 execute( TC_lcs_loc_req_for_active_ms() );
10943 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10944 execute( TC_lcs_loc_req_for_idle_ms() );
10945 execute( TC_lcs_loc_req_no_subscriber() );
10946 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10947 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10948 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10949 execute( TC_cm_service_during_lcs_loc_req() );
10950 execute( TC_ho_during_lcs_loc_req() );
10951 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010952
10953 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010954
10955 execute( TC_refuse_chan_act_to_vamos() );
10956 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010957
10958 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010959
10960 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010961
10962 execute( TC_imm_ass_post_chan_ack() );
10963 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010964 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010965 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010966 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010967
10968 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010969
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010970 execute( TC_ratectr_all_available_allocated() );
10971 execute( TC_ratectr_all_available_allocated_dyn() );
10972
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010973 execute( TC_cm_serv_rej() );
10974
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010975 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010010976
10977 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
10978 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
10979 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010010980}
10981
10982}