blob: b34ad29bcd48a5ed58563deb1eee943088f22798 [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 Hofmeyrb7581872021-11-07 14:02:49 +0100767}
768
769function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
770 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000771 log("initial bts rate counters: ", g_ctr_bts);
772 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;
777 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, bts_names);
778 log("initial bts rate counters: ", g_ctr_bts);
779 f_ctrs_bsc_init(counternames_bsc_bts_handover);
780}
781
782private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000783 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100784}
785
786private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
787 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000788 f_ctrs_bsc_add(countername, val);
789}
790
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100791function f_ctrs_bts_verify() runs on test_CT {
792 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
793}
794
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000795/* f_ctrs_bsc_and_bts_init();
796 * f_do_thing(on_bts := 0);
797 * f_do_thing(on_bts := 0);
798 * f_do_other(on_bts := 1);
799 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
800 * f_ctrs_bsc_and_bts_add(1, "other");
801 * f_ctrs_bsc_and_bts_verify();
802 */
803private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100804 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000805 f_ctrs_bsc_verify();
806}
807
808/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
809 * f_ctrs_bsc_and_bts_init();
810 * f_do_thing(on_bts := 0);
811 * f_do_thing(on_bts := 0);
812 * f_do_thing(on_bts := 0);
813 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
814 */
815private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
816 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
817 f_ctrs_bsc_and_bts_verify();
818}
819
820
821/* Convenience functions for rate counters using g_ctr_bsc. */
822
823private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
824 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
825 log("initial bsc rate counters: ", g_ctr_bsc);
826}
827
828private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
829 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
830}
831
832/* f_ctrs_bsc_init();
833 * f_do_thing();
834 * f_do_thing();
835 * f_do_other();
836 * f_ctrs_bsc_add("thing", 2);
837 * f_ctrs_bsc_add("other");
838 * f_ctrs_bsc_verify();
839 */
840private function f_ctrs_bsc_verify() runs on test_CT {
841 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
842}
843
844/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
845 * f_ctrs_bsc_init();
846 * f_do_thing();
847 * f_ctrs_bsc_expect("thing", 1);
848 */
849private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
850 f_ctrs_bsc_add(countername, val);
851 f_ctrs_bsc_verify();
852}
853
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200854
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200855friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200856 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100857 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200858 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100859}
860
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200861private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100862 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200863 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100864 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200865 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
866 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100867 T.start;
868 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200869 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
870 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200871 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100872 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200873 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200874 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100875 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200876 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200877 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100878 repeat;
879 }
880 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200881 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200882 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200883 /* If we received a RESET after ours was sent, it
884 may be a race condition where the other peer beacame
885 available after we sent it, but we are in a desired
886 state anyway, so go forward. */
887 if (not reset_received) {
888 setverdict(fail);
889 }
890 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100891 }
Harald Welte28d943e2017-11-25 15:00:50 +0100892}
893
Harald Welteae026692017-12-09 01:03:01 +0100894type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100895 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100896 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100897 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100898 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100899 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100900 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100901 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100902 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100903}
904
Harald Welte21b46bd2017-12-17 19:46:32 +0100905/*! Start the IPA/RSL related bits for one IPA_Client.
906 * \param clnt IPA_Client for which to establish
907 * \param bsc_host IP address / hostname of the BSC
908 * \param bsc_port TCP port number of the BSC
909 * \param i number identifying this BTS
910 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100911function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
912 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100913runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100914 timer T := 10.0;
915
Harald Welte96c94412017-12-09 03:12:45 +0100916 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100917 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
918 clnt.ccm_pars := c_IPA_default_ccm_pars;
919 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
920 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100921 if (handler_mode) {
922 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100923 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100924 }
Harald Welteae026692017-12-09 01:03:01 +0100925
926 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100927 if (handler_mode) {
928 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
929 } else {
930 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
931 }
Harald Welteae026692017-12-09 01:03:01 +0100932
Harald Welte5d1a2202017-12-13 19:51:29 +0100933 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100934 if (handler_mode) {
935 clnt.vc_RSL.start(RSL_Emulation.main());
936 return;
937 }
Harald Welteae026692017-12-09 01:03:01 +0100938
939 /* wait for IPA RSL link to connect and send ID ACK */
940 T.start;
941 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700942 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100943 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700944 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100945 }
Harald Welte60e823a2017-12-10 14:10:59 +0100946 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100947 [] IPA_RSL[i].receive { repeat }
948 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100949 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200950 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100951 }
952 }
953}
954
Harald Welte12055472018-03-17 20:10:08 +0100955function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
956 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
957 return;
958 }
959 clnt.vc_IPA.stop;
960 if (isbound(clnt.vc_RSL)) {
961 clnt.vc_RSL.stop;
962 }
963}
964
Harald Welte21b46bd2017-12-17 19:46:32 +0100965/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100966function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
967 timer T := secs_max;
968 T.start;
969 while (true) {
970 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
971 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100972 /* the 'degraded' state exists from OML connection time, and we have to wait
973 * until all MO's are initialized */
974 T.start(1.0);
975 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100976 return;
977 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100978 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100979 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100980 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200981 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100982 }
983 }
984}
985
Harald Welte21b46bd2017-12-17 19:46:32 +0100986/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100987altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100988 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100989 [] T_guard.timeout {
990 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200991 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100992 }
Harald Welte60e823a2017-12-10 14:10:59 +0100993 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200994 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100995 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200996 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100997 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100998 }
Harald Welte28d943e2017-11-25 15:00:50 +0100999}
1000
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001001altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001002 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001003 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001004 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001005 }
1006}
1007
Daniel Willmann191e0d92018-01-17 12:44:35 +01001008function f_init_mgcp(charstring id) runs on test_CT {
1009 id := id & "-MGCP";
1010
1011 var MGCPOps ops := {
1012 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1013 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1014 };
1015 var MGCP_conn_parameters mgcp_pars := {
1016 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001017 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001018 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001019 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001020 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1021 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001022 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001023 };
1024
1025 vc_MGCP := MGCP_Emulation_CT.create(id);
1026 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1027}
1028
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001029/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1030 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1031 * OsmuxCID IE.
1032 */
1033private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1034 f_vty_enter_cfg_msc(BSCVTY, 0);
1035 if (allow) {
1036 f_vty_transceive(BSCVTY, "osmux on");
1037 } else {
1038 f_vty_transceive(BSCVTY, "osmux off");
1039 }
1040 f_vty_transceive(BSCVTY, "exit");
1041 f_vty_transceive(BSCVTY, "exit");
1042 g_osmux_enabled := allow;
1043}
1044
Max2253c0b2018-11-06 19:28:05 +01001045function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001046 if (BSCVTY.checkstate("Mapped")) {
1047 /* skip initialization if already executed once */
1048 return;
1049 }
Harald Weltebc03c762018-02-12 18:09:38 +01001050 map(self:BSCVTY, system:BSCVTY);
1051 f_vty_set_prompts(BSCVTY);
1052 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001053 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1054 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001055}
1056
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001057friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001058{
1059 // log on TTCN3 log output
1060 log(log_msg);
1061 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001062 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001063}
1064
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001065private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1066{
1067 if (rsl_idx >= lengthof(g_system_information)) {
1068 g_system_information[rsl_idx] := SystemInformationConfig_omit
1069 }
1070 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1071}
1072
1073altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1074 var ASP_RSL_Unitdata rx_rsl_ud;
1075
1076 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1077 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1078 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1079 repeat;
1080 }
1081 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1082 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1083 repeat;
1084 }
1085 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1086 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1087 repeat;
1088 }
1089 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1090 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1091 repeat;
1092 }
1093
1094 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1095 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1096 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1097 repeat;
1098 }
1099 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1100 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1101 repeat;
1102 }
1103 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1104 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1105 repeat;
1106 }
1107 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1108 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1109 repeat;
1110 }
1111}
1112
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001113/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1114private type record of boolean my_BooleanList;
1115
1116private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1117{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001118 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1119
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001120 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001121 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1122 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1123 * stepping into that config node. */
1124 log("msc ", msc_nr, " is not configured, skipping");
1125 continue;
1126 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001127 f_vty_enter_cfg_msc(pt, msc_nr);
1128 if (allow_attach_list[msc_nr]) {
1129 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1130 f_vty_transceive(pt, "allow-attach", strict := false);
1131 } else {
1132 f_vty_transceive(pt, "no allow-attach", strict := false);
1133 }
1134 f_vty_transceive(pt, "exit");
1135 f_vty_transceive(pt, "exit");
1136 }
1137}
1138
Harald Welte21b46bd2017-12-17 19:46:32 +01001139/* global initialization function
1140 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001141 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1142 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1143 */
1144function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001145 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001146 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001147
Harald Welteae026692017-12-09 01:03:01 +01001148 if (g_initialized) {
1149 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001150 }
Harald Welteae026692017-12-09 01:03:01 +01001151 g_initialized := true;
1152
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001153 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001154 activate(as_Tguard());
1155
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001156 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001157 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001158
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001159 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001160 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1161
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001162 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1163 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1164 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1165 }
1166
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001167 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001168 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001169 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1170 * MSC-side BSSAP emulation */
1171 if (handler_mode) {
1172 var RanOps ranops := MSC_RanOps;
1173 ranops.use_osmux := g_osmux_enabled;
1174 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1175 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1176 f_ran_adapter_start(g_bssap[bssap_idx]);
1177 } else {
1178 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1179 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1180 f_ran_adapter_start(g_bssap[bssap_idx]);
1181 f_legacy_bssap_reset();
1182 }
Harald Welte67089ee2018-01-17 22:19:03 +01001183 }
Harald Welted5833a82018-05-27 16:52:56 +02001184
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001185 if (mp_enable_lcs_tests) {
1186 if (handler_mode) {
1187 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1188 } else {
1189 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1190 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1191 }
1192 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001193 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001194
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001195 /* start the test with exactly all enabled MSCs allowed to attach */
1196 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1197
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001198 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001199
Daniel Willmann191e0d92018-01-17 12:44:35 +01001200 f_init_mgcp("VirtMSC");
1201
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001202 for (var integer i := 0; i < nr_bts; i := i+1) {
1203 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001204 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001205}
Harald Welte696ddb62017-12-08 14:01:43 +01001206
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001207function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1208runs on test_CT {
1209 /* wait until osmo-bts-omldummy has respawned */
1210 f_wait_oml(bts_idx, "degraded", 5.0);
1211
1212 /* start RSL connection */
1213 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1214 /* wait until BSC tells us "connected" */
1215 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001216}
1217
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001218function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1219 template SystemInformationConfig expect_si)
1220runs on test_CT {
1221 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1222
1223 f_init_bts(bts_idx, handler_mode);
1224
1225 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1226 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1227 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1228 */
1229 f_sleep(5.0);
1230 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1231
1232 deactivate(sysinfo);
1233
1234 if (match(g_system_information[bts_idx], expect_si)) {
1235 setverdict(pass);
1236 } else {
1237 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1238 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1239 setverdict(fail, "received SI does not match expectations");
1240 return;
1241 }
1242}
1243
Maxd4e56962018-10-31 19:08:25 +01001244/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001245function 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 +01001246runs on test_CT return RSL_Message {
1247 var ASP_RSL_Unitdata rx_rsl_ud;
1248 timer T := t_secs;
1249
1250 T.start;
1251 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001252 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001253 T.stop;
1254 }
1255 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001256 [] T.timeout {
1257 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001258 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001259 }
Harald Welteae026692017-12-09 01:03:01 +01001260 }
1261 return rx_rsl_ud.rsl;
1262}
1263
Harald Welte21b46bd2017-12-17 19:46:32 +01001264/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001265function 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 +01001266runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001267 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001268}
1269
1270
Harald Welte4003d112017-12-09 22:35:39 +01001271/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001272testcase TC_chan_act_noreply() runs on test_CT {
1273 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001274 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001275
Harald Welte89d42e82017-12-17 16:42:41 +01001276 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001277
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001278 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001279 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001280 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001281}
1282
Harald Welte4003d112017-12-09 22:35:39 +01001283/* verify if the "chreq:total" counter increments as expected */
1284testcase TC_chan_act_counter() runs on test_CT {
1285 var BSSAP_N_UNITDATA_ind ud_ind;
1286 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001287 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001288
Harald Welte89d42e82017-12-17 16:42:41 +01001289 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001290
1291 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001292 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001293 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001294 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1295
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001296 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001297}
1298
Harald Welteae026692017-12-09 01:03:01 +01001299/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001300private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001301 var RSL_Message rx_rsl;
1302
Harald Welteae026692017-12-09 01:03:01 +01001303 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001304 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001305
1306 /* expect BSC to disable the channel again if there's no RLL EST IND */
1307 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1308
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001309 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001310}
1311
Philipp Maier9c60a622020-07-09 15:08:46 +02001312/* Normal variant */
1313testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001314 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001315 f_TC_chan_act_ack_noest();
1316}
1317
1318/* Emergency call variant */
1319testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1320 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001321 f_init(1);
1322 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001323 f_TC_chan_act_ack_noest(ra := 'A5'O);
1324}
1325
Philipp Maier606f07d2020-08-12 17:21:58 +02001326/* Emergency call variant, but emergency calls are not allowed */
1327testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1328 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1329
1330 var RSL_Message rx_rsl;
1331 var GsmRrMessage rr;
1332
1333 f_init(1);
1334 f_vty_allow_emerg_bts(false, 0);
1335
1336 IPA_RSL[0].clear;
1337 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1338
1339 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1340 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1341 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1342 setverdict(pass);
1343 } else {
1344 setverdict(fail, "immediate assignment not rejected");
1345 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001346
1347 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001348}
1349
Harald Welteae026692017-12-09 01:03:01 +01001350/* Test behavior if MSC never answers to CR */
1351testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001352 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1353 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001354 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001355 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001356
Harald Welte89d42e82017-12-17 16:42:41 +01001357 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001358
1359 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001360 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001361
1362 var octetstring l3 := '00010203040506'O
1363 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1364
1365 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1366
1367 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001368 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001369 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001370 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001371}
1372
1373/* Test behavior if MSC answers with CREF to CR */
1374testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1375 var BSSAP_N_CONNECT_ind rx_c_ind;
1376 var RSL_Message rx_rsl;
1377
Harald Welte89d42e82017-12-17 16:42:41 +01001378 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001379
1380 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001381 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001382
1383 var octetstring l3 := '00010203040506'O
1384 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1385
1386 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1387 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1388
1389 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001390 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001391 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001392}
1393
Harald Welte618ef642017-12-14 14:58:20 +01001394/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1395testcase TC_chan_act_nack() runs on test_CT {
1396 var RSL_Message rx_rsl;
1397 var integer chact_nack;
1398
Harald Welte89d42e82017-12-17 16:42:41 +01001399 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001400
1401 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1402
1403 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1404 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1405 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1406
1407 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1408
1409 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1410 f_sleep(0.5);
1411
1412 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1413
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001414 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001415}
1416
Harald Welte799c97b2017-12-14 17:50:30 +01001417/* Test for channel exhaustion due to RACH overload */
1418testcase TC_chan_exhaustion() runs on test_CT {
1419 var ASP_RSL_Unitdata rsl_ud;
1420 var integer i;
1421 var integer chreq_total, chreq_nochan;
1422
Harald Welte89d42e82017-12-17 16:42:41 +01001423 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001424
1425 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1426 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1427
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001428 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001429 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1430 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001431 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 +01001432 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001433 }
1434
1435 IPA_RSL[0].clear;
1436
Harald Weltedd8cbf32018-01-28 12:07:52 +01001437 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001438 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001439
1440 /* now expect additional channel activations to fail */
1441 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1442
1443 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001444 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001445 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1446 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001447 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001448 var GsmRrMessage rr;
1449 /* match on IMM ASS REJ */
1450 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1451 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1452 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001453 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001454 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1455 chreq_nochan+1);
1456 setverdict(pass);
1457 } else {
1458 repeat;
1459 }
1460 }
1461 [] IPA_RSL[0].receive { repeat; }
1462 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001463 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001464}
1465
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001466/* Test channel deactivation due to silence from MS */
1467testcase TC_chan_deact_silence() runs on test_CT {
1468 var RslChannelNr chan_nr;
1469
1470 f_init(1);
1471
1472 /* Request for a dedicated channel */
1473 chan_nr := f_chreq_act_ack('23'O);
1474
1475 /* Wait some time until the channel is released */
1476 f_sleep(2.0);
1477
1478 /* Expect CHANnel RELease */
1479 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001480 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001481 log("Received CHANnel RELease");
1482 setverdict(pass);
1483 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001484 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001485 /* See OS#3709, OsmoBSC should not send Immediate
1486 * Assignment Reject since a dedicated channel was
1487 * already allocated, and Immediate Assignment was
1488 * already sent. */
1489 setverdict(fail, "Unexpected Immediate Assignment!");
1490 }
1491 [] IPA_RSL[0].receive {
1492 setverdict(fail, "Unexpected RSL message!");
1493 }
1494 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001495 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001496}
1497
Harald Weltecfe2c962017-12-15 12:09:32 +01001498/***********************************************************************
1499 * Assignment Testing
1500 ***********************************************************************/
1501
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001502/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1503 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001504testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001505 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001506
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001507 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1508 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001509 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001510 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001511}
1512
Harald Welte16a4adf2017-12-14 18:54:01 +01001513/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001514testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001515 var BSSAP_N_CONNECT_ind rx_c_ind;
1516 var RSL_Message rx_rsl;
1517 var DchanTuple dt;
1518
Harald Welte89d42e82017-12-17 16:42:41 +01001519 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001520
1521 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001522 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001523 /* send assignment without AoIP IEs */
1524 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1525 } else {
1526 /* Send assignmetn without CIC in IPA case */
1527 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1528 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1529 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1530 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001531 alt {
1532 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1533 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1534 }
Harald Welte235ebf12017-12-15 14:18:16 +01001535 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001536 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1537 setverdict(pass);
1538 }
1539 [] BSSAP.receive { repeat; }
1540 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001541 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001542}
1543
Harald Welteed848512018-05-24 22:27:58 +02001544/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001545function 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 +02001546 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001547 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001548 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001549 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001550 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001551 if (osmux_enabled) {
1552 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1553 } else {
1554 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1555 }
Harald Welteed848512018-05-24 22:27:58 +02001556 } else {
1557 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001558 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001559 }
1560 return ass_cmd;
1561}
1562
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001563function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001564 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1565 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001566 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001567
1568 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1569 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1570 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1571 var template BSSMAP_IE_KC128 kc128 := omit;
1572 if (ispresent(enc)) {
1573 var TestHdlrEncrParams v_enc := valueof(enc);
1574 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1575 chosenEncryptionAlgorithm := valueof(
1576 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001577 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001578 if (ispresent(v_enc.enc_kc128)) {
1579 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1580 }
1581 }
1582
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001583 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001584 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001585 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001586 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1587 encryptionInformation := encryptionInformation,
1588 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1589 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001590 } else {
1591 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001592 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1593 encryptionInformation := encryptionInformation,
1594 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1595 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001596 }
1597 return ho_req;
1598}
1599
Harald Welteed848512018-05-24 22:27:58 +02001600/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001601function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001602 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001603 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001604 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001605 if (expect_osmux) {
1606 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1607 } else {
1608 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1609 }
Harald Welteed848512018-05-24 22:27:58 +02001610 } else {
1611 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001612 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001613 }
1614 return exp_compl;
1615}
1616
Harald Welte235ebf12017-12-15 14:18:16 +01001617/* Run everything required up to sending a caller-specified assignment command and expect response */
1618function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1619runs on test_CT {
1620 var BSSAP_N_CONNECT_ind rx_c_ind;
1621 var RSL_Message rx_rsl;
1622 var DchanTuple dt;
1623
Harald Welte89d42e82017-12-17 16:42:41 +01001624 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001625
1626 dt := f_est_dchan('23'O, 23, '00000000'O);
1627 /* send assignment without AoIP IEs */
1628 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1629 alt {
1630 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1631 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1632 setverdict(pass);
1633 } else {
1634 setverdict(fail, fail_text);
1635 }
1636 }
1637 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1638 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1639 setverdict(pass);
1640 } else {
1641 setverdict(fail, fail_text);
1642 }
1643 }
1644 [] BSSAP.receive { repeat; }
1645 }
1646}
1647testcase TC_assignment_csd() runs on test_CT {
1648 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001649 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001650 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1651 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1652 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001653 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001654}
1655
1656testcase TC_assignment_ctm() runs on test_CT {
1657 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001658 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001659 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1660 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1661 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001662 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001663}
1664
Harald Welte4003d112017-12-09 22:35:39 +01001665type record DchanTuple {
1666 integer sccp_conn_id,
1667 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001668}
1669
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001670type record of DchanTuple DchanTuples;
1671
Harald Welted6939652017-12-13 21:02:46 +01001672/* Send CHAN RQD and wait for allocation; acknowledge it */
1673private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1674runs on test_CT return RslChannelNr {
1675 var RSL_Message rx_rsl;
1676 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1677 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1678 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1679 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001680 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001681 return chan_nr;
1682}
1683
Harald Welte4003d112017-12-09 22:35:39 +01001684/* helper function to establish a dedicated channel via BTS and MSC */
1685function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1686runs on test_CT return DchanTuple {
1687 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001688 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001689
Harald Welte4003d112017-12-09 22:35:39 +01001690 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001691 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001692
1693 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1694
1695 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1696 dt.sccp_conn_id := rx_c_ind.connectionId;
1697 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1698
1699 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001700}
1701
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001702/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1703function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1704runs on test_CT return DchanTuple {
1705 var BSSAP_N_CONNECT_ind rx_c_ind;
1706 var DchanTuple dt;
1707
1708 /* Send CHAN RQD */
1709 var RSL_Message rx_rsl;
1710 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1711
1712 /* The dyn TS first deactivates PDCH */
1713 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1714 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1715 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1716
1717 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1718 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1719
1720 /* Now activates the signalling channel */
1721 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1722 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1723
1724 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1725
1726 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1727 dt.sccp_conn_id := rx_c_ind.connectionId;
1728 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1729
1730 return dt;
1731}
1732
Harald Welte641fcbe2018-06-14 10:58:35 +02001733/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1734private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1735 var RSL_Message rx_rsl;
1736 /* expect BSC to disable the channel */
1737 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1738 /* respond with CHAN REL ACK */
1739 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1740
1741 /* expect Clear Complete from BSC */
1742 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1743
1744 /* MSC disconnects as instructed. */
1745 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1746}
1747
Harald Welte4003d112017-12-09 22:35:39 +01001748/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1749testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001750 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001751 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001752
Harald Welte89d42e82017-12-17 16:42:41 +01001753 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001754
Harald Welte4003d112017-12-09 22:35:39 +01001755 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1756
1757 /* simulate RLL REL IND */
1758 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1759
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001760 /* expect Clear Request on MSC side */
1761 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1762
1763 /* Instruct BSC to clear channel */
1764 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1765 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1766
Harald Welte4003d112017-12-09 22:35:39 +01001767 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001768 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001769
1770 /* wait for SCCP emulation to do its job */
1771 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001772
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001773 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001774}
1775
1776/* Test behavior of channel release after CONN FAIL IND from BTS */
1777testcase TC_chan_rel_conn_fail() runs on test_CT {
1778 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001779 var DchanTuple dt;
1780
Harald Welte89d42e82017-12-17 16:42:41 +01001781 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001782
1783 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1784
1785 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001786 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 +01001787 /* TODO: different cause values? */
1788
Harald Welte4003d112017-12-09 22:35:39 +01001789 /* expect Clear Request from BSC */
1790 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1791
1792 /* Instruct BSC to clear channel */
1793 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1794 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1795
Harald Welte6ff76ea2018-01-28 13:08:01 +01001796 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001797 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001798
1799 /* wait for SCCP emulation to do its job */
1800 f_sleep(1.0);
1801
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001802 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001803}
1804
Harald Welte99f3ca02018-06-14 13:40:29 +02001805/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1806/* See also https://www.osmocom.org/issues/3182 */
1807testcase TC_early_conn_fail() runs on test_CT {
1808 var RSL_Message rx_rsl;
1809 var DchanTuple dt;
1810
1811 f_init(1);
1812
1813 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001814 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001815
1816 /* BTS->BSC: simulate CONN FAIL IND */
1817 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1818
1819 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1820 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1821
1822 /* BTS<-BSC: respond with CHAN REL ACK */
1823 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1824
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001825 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001826}
1827
1828/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1829/* See also https://www.osmocom.org/issues/3182 */
1830testcase TC_late_conn_fail() runs on test_CT {
1831 var RSL_Message rx_rsl;
1832 var DchanTuple dt;
1833
1834 f_init(1);
1835
1836 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1837
1838 /* BSC<-MSC: Instruct BSC to clear connection */
1839 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1840
1841 /* BTS->BSC: expect BSC to deactivate SACCH */
1842 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1843
1844 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1845 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1846
1847 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1848 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1849 /* BTS->BSC: respond with CHAN REL ACK */
1850 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1851
1852 /* BSC->MSC: expect Clear Complete from BSC */
1853 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1854
1855 /* BSC<-MSC: MSC disconnects as requested. */
1856 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1857
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001858 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001859}
1860
Oliver Smithaf03bef2021-08-24 15:34:51 +02001861private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1862 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1863 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1864
1865 f_statsd_reset();
1866
1867 /* Establish SDCCH */
1868 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1869 f_establish_fully(ass_cmd, exp_fail);
1870
1871 /* Expect stats to be 0 */
1872 var StatsDExpects expect := {
1873 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1874 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1875 };
1876 f_statsd_expect(expect);
1877
1878 /* Simulate CONN FAIL IND on SDCCH */
1879 RSL.send(ts_ASP_RSL_UD(
1880 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1881 IPAC_PROTO_RSL_TRX0));
1882
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001883 f_sleep(1.0);
1884
Oliver Smithaf03bef2021-08-24 15:34:51 +02001885 /* Expect stats to be 1 */
1886 expect := {
1887 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1888 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1889 };
1890 f_statsd_expect(expect);
1891}
1892testcase TC_stats_conn_fail() runs on test_CT {
1893 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1894 var MSC_ConnHdlr vc_conn;
1895
1896 f_init(1, true);
1897 f_sleep(1.0);
1898
1899 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1900 vc_conn.done;
1901
1902 f_shutdown_helper();
1903}
1904
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001905function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001906 boolean expect_deact_sacch := true,
1907 boolean expect_rr_chan_rel := true,
1908 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001909 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001910 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001911 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001912 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001913
1914 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001915 var boolean got_deact_sacch := false;
1916 var boolean got_rr_chan_rel := false;
1917 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001918 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001919 var RSL_IE_Body l3_ie;
1920 var PDU_ML3_NW_MS l3;
1921 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001922 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1923 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001924 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001925 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001926 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001927 repeat;
1928 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001929 [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 +01001930 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001931
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001932 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1933 setverdict(fail, "cannot find L3");
1934 mtc.stop;
1935 }
1936 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1937
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001938 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001939 var CellSelIndValue cells := dec_CellSelIndValue(
1940 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1941
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001942 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1943 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001944 setverdict(pass);
1945 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001946 log("EXPECTED CELLS: ", expect_cells);
1947 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001948 }
1949 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001950
1951 if (not istemplatekind(expect_rr_cause, "omit")) {
1952 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1953 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1954 if (match(got_cause, expect_rr_cause)) {
1955 setverdict(pass);
1956 } else {
1957 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1958 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1959 }
1960 }
Harald Welte99787102019-02-04 10:41:36 +01001961 repeat;
1962 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001963 [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 +01001964 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001965
1966 if (not istemplatekind(expect_rr_cause, "omit")) {
1967 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1968 setverdict(fail, "cannot find L3");
1969 mtc.stop;
1970 }
1971 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1972
1973 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1974 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1975 if (match(got_cause, expect_rr_cause)) {
1976 setverdict(pass);
1977 } else {
1978 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1979 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1980 }
1981 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001982 repeat;
1983 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001984 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001985 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001986 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001987 if (handle_rll_rel) {
1988 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1989 }
Harald Welte91d54a52018-01-28 15:35:07 +01001990 repeat;
1991 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001992 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001993 /* respond with CHAN REL ACK */
1994 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1995 }
1996 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001997 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001998 repeat;
1999 }
2000 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002001
2002 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2003 " got_rll_rel_req=", got_rll_rel_req);
2004
2005 if (expect_deact_sacch != got_deact_sacch) {
2006 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2007 }
2008 if (expect_rr_chan_rel != got_rr_chan_rel) {
2009 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2010 }
2011 if (expect_rll_rel_req != got_rll_rel_req) {
2012 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2013 }
Harald Welte91d54a52018-01-28 15:35:07 +01002014}
2015
Harald Welte4003d112017-12-09 22:35:39 +01002016/* Test behavior of channel release after hard Clear Command from MSC */
2017testcase TC_chan_rel_hard_clear() runs on test_CT {
2018 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002019 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002020
Harald Welte89d42e82017-12-17 16:42:41 +01002021 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002022
2023 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2024
2025 /* Instruct BSC to clear channel */
2026 var BssmapCause cause := 0;
2027 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2028
2029 /* expect Clear Complete from BSC on A */
2030 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2031 /* release the SCCP connection */
2032 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2033 }
2034
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002035 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002036 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002037}
2038
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002039function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2040 var BSSAP_N_DATA_ind rx_di;
2041 var DchanTuple dt;
2042
2043 f_init(1);
2044
2045 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2046 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2047 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2048 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2049
2050 /* Instruct BSC to clear channel */
2051 var BssmapCause cause := 0;
2052 if (tx_csfb_ind) {
2053 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2054 } else {
2055 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2056 }
2057
2058 /* expect Clear Complete from BSC on A */
2059 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2060 /* release the SCCP connection */
2061 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2062 }
2063
2064 /* 1 neighbor is added by default in osmo-bts.cfg and
2065 SystemInformationConfig_default, use that: */
2066 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2067
2068 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2069 f_shutdown_helper();
2070}
2071
2072/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2073 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2074 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2075 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2076 Indicator or not shouldn't matter at all. */
2077testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2078 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2079}
2080
2081/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2082 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2083 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2084 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2085testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2086 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2087}
2088
2089/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2090 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2091 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2092 CSFB Indicator should not be used anymore, and hence, there should be no
2093 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2094 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002095testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2096 var BSSAP_N_DATA_ind rx_di;
2097 var DchanTuple dt;
2098
2099 f_init(1);
2100
2101 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2102
2103 /* Instruct BSC to clear channel */
2104 var BssmapCause cause := 0;
2105 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2106
2107 /* expect Clear Complete from BSC on A */
2108 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2109 /* release the SCCP connection */
2110 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2111 }
2112
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002113 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002114 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002115}
2116
Harald Welted8c36cd2017-12-09 23:05:31 +01002117/* Test behavior of channel release after hard RLSD from MSC */
2118testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002119 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002120
Harald Welte89d42e82017-12-17 16:42:41 +01002121 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002122
2123 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2124
2125 /* release the SCCP connection */
2126 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2127
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002128 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002129 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002130}
2131
Harald Welte550daf92018-06-11 19:22:13 +02002132/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2133testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2134 var DchanTuple dt;
2135
2136 f_init(1);
2137
2138 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2139
2140 /* release the SCCP connection */
2141 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2142
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002143 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002144 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002145}
2146
Harald Welte85804d42017-12-10 14:11:58 +01002147/* Test behavior of channel release after BSSMAP RESET from MSC */
2148testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002149 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002150
Harald Welte89d42e82017-12-17 16:42:41 +01002151 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002152
2153 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2154
2155 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2156 IPA_RSL[0].clear;
2157
2158 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002159 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 +01002160 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002161 [] 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 +01002162 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2163 }
2164
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002165 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002166 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002167}
2168
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002169/* Verify T(iar) triggers and releases the channel */
2170testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2171 var DchanTuple dt;
2172
2173 /* Set T(iar) in BSC low enough that it will trigger before other side
2174 has time to keep alive with a T(ias). Keep recommended ratio of
2175 T(iar) >= T(ias)*2 */
2176 g_bsc_sccp_timer_ias := 2;
2177 g_bsc_sccp_timer_iar := 5;
2178
2179 f_init(1);
2180
2181 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2182 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002183 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002184}
2185
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002186private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2187runs on test_CT
2188{
2189 var DchanTuple dt;
2190
2191 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2192 var BssmapCause cause := 0;
2193 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2194 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2195 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2196 }
2197
2198 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 +02002199}
2200
2201/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2202testcase TC_chan_rel_rr_cause() runs on test_CT {
2203 f_init(1);
2204
2205 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2206 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2207 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2208 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2209 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2210 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002211
2212 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002213}
2214
Harald Welte5cd20ed2017-12-13 21:03:20 +01002215/* Test behavior if RSL EST IND for non-active channel */
2216testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2217 timer T := 2.0;
2218
Harald Welte89d42e82017-12-17 16:42:41 +01002219 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002220
2221 var octetstring l3 := '00010203040506'O;
2222 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2223 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2224
2225 T.start;
2226 alt {
2227 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2228 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2229 }
2230 [] BSSAP.receive {}
2231 [] IPA_RSL[0].receive {}
2232 [] T.timeout {}
2233 }
2234
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002235 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002236}
2237
2238/* Test behavior if RSL EST IND for invalid SAPI */
2239testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2240 var RslChannelNr chan_nr;
2241
Harald Welte89d42e82017-12-17 16:42:41 +01002242 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002243
2244 chan_nr := f_chreq_act_ack()
2245
2246 var octetstring l3 := '00010203040506'O;
2247 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2248
2249 timer T := 2.0;
2250 T.start;
2251 alt {
2252 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2253 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2254 }
2255 [] BSSAP.receive { repeat; }
2256 [] IPA_RSL[0].receive { repeat; }
2257 [] T.timeout {}
2258 }
2259
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002260 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002261}
2262
2263/* Test behavior if RSL EST IND for invalid SAPI */
2264testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2265 timer T := 2.0;
2266
Harald Welte89d42e82017-12-17 16:42:41 +01002267 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002268
2269 var RslChannelNr chan_nr := f_chreq_act_ack();
2270
2271 var octetstring l3 := '00010203040506'O;
2272 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2273
2274 T.start;
2275 alt {
2276 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2277 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2278 }
2279 [] BSSAP.receive { repeat; }
2280 [] IPA_RSL[0].receive { repeat; }
2281 [] T.timeout {}
2282 }
2283
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002284 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002285}
2286
2287/* Test behavior if RSL EST IND for invalid SACCH */
2288testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2289 timer T := 2.0;
2290
Harald Welte89d42e82017-12-17 16:42:41 +01002291 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002292
2293 var RslChannelNr chan_nr := f_chreq_act_ack();
2294
2295 var octetstring l3 := '00010203040506'O;
2296 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2297
2298 T.start;
2299 alt {
2300 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2301 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2302 }
2303 [] BSSAP.receive { repeat; }
2304 [] IPA_RSL[0].receive { repeat; }
2305 [] T.timeout {}
2306 }
2307
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002308 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002309}
2310
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002311/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2312private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2313 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2314 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2315
2316 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2317 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2318
2319 f_establish_fully(ass_cmd, exp_compl);
2320
2321 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2322 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2323 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2324 BSSAP.receive(PDU_BSSAP:{
2325 discriminator := '1'B,
2326 spare := '0000000'B,
2327 dlci := 'C3'O,
2328 lengthIndicator := ?,
2329 pdu := { dtap := '0904'O }
2330 });
2331
2332 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2333 for (var integer i := 0; i < 32; i := i + 1) {
2334 var octetstring l3 := '09'O & f_rnd_octstring(14);
2335 var template (value) RslLinkId link_id;
2336 var template (value) OCT1 dlci;
2337
2338 if (i mod 2 == 0) {
2339 /* SAPI0 on FACCH or SDCCH */
2340 link_id := ts_RslLinkID_DCCH(0);
2341 dlci := '80'O;
2342 } else {
2343 /* SAPI3 on SACCH */
2344 link_id := ts_RslLinkID_SACCH(3);
2345 dlci := 'C3'O;
2346 }
2347
2348 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002349 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002350 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002351 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002352 }
2353}
2354testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2355 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2356 var MSC_ConnHdlr vc_conn;
2357
2358 f_init(1, true);
2359 f_sleep(1.0);
2360
2361 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2362 vc_conn.done;
2363
2364 f_shutdown_helper();
2365}
2366
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002367private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2368 template myBSSMAP_Cause cause := ?,
2369 float T_val := 2.0)
2370runs on test_CT {
2371 var BSSAP_N_DATA_ind rx_di;
2372 timer T;
2373
2374 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2375 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2376
2377 T.start(T_val);
2378 alt {
2379 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2380 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2381 if (not match(rx_cause, tr_cause)) {
2382 setverdict(fail, "Rx unexpected Cause IE: ",
2383 rx_cause, " vs expected ", tr_cause);
2384 }
2385 setverdict(pass);
2386 }
2387 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2388 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2389 }
2390 [] T.timeout {
2391 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2392 }
2393 }
2394}
2395
2396/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2397testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2398 var octetstring rnd_data := f_rnd_octstring(16);
2399 var RSL_Message rx_rsl;
2400 var DchanTuple dt;
2401
2402 f_init(1);
2403
2404 /* MS establishes a SAPI=0 link on DCCH */
2405 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2406
2407 /* MSC sends some data on (not yet established) SAPI=3 link */
2408 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2409 /* BSC attempts to establish a SAPI=3 link on DCCH */
2410 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2411
2412 /* MS sends unexpected RELease INDication on SAPI=3 */
2413 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2414 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2415 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2416
2417 /* Clean up the connection */
2418 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2419 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2420
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002421 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002422}
2423
2424/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2425testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2426 var octetstring rnd_data := f_rnd_octstring(16);
2427 var RSL_Message rx_rsl;
2428 var DchanTuple dt;
2429
2430 f_init(1);
2431
2432 /* MS establishes a SAPI=0 link on DCCH */
2433 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2434
2435 /* MSC sends some data on (not yet established) SAPI=3 link */
2436 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2437 /* BSC attempts to establish a SAPI=3 link on DCCH */
2438 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2439
2440 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2441 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2442 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2443 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2444
2445 /* Clean up the connection */
2446 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2447 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2448
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002449 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002450}
2451
2452/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2453testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2454 var octetstring rnd_data := f_rnd_octstring(16);
2455 var RSL_Message rx_rsl;
2456 var DchanTuple dt;
2457
2458 f_init(1);
2459
2460 /* MS establishes a SAPI=0 link on DCCH */
2461 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2462
2463 /* MSC sends some data on (not yet established) SAPI=3 link */
2464 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2465 /* BSC attempts to establish a SAPI=3 link on DCCH */
2466 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2467
2468 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2469 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2470
2471 /* Clean up the connection */
2472 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2473 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2474
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002475 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002476}
2477
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002478testcase TC_si_default() runs on test_CT {
2479 f_init(0);
2480 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002481 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002482}
Harald Welte4003d112017-12-09 22:35:39 +01002483
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002484/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2485 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2486private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2487{
2488 select (earfcn_index) {
2489 case (0) {
2490 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2491 return 111;
2492 }
2493 case (1) {
2494 return 1;
2495 }
2496 case (2) {
2497 return 0;
2498 }
2499 case (3) {
2500 return 65535;
2501 }
2502 case else {
2503 return 23 * (earfcn_index - 3);
2504 }
2505 }
2506}
2507
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002508function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2509 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002510
2511 f_init(0);
2512
2513 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2514 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002515 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2516 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002517 }
2518
2519 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2520
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002521 if (not istemplatekind(expect_cells, "omit")) {
2522 /* Also check that RR Channel Release contains these EARFCNs.
2523 * (copied code from TC_chan_rel_hard_clear_csfb) */
2524 var BSSAP_N_DATA_ind rx_di;
2525 var DchanTuple dt;
2526
2527 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002528 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2529 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2530 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002531
2532 /* Instruct BSC to clear channel */
2533 var BssmapCause cause := 0;
2534 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2535
2536 /* expect Clear Complete from BSC on A */
2537 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2538 /* release the SCCP connection */
2539 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2540 }
2541
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002542 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 +02002543 }
2544
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002545 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002546 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 +02002547 }
2548}
2549
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002550private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2551{
2552 var template SI2quaterRestOctetsList si2quater := {};
2553 var integer si2quater_count := (count + 2) / 3;
2554
2555 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002556 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002557 var integer index := i / 3;
2558 var integer earfcn_index := i mod 3;
2559 if (index >= lengthof(si2quater)) {
2560 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2561 }
2562 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);
2563 }
2564
2565 return si2quater;
2566}
2567
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002568private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2569{
2570 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2571
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002572 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002573 for (var integer i := 0; i < count; i := i + 1) {
2574 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002575 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002576 }
2577
2578 return tr_CellSelIndValue_EUTRAN(cells);
2579}
2580
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002581private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2582{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002583 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002584 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002585 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2586 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002587}
2588
2589testcase TC_si2quater_2_earfcns() runs on test_CT {
2590 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002591 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002592}
2593
2594testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002595 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002596 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002597}
2598
2599testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002600 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002601 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002602}
2603
2604testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002605 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002606 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002607}
2608
2609testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002610 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002611 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002612}
2613
2614testcase TC_si2quater_12_earfcns() runs on test_CT {
2615 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002616 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002617}
2618
2619testcase TC_si2quater_23_earfcns() runs on test_CT {
2620 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002621 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002622}
2623
2624testcase TC_si2quater_32_earfcns() runs on test_CT {
2625 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002626 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002627}
2628
2629testcase TC_si2quater_33_earfcns() runs on test_CT {
2630 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002631 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002632}
2633
2634testcase TC_si2quater_42_earfcns() runs on test_CT {
2635 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002636 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002637}
2638
2639testcase TC_si2quater_48_earfcns() runs on test_CT {
2640 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002641 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002642}
2643
2644/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2645 * 48 EARFCNs. */
2646testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002647 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002648 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2649 f_init(0);
2650
2651 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002652 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2653 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002654 }
2655
2656 /* The 49th EARFCN no longer fits, expect VTY error */
2657 f_vty_enter_cfg_bts(BSCVTY, 0);
2658 var charstring vty_error;
2659 vty_error := f_vty_transceive_ret(BSCVTY,
2660 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2661 f_vty_transceive(BSCVTY, "end");
2662
2663 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2664 log("Got expected VTY error: ", vty_error);
2665 setverdict(pass);
2666 } else {
2667 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2668 }
2669
2670 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2671
2672 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002673 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 +02002674 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002675 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002676}
2677
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002678private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2679{
2680 var uint8_t count := 0;
2681 for (var integer i := 5; i < 16; i := i + 1) {
2682 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2683 count := count + 1;
2684 }
2685 }
2686 return count;
2687}
2688
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002689private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2690{
2691 var ASP_RSL_Unitdata rx_rsl_ud;
2692 var SystemInformationType1 last_si1;
2693
2694 timer T := 30.0;
2695 T.start;
2696 alt {
2697 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2698 tr_RSL_BCCH_INFO,
2699 tr_RSL_NO_SACCH_FILL,
2700 tr_RSL_SACCH_FILL))
2701 ) -> value rx_rsl_ud {
2702 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2703 if (g_system_information[rsl_idx].si1 == omit) {
2704 repeat;
2705 }
2706 last_si1 := g_system_information[rsl_idx].si1;
2707 g_system_information[rsl_idx].si1 := omit;
2708 T.stop;
2709 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002710 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002711 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2712 }
2713 return last_si1;
2714}
2715
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002716/* verify ACC rotate feature */
2717testcase TC_si_acc_rotate() runs on test_CT {
2718 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002719 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002720 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002721 var uint8_t count;
2722 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2723
2724 f_init(0, guard_timeout := 60.0);
2725
2726 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2727 "access-control-class-rotate 3",
2728 "access-control-class-rotate-quantum 1"});
2729
2730 /* Init and get first sysinfo */
2731 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2732
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002733 for (var integer i:= 0; i < 20; i := i + 1) {
2734 last_si1 := f_recv_next_si1(0);
2735 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002736 count := f_acc09_count_allowed(acc);
2737 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2738
2739 if (count != 3) {
2740 log("RSL: EXPECTED SI ACC len=3");
2741 setverdict(fail, "received SI does not match expectations");
2742 break;
2743 }
2744
2745 for (var integer j := 0; j < 10; j := j + 1) {
2746 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2747 times_allowed[j] := times_allowed[j] + 1;
2748 }
2749 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002750 }
2751
2752 for (var integer j := 0; j < 10; j := j + 1) {
2753 log("ACC", j, " allowed ", times_allowed[j], " times" );
2754 if (j != 5 and times_allowed[j] < 3) {
2755 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2756 } else if (j == 5 and times_allowed[j] > 0) {
2757 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2758 }
2759 }
2760
2761 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2762 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002763 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002764}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002765
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002766/* verify ACC startup ramp+rotate feature */
2767testcase TC_si_acc_ramp_rotate() runs on test_CT {
2768 var template SystemInformationConfig sic := SystemInformationConfig_default;
2769 var SystemInformationType1 last_si1;
2770 var AccessControlClass acc;
2771 var ASP_RSL_Unitdata rx_rsl_ud;
2772 var uint8_t count;
2773 var uint8_t prev_count;
2774 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2775
2776 f_init(0, guard_timeout := 80.0);
2777
2778 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2779 "access-control-class-rotate 0",
2780 "access-control-class-rotate-quantum 1",
2781 "access-control-class-ramping",
2782 "access-control-class-ramping-step-interval 5",
2783 "access-control-class-ramping-step-size 5"});
2784
2785 /* Init and get first sysinfo */
2786 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2787 last_si1 := g_system_information[0].si1;
2788 acc := last_si1.rach_control.acc;
2789 count := f_acc09_count_allowed(acc);
2790 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2791 while (count > 0) {
2792 last_si1 := f_recv_next_si1(0);
2793 acc := last_si1.rach_control.acc;
2794 count := f_acc09_count_allowed(acc);
2795 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2796 }
2797
2798 /* Increase adm subset size, we should see ramping start up */
2799 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2800 prev_count := 0;
2801 while (true) {
2802 last_si1 := f_recv_next_si1(0);
2803 acc := last_si1.rach_control.acc;
2804 count := f_acc09_count_allowed(acc);
2805 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2806
2807 if (prev_count > count) {
2808 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2809 break;
2810 }
2811
2812 if (count == 9) {
2813 break; /* Maximum reached (10 - 1 perm barred), done here */
2814 }
2815
2816 prev_count := count;
2817 }
2818
2819 setverdict(pass);
2820
2821 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2822 "rach access-control-class 4 allowed",
2823 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002824 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002825}
2826
Harald Welte4003d112017-12-09 22:35:39 +01002827testcase TC_ctrl_msc_connection_status() runs on test_CT {
2828 var charstring ctrl_resp;
2829
Harald Welte89d42e82017-12-17 16:42:41 +01002830 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002831
2832 /* See https://osmocom.org/issues/2729 */
2833 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002834 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002835}
2836
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002837testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2838 var charstring ctrl_resp;
2839
2840 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002841
2842 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002843 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002844}
2845
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002846/* Verify correct stats on the number of configured and connected MSCs */
2847private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2848 g_pars := f_gen_test_hdlr_pars();
2849 var StatsDExpects expect := {
2850 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2851 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2852 };
2853 f_statsd_expect(expect);
2854}
2855
2856private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2857{
2858 var MSC_ConnHdlr vc_conn;
2859
2860 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2861 f_sleep(1.0);
2862 vc_conn := f_start_handler(tc_fn);
2863 vc_conn.done;
2864
2865 /* Also verify stat exposed on CTRL interface */
2866 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2867 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2868
2869 f_shutdown_helper();
2870}
2871
2872/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2873private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2874 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2875}
2876testcase TC_stat_num_msc_connected_1() runs on test_CT {
2877 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2878}
2879
2880/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2881private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2882 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2883}
2884testcase TC_stat_num_msc_connected_2() runs on test_CT {
2885 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2886}
2887
2888/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2889private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2890 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2891}
2892testcase TC_stat_num_msc_connected_3() runs on test_CT {
2893 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2894}
2895
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002896/* Verify correct stats on the number of configured and connected MSCs */
2897private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
2898 g_pars := f_gen_test_hdlr_pars();
2899 var StatsDExpects expect := {
2900 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
2901 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2902 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
2903 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2904 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
2905 };
2906 f_statsd_expect(expect);
2907}
2908
2909private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
2910 var MSC_ConnHdlr vc_conn;
2911
2912 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
2913 f_sleep(1.0);
2914 vc_conn := f_start_handler(tc_fn);
2915 vc_conn.done;
2916
2917 /* Also verify stat exposed on CTRL interface */
2918 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
2919 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
2920 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
2921 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
2922
Neels Hofmeyra41ae302021-09-06 22:06:02 +02002923 /* Verify rf_states exposed on CTRL interface */
2924 var charstring expect_net_rf_states := "";
2925 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
2926 var charstring expect_bts_rf_states := int2str(i) & ",0,";
2927 if (i < NUM_BTS) {
2928 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
2929 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
2930 } else {
2931 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
2932 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
2933 }
2934 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
2935 expect_bts_rf_states := expect_bts_rf_states & "on,";
2936 if (i < nr_bts) {
2937 /* For BTS where RSL is connected, the RSL state will be "up" */
2938 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
2939 } else {
2940 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
2941 }
2942
2943 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
2944 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
2945 }
2946 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
2947
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002948 f_shutdown_helper();
2949}
2950
2951/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
2952private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
2953 f_tc_stat_num_bts_connected_msc_connhdlr(1);
2954}
2955testcase TC_stat_num_bts_connected_1() runs on test_CT {
2956 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
2957}
2958
2959/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
2960private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
2961 f_tc_stat_num_bts_connected_msc_connhdlr(2);
2962}
2963testcase TC_stat_num_bts_connected_2() runs on test_CT {
2964 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
2965}
2966
2967/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
2968private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
2969 f_tc_stat_num_bts_connected_msc_connhdlr(3);
2970}
2971testcase TC_stat_num_bts_connected_3() runs on test_CT {
2972 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
2973}
2974
Harald Welte4003d112017-12-09 22:35:39 +01002975testcase TC_ctrl() runs on test_CT {
2976 var charstring ctrl_resp;
2977
Harald Welte89d42e82017-12-17 16:42:41 +01002978 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002979
2980 /* all below values must match the osmo-bsc.cfg config file used */
2981
Harald Welte6a129692018-03-17 17:30:14 +01002982 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2983 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002984 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002985
2986 var integer bts_nr := 0;
2987 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2988 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2989 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2990 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2991 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2992 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2993 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2994
2995 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2996 f_sleep(2.0);
2997 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2998 setverdict(fail, "oml-uptime not incrementing as expected");
2999 }
3000 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3001
3002 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3003
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003004 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003005}
3006
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003007/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3008 "location-state" over the SCCPlite IPA conn */
3009testcase TC_ctrl_location() runs on test_CT {
3010 var MSC_ConnHdlr vc_conn;
3011 var integer bts_nr := 0;
3012
3013 f_init(1, true);
3014 f_sleep(1.0);
3015
3016 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3017 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3018 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3019
3020 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3021 f_sleep(2.0);
3022
3023 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3024 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3025 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3026
3027 /* should match the one from config */
3028 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3029
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003030 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003031}
3032
Harald Welte6f521d82017-12-11 19:52:02 +01003033
3034/***********************************************************************
3035 * Paging Testing
3036 ***********************************************************************/
3037
3038type record Cell_Identity {
3039 GsmMcc mcc,
3040 GsmMnc mnc,
3041 GsmLac lac,
3042 GsmCellId ci
3043};
Harald Welte24135bd2018-03-17 19:27:53 +01003044private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003045private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003046
Harald Welte5d1a2202017-12-13 19:51:29 +01003047type set of integer BtsIdList;
3048
3049private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3050 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3051 if (bts_id == bts_ids[j]) {
3052 return true;
3053 }
3054 }
3055 return false;
3056}
Harald Welte6f521d82017-12-11 19:52:02 +01003057
3058/* core paging test helper function; used by most paging test cases */
3059private function f_pageing_helper(hexstring imsi,
3060 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003061 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003062 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003063 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003064{
3065 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003066 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003067 var RSL_Message rx_rsl;
3068 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003069 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003070
3071 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003072
3073 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003074 for (i := 0; i < NUM_BTS; i := i + 1) {
3075 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003076 }
Harald Welte6f521d82017-12-11 19:52:02 +01003077
3078 if (isvalue(rsl_chneed)) {
3079 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3080 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3081 } else {
3082 bssmap_chneed := omit;
3083 }
3084
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003085 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3086 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003087
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003088 if (not istemplatekind(tmsi, "omit")) {
3089 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003090 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003091 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003092 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003093
Harald Welte5d1a2202017-12-13 19:51:29 +01003094 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003095 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003096 /* check channel type, paging group */
3097 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3098 setverdict(fail, "Paging for wrong paging group");
3099 }
3100 if (ispresent(rsl_chneed) and
3101 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3102 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3103 }
Harald Welte6f521d82017-12-11 19:52:02 +01003104 }
Harald Welte2fccd982018-01-31 15:48:19 +01003105 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003106 /* do a quick check on all not-included BTSs if they received paging */
3107 for (i := 0; i < NUM_BTS; i := i + 1) {
3108 timer T := 0.1;
3109 if (f_bts_in_list(i, bts_ids)) {
3110 continue;
3111 }
3112 T.start;
3113 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003114 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003115 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3116 }
3117 [] IPA_RSL[i].receive { repeat; }
3118 [] T.timeout { }
3119 }
Harald Welte6f521d82017-12-11 19:52:02 +01003120 }
3121
3122 setverdict(pass);
3123}
3124
Harald Welte5d1a2202017-12-13 19:51:29 +01003125const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003126const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003127const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3128const BtsIdList c_BtsId_LAC2 := { 2 };
3129
Harald Welte6f521d82017-12-11 19:52:02 +01003130/* PAGING by IMSI + TMSI */
3131testcase TC_paging_imsi_nochan() runs on test_CT {
3132 var BSSMAP_FIELD_CellIdentificationList cid_list;
3133 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003134 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003135 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003136}
3137
3138/* PAGING by IMSI + TMSI */
3139testcase TC_paging_tmsi_nochan() runs on test_CT {
3140 var BSSMAP_FIELD_CellIdentificationList cid_list;
3141 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003142 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003143 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003144}
3145
3146/* Paging with different "channel needed' values */
3147testcase TC_paging_tmsi_any() runs on test_CT {
3148 var BSSMAP_FIELD_CellIdentificationList cid_list;
3149 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003150 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003151 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003152}
3153testcase TC_paging_tmsi_sdcch() runs on test_CT {
3154 var BSSMAP_FIELD_CellIdentificationList cid_list;
3155 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003156 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003157 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003158}
3159testcase TC_paging_tmsi_tch_f() runs on test_CT {
3160 var BSSMAP_FIELD_CellIdentificationList cid_list;
3161 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003162 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003163 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003164}
3165testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3166 var BSSMAP_FIELD_CellIdentificationList cid_list;
3167 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003168 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003169 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003170}
3171
3172/* Paging by CGI */
3173testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3174 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3175 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003176 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003177 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003178}
3179
3180/* Paging by LAC+CI */
3181testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3182 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3183 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003184 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003185 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003186}
3187
3188/* Paging by CI */
3189testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3190 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3191 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003192 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003193 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003194}
3195
3196/* Paging by LAI */
3197testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3198 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3199 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003200 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003201 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003202}
3203
3204/* Paging by LAC */
3205testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3206 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3207 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003208 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003209 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003210}
3211
3212/* Paging by "all in BSS" */
3213testcase TC_paging_imsi_nochan_all() runs on test_CT {
3214 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3215 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003216 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003217 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003218}
3219
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003220/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003221testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3222 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3223 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 +01003224 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003225 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003226}
Harald Welte6f521d82017-12-11 19:52:02 +01003227
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003228/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003229testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3230 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3231 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003232 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003233 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003234}
3235
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003236/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003237testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3238 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3239 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003240 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003241 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003242}
3243
Harald Welte6f521d82017-12-11 19:52:02 +01003244/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003245testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3246 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3247 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3248 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003249 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003250}
3251
3252/* Paging on empty list: Verify none of them page */
3253testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3254 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3255 cid_list := { cIl_LAC := { } };
3256 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003257 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003258}
3259
Stefan Sperling049a86e2018-03-20 15:51:00 +01003260/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3261testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3262 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3263 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3264 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3265 f_shutdown_helper();
3266}
3267
Harald Welte6f521d82017-12-11 19:52:02 +01003268/* Verify paging retransmission interval + count */
3269/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003270/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003271
Harald Weltee65d40e2017-12-13 00:09:06 +01003272/* Verify PCH load */
3273testcase TC_paging_imsi_load() runs on test_CT {
3274 var BSSMAP_FIELD_CellIdentificationList cid_list;
3275 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003276 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003277 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003278 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003279
3280 /* tell BSC there is no paging space anymore */
3281 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003282 f_sleep(0.2);
3283 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003284
3285 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3286 * there would be 8 retransmissions during 4 seconds */
3287 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003288 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003289 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003290 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003291 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003292 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003293 }
Harald Welte2caa1062018-03-17 18:19:05 +01003294 [] T_retrans.timeout {
3295 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3296 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3297 T_retrans.start;
3298 repeat;
3299 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003300 [] T.timeout {
3301 setverdict(pass);
3302 }
3303 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003304
3305 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003306}
3307
Harald Welte235ebf12017-12-15 14:18:16 +01003308/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003309testcase TC_paging_counter() runs on test_CT {
3310 var BSSMAP_FIELD_CellIdentificationList cid_list;
3311 timer T := 4.0;
3312 var integer i;
3313 var integer paging_attempted_bsc;
3314 var integer paging_attempted_bts[NUM_BTS];
3315 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");
3322 for (i := 0; i < NUM_BTS; i := i+1) {
3323 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3324 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3325 }
3326
3327 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3328
3329 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3330 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3331 for (i := 0; i < NUM_BTS; i := i+1) {
3332 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3333 paging_attempted_bts[i]+1);
3334 }
3335
3336 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3337 f_sleep(12.0);
3338 for (i := 0; i < NUM_BTS; i := i+1) {
3339 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3340 paging_expired_bts[i]+1);
3341 }
Harald Welte1ff69992017-12-14 12:31:17 +01003342
Philipp Maier282ca4b2018-02-27 17:17:00 +01003343 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003344}
3345
3346
Harald Welte10985002017-12-12 09:29:15 +01003347/* Verify paging stops after A-RESET */
3348testcase TC_paging_imsi_a_reset() runs on test_CT {
3349 var BSSMAP_FIELD_CellIdentificationList cid_list;
3350 timer T := 3.0;
3351 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003352 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003353
3354 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003355 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 +01003356 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003357 [] 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 +01003358 [] BSSAP.receive { repeat; }
3359 }
3360
Daniel Willmanncbef3982018-07-30 09:22:40 +02003361 /* Wait to avoid a possible race condition if a paging message is
3362 * received right before the reset ACK. */
3363 f_sleep(0.2);
3364
Harald Welte10985002017-12-12 09:29:15 +01003365 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003366 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3367 IPA_RSL[i].clear;
3368 }
Harald Welte10985002017-12-12 09:29:15 +01003369
3370 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3371 T.start;
3372 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003373 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003374 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003375 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003376 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003377 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003378 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003379 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003380 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003381 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003382 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003383 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003384 }
Harald Welte10985002017-12-12 09:29:15 +01003385 [] T.timeout {
3386 setverdict(pass);
3387 }
3388 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003389
3390 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003391}
Harald Welteae026692017-12-09 01:03:01 +01003392
Philipp Maierf45824a2019-08-14 14:44:10 +02003393/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3394 * paging response we can not know which MSC is in charge, so we will blindly
3395 * pick the first configured MSC. This behavior is required in order to make
3396 * MT-CSFB calls working because in those cases the BSC can not know that the
3397 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3398 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003399 */
3400testcase TC_paging_resp_unsol() runs on test_CT {
3401
3402 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003403 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003404
3405 var BSSAP_N_CONNECT_ind rx_c_ind;
3406 var DchanTuple dt;
3407 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003408 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003409
3410 /* Send CHAN RQD and wait for allocation; acknowledge it */
3411 dt.rsl_chan_nr := f_chreq_act_ack();
3412
3413 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3414 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3415
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003416
Philipp Maierf45824a2019-08-14 14:44:10 +02003417 /* Expevct a CR with a matching Paging response on the A-Interface */
3418 T.start;
3419 alt {
3420 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3421 setverdict(pass);
3422 }
3423 [] BSSAP.receive {
3424 setverdict(fail, "Received unexpected message on A-Interface!");
3425 }
3426 [] T.timeout {
3427 setverdict(fail, "Received nothing on A-Interface!");
3428 }
3429 }
3430
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003431 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003432}
3433
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003434/* Test RSL link drop causes counter increment */
3435testcase TC_rsl_drop_counter() runs on test_CT {
3436 var integer rsl_fail;
3437
Harald Welte89d42e82017-12-17 16:42:41 +01003438 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003439
3440 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3441
3442 bts[0].rsl.vc_IPA.stop;
3443
3444 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3445
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003446 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003447}
3448
3449/* TODO: Test OML link drop causes counter increment */
3450
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003451/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3452function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3453 timer T := 10.0;
3454
3455 bts[0].rsl.id := "IPA-0-RSL";
3456 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3457 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3458 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003459 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003460
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003461 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003462
3463 f_init_mgcp("VirtMSC");
3464
3465 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3466 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3467 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3468 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3469
3470 /* wait for IPA OML link to connect and then disconnect */
3471 T.start;
3472 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003473 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003474 T.stop;
3475 return true;
3476 }
3477 [] IPA_RSL[0].receive { repeat }
3478 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003479 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003480 }
3481 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003482 return false;
3483}
3484
3485/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3486testcase TC_rsl_unknown_unit_id() runs on test_CT {
3487 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3488 setverdict(pass);
3489 } else {
3490 setverdict(fail, "Timeout RSL waiting for connection to close");
3491 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003492 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003493}
3494
3495
3496/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3497testcase TC_oml_unknown_unit_id() runs on test_CT {
3498 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3499 setverdict(pass);
3500 } else {
3501 setverdict(fail, "Timeout OML waiting for connection to close");
3502 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003503 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003504}
3505
3506
Harald Weltec1a2fff2017-12-17 11:06:19 +01003507/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003508 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003509 ***********************************************************************/
3510
Harald Welte6811d102019-04-14 22:23:14 +02003511import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003512import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003513import from RSL_Emulation all;
3514import from MSC_ConnectionHandler all;
3515
3516type function void_fn(charstring id) runs on MSC_ConnHdlr;
3517
Harald Welte336820c2018-05-31 20:34:52 +02003518/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003519private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3520 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003521 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003522 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003523 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003524 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003525 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3526 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3527 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003528 if (isvalue(bts[2])) {
3529 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3530 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3531 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003532 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003533 if (mp_enable_lcs_tests) {
3534 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3535 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3536 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003537 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003538 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003539 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003540}
3541
Neels Hofmeyrda436782021-07-20 22:09:06 +02003542function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003543runs on test_CT return MSC_ConnHdlr {
3544 var charstring id := testcasename();
3545 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003546 var integer bssap_idx := 0;
3547 if (isvalue(pars)) {
3548 bssap_idx := valueof(pars).mscpool.bssap_idx;
3549 }
Harald Welte336820c2018-05-31 20:34:52 +02003550 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003551 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003552 return vc_conn;
3553}
3554
3555function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3556runs on test_CT return MSC_ConnHdlr {
3557 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003558 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003559 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003560 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003561 return vc_conn;
3562}
3563
Neels Hofmeyrda436782021-07-20 22:09:06 +02003564function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3565runs on test_CT return MSC_ConnHdlr {
3566 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3567}
3568
Harald Weltea0630032018-03-20 21:09:55 +01003569/* first function inside ConnHdlr component; sets g_pars + starts function */
3570private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3571runs on MSC_ConnHdlr {
3572 if (isvalue(pars)) {
3573 g_pars := valueof(pars);
3574 }
3575 fn.apply(id);
3576}
3577
Oliver Smith26a3db72021-07-09 13:51:29 +02003578private function f_vty_encryption_a5(charstring options) runs on test_CT {
3579 f_vty_transceive(BSCVTY, "configure terminal");
3580 f_vty_transceive(BSCVTY, "network");
3581 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3582 f_vty_transceive(BSCVTY, "exit");
3583 f_vty_transceive(BSCVTY, "exit");
3584}
3585
3586private function f_vty_encryption_a5_reset() runs on test_CT {
3587 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3588 f_vty_encryption_a5("0 1 3");
3589}
3590
Harald Welte3c86ea02018-05-10 22:28:05 +02003591/* Establish signalling channel (non-assignment case) followed by cipher mode */
3592private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003593 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3594 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003595 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003596 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3597 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3598 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3599 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003600
Philipp Maier23000732018-05-18 11:25:37 +02003601 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003602}
3603testcase TC_ciph_mode_a5_0() runs on test_CT {
3604 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003605 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003606 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3607
3608 f_init(1, true);
3609 f_sleep(1.0);
3610 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3611 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003612 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003613}
3614testcase TC_ciph_mode_a5_1() runs on test_CT {
3615 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003616 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003617 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3618
3619 f_init(1, true);
3620 f_sleep(1.0);
3621 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3622 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003623 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003624}
Oliver Smith50b98122021-07-09 15:00:28 +02003625/* OS#4975: verify that A5/2 is preferred over A5/0 */
3626testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3627 var MSC_ConnHdlr vc_conn;
3628 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3629
3630 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3631 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3632
3633 f_init(1, true);
3634 f_vty_encryption_a5("0 1 2 3");
3635 f_sleep(1.0);
3636 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3637 vc_conn.done;
3638 f_vty_encryption_a5_reset();
3639 f_shutdown_helper();
3640}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003641/* OS#4975: verify that A5/1 is preferred over A5/2 */
3642testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3643 var MSC_ConnHdlr vc_conn;
3644 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3645
3646 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3647 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3648
3649 f_init(1, true);
3650 f_vty_encryption_a5("1 2");
3651 f_sleep(1.0);
3652 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3653 vc_conn.done;
3654 f_vty_encryption_a5_reset();
3655 f_shutdown_helper();
3656}
Harald Welte3c86ea02018-05-10 22:28:05 +02003657testcase TC_ciph_mode_a5_3() runs on test_CT {
3658 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003659 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003660 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3661
3662 f_init(1, true);
3663 f_sleep(1.0);
3664 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3665 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003666 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003667}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003668/* Establish a Signalling channel with A5/4 encryption. */
3669testcase TC_ciph_mode_a5_4() runs on test_CT {
3670 var MSC_ConnHdlr vc_conn;
3671 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3672 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003673
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003674 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003675 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003676 f_sleep(1.0);
3677 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3678 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003679 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003680 f_shutdown_helper();
3681}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003682/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3683private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3684 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3685 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3686 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3687 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3688
3689 f_establish_fully(ass_cmd, exp_compl);
3690}
3691testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3692 var MSC_ConnHdlr vc_conn;
3693 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3694
3695 f_init(1, true);
3696 f_sleep(1.0);
3697 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3698 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003699 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003700}
3701
Harald Welte3c86ea02018-05-10 22:28:05 +02003702
3703/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003704private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003705 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3706 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003707
Harald Welte552620d2017-12-16 23:21:36 +01003708 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3709 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003710
Harald Weltea0630032018-03-20 21:09:55 +01003711 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003712}
Harald Welte552620d2017-12-16 23:21:36 +01003713testcase TC_assignment_fr_a5_0() runs on test_CT {
3714 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003715 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003716 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003717
Harald Welte89d42e82017-12-17 16:42:41 +01003718 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003719 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003720 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003721 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003722 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003723}
Harald Welte552620d2017-12-16 23:21:36 +01003724testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003725 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003726 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003727 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003728
Harald Welte89d42e82017-12-17 16:42:41 +01003729 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003730 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003731 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3732 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003733 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003734}
3735testcase TC_assignment_fr_a5_3() runs on test_CT {
3736 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003737 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003738 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003739
Harald Welte651fcdc2018-05-10 20:23:16 +02003740 f_init(1, true);
3741 f_sleep(1.0);
3742 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003743 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003744 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003745}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003746/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3747testcase TC_assignment_fr_a5_4() runs on test_CT {
3748 var MSC_ConnHdlr vc_conn;
3749 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3750 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3751
3752 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003753 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003754 f_sleep(1.0);
3755 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3756 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003757 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003758 f_shutdown_helper();
3759}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003760
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003761/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3762testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3763 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3764 var MSC_ConnHdlr vc_conn;
3765
3766 f_init(1, true);
3767 f_sleep(1.0);
3768
3769 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3770 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3771 vc_conn.done;
3772 f_shutdown_helper();
3773}
3774
Harald Welte552620d2017-12-16 23:21:36 +01003775/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3776private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003777 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003778 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003779 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003780
3781 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003782 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3783
Harald Weltea0630032018-03-20 21:09:55 +01003784 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003785}
Harald Welte552620d2017-12-16 23:21:36 +01003786testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3787 var MSC_ConnHdlr vc_conn;
3788
Harald Welte89d42e82017-12-17 16:42:41 +01003789 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003790 f_sleep(1.0);
3791
Harald Welte8863fa12018-05-10 20:15:27 +02003792 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003793 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003794 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003795}
3796
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003797private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3798 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3799 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003800
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003801 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3802 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3803
3804 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3805
3806 var BSSMAP_FIELD_CodecType codecType;
3807 timer T := 10.0;
3808
3809 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3810 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3811
3812 f_create_chan_and_exp();
3813 /* we should now have a COMPL_L3 at the MSC */
3814
3815 var template PDU_BSSAP exp_l3_compl;
3816 exp_l3_compl := tr_BSSMAP_ComplL3()
3817 if (g_pars.aoip == false) {
3818 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3819 } else {
3820 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3821 }
3822 T.start;
3823 alt {
3824 [] BSSAP.receive(exp_l3_compl);
3825 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3826 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3827 }
3828 [] T.timeout {
3829 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3830 }
3831 }
3832
3833 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003834 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003835}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003836testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3837 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003838 var MSC_ConnHdlr vc_conn;
3839
Harald Welte89d42e82017-12-17 16:42:41 +01003840 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003841 f_sleep(1.0);
3842
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003843 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003844 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003845 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003846 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003847}
3848
3849
Harald Welte4532e0a2017-12-23 02:05:44 +01003850private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003851 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003852 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003853 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003854 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003855
3856 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003857 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003858
3859 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003860 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3861 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003862 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3863 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3864 };
3865 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003866}
3867
3868testcase TC_assignment_sign() runs on test_CT {
3869 var MSC_ConnHdlr vc_conn;
3870
3871 f_init(1, true);
3872 f_sleep(1.0);
3873
Harald Welte8863fa12018-05-10 20:15:27 +02003874 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003875 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003876 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003877}
3878
Harald Welte60aa5762018-03-21 19:33:13 +01003879/***********************************************************************
3880 * Codec (list) testing
3881 ***********************************************************************/
3882
3883/* check if the given rsl_mode is compatible with the a_elem */
3884private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3885return boolean {
3886 select (a_elem.codecType) {
3887 case (GSM_FR) {
3888 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3889 return true;
3890 }
3891 }
3892 case (GSM_HR) {
3893 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3894 return true;
3895 }
3896 }
3897 case (GSM_EFR) {
3898 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3899 return true;
3900 }
3901 }
3902 case (FR_AMR) {
3903 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3904 return true;
3905 }
3906 }
3907 case (HR_AMR) {
3908 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3909 return true;
3910 }
3911 }
3912 case else { }
3913 }
3914 return false;
3915}
3916
3917/* check if the given rsl_mode is compatible with the a_list */
3918private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3919return boolean {
3920 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3921 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3922 return true;
3923 }
3924 }
3925 return false;
3926}
3927
3928/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003929function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003930return BSSMAP_IE_ChannelType {
3931 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3932 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3933 select (a_elem.codecType) {
3934 case (GSM_FR) {
3935 ret.channelRateAndType := ChRate_TCHF;
3936 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3937 }
3938 case (GSM_HR) {
3939 ret.channelRateAndType := ChRate_TCHH;
3940 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3941 }
3942 case (GSM_EFR) {
3943 ret.channelRateAndType := ChRate_TCHF;
3944 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3945 }
3946 case (FR_AMR) {
3947 ret.channelRateAndType := ChRate_TCHF;
3948 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3949 }
3950 case (HR_AMR) {
3951 ret.channelRateAndType := ChRate_TCHH;
3952 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3953 }
3954 case else {
3955 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003956 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003957 }
3958 }
3959 return ret;
3960}
3961
Harald Weltea63b9102018-03-22 20:36:16 +01003962private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3963return template RSL_IE_Body {
3964 var template RSL_IE_Body mode_ie := {
3965 chan_mode := {
3966 len := ?,
3967 reserved := ?,
3968 dtx_d := ?,
3969 dtx_u := ?,
3970 spd_ind := RSL_SPDI_SPEECH,
3971 ch_rate_type := -,
3972 coding_alg_rate := -
3973 }
3974 }
3975
3976 select (a_elem.codecType) {
3977 case (GSM_FR) {
3978 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3979 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3980 }
3981 case (GSM_HR) {
3982 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3983 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3984 }
3985 case (GSM_EFR) {
3986 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3987 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3988 }
3989 case (FR_AMR) {
3990 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3991 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3992 }
3993 case (HR_AMR) {
3994 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3995 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3996 }
3997 }
3998 return mode_ie;
3999}
4000
Harald Welte60aa5762018-03-21 19:33:13 +01004001type record CodecListTest {
4002 BSSMAP_IE_SpeechCodecList codec_list,
4003 charstring id
4004}
4005type record of CodecListTest CodecListTests
4006
4007private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004008 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
4009 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01004010
4011 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004012 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004013 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4014 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4015 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004016 if (isvalue(g_pars.expect_mr_s0_s7)) {
4017 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4018 g_pars.expect_mr_s0_s7;
4019 }
Harald Welte79f3f542018-05-25 20:02:37 +02004020 }
Harald Welte60aa5762018-03-21 19:33:13 +01004021 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4022 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004023 log("expecting ASS COMPL like this: ", exp_compl);
4024
4025 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004026
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004027 if (not g_pars.expect_channel_mode_modify) {
4028 /* Verify that the RSL-side activation actually matches our expectations */
4029 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004030
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004031 var RSL_IE_Body mode_ie;
4032 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4033 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004034 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004035 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004036 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4037 if (not match(mode_ie, t_mode_ie)) {
4038 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4039 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004040 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004041
4042 var RSL_IE_Body mr_conf;
4043 if (g_pars.expect_mr_conf_ie != omit) {
4044 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4045 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4046 mtc.stop;
4047 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004048 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004049
4050 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4051 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4052 g_pars.expect_mr_conf_ie);
4053 }
4054 } else {
4055 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4056 log("found RSL MR CONFIG IE: ", mr_conf);
4057 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4058 mtc.stop;
4059 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004060 }
4061 }
Harald Welte60aa5762018-03-21 19:33:13 +01004062}
4063
Philipp Maierd0e64b02019-03-13 14:15:23 +01004064private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4065
4066 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4067 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4068
4069 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004070 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004071 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4072 }
4073 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4074 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4075 log("expecting ASS FAIL like this: ", exp_fail);
4076
4077 f_establish_fully(ass_cmd, exp_fail);
4078}
4079
Harald Welte60aa5762018-03-21 19:33:13 +01004080testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004081 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004082 var MSC_ConnHdlr vc_conn;
4083
4084 f_init(1, true);
4085 f_sleep(1.0);
4086
4087 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004088 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004089 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004090 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004091}
4092
4093testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004094 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004095 var MSC_ConnHdlr vc_conn;
4096
4097 f_init(1, true);
4098 f_sleep(1.0);
4099
4100 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004101 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004102 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004103 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004104}
4105
4106testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004107 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004108 var MSC_ConnHdlr vc_conn;
4109
4110 f_init(1, true);
4111 f_sleep(1.0);
4112
4113 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004114 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004115 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004116 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004117}
4118
Philipp Maierd0e64b02019-03-13 14:15:23 +01004119/* Allow 5,90k only (current default config) */
4120private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004121 f_vty_cfg_msc(BSCVTY, 0, {
4122 "amr-config 12_2k forbidden",
4123 "amr-config 10_2k forbidden",
4124 "amr-config 7_95k forbidden",
4125 "amr-config 7_40k forbidden",
4126 "amr-config 6_70k forbidden",
4127 "amr-config 5_90k allowed",
4128 "amr-config 5_15k forbidden",
4129 "amr-config 4_75k forbidden"
4130 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004131}
4132
4133/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4134 * ("Config-NB-Code = 1") */
4135private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004136 f_vty_cfg_msc(BSCVTY, 0, {
4137 "amr-config 12_2k allowed",
4138 "amr-config 10_2k forbidden",
4139 "amr-config 7_95k forbidden",
4140 "amr-config 7_40k allowed",
4141 "amr-config 6_70k forbidden",
4142 "amr-config 5_90k allowed",
4143 "amr-config 5_15k forbidden",
4144 "amr-config 4_75k allowed"
4145 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004146}
4147
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004148private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4149 var charstring tch;
4150 if (fr) {
4151 tch := "tch-f";
4152 } else {
4153 tch := "tch-h";
4154 }
4155 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4156}
4157
4158/* Set the AMR start-mode for this TCH back to the default configuration. */
4159private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4160 f_vty_amr_start_mode_set(fr, "auto");
4161}
4162
Harald Welte60aa5762018-03-21 19:33:13 +01004163testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004164 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004165 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004166
4167 /* Note: This setups the codec configuration. The parameter payload in
4168 * mr_conf must be consistant with the parameter codecElements in pars
4169 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004170 var RSL_IE_Body mr_conf := {
4171 other := {
4172 len := 2,
4173 payload := '2804'O
4174 }
4175 };
Harald Welte60aa5762018-03-21 19:33:13 +01004176
Philipp Maier7695a0d2018-09-27 17:52:14 +02004177 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004178 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004179 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4180 pars.expect_mr_conf_ie := mr_conf;
4181
Harald Welte60aa5762018-03-21 19:33:13 +01004182 f_init(1, true);
4183 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004184 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004185
Harald Welte8863fa12018-05-10 20:15:27 +02004186 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004187 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004188
4189 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004190 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004191}
4192
4193testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004194 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004195 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004196
4197 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004198 var RSL_IE_Body mr_conf := {
4199 other := {
4200 len := 2,
4201 payload := '2804'O
4202 }
4203 };
Harald Welte60aa5762018-03-21 19:33:13 +01004204
Philipp Maier7695a0d2018-09-27 17:52:14 +02004205 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004206 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004207 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4208 pars.expect_mr_conf_ie := mr_conf;
4209
Harald Welte60aa5762018-03-21 19:33:13 +01004210 f_init(1, true);
4211 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004212 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004213
Harald Welte8863fa12018-05-10 20:15:27 +02004214 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004215 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004216
4217 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004218 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004219}
4220
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004221/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4222testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4223 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4224 var MSC_ConnHdlr vc_conn;
4225
4226 f_init(1, true);
4227 f_sleep(1.0);
4228
4229 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4230 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4231 * expecting a Channel Mode Modify if the channel type is compatible. */
4232 f_disable_all_sdcch();
4233 f_disable_all_tch_h();
4234
4235 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4236 pars.expect_channel_mode_modify := true;
4237 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4238 vc_conn.done;
4239
4240 f_enable_all_sdcch();
4241 f_enable_all_tch();
4242 f_shutdown_helper();
4243}
4244
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004245/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4246testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4247 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4248 var MSC_ConnHdlr vc_conn;
4249
4250 var RSL_IE_Body mr_conf := {
4251 other := {
4252 len := 2,
4253 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4254 }
4255 };
4256
4257 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4258 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4259 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4260 pars.expect_mr_conf_ie := mr_conf;
4261
4262 f_init(1, true);
4263 f_sleep(1.0);
4264
4265 /* First set nonzero start mode bits */
4266 f_vty_amr_start_mode_set(true, "4");
4267 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4268 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4269 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4270 f_vty_amr_start_mode_set(true, "auto");
4271
4272 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4273 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004274
4275 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4276 f_vty_amr_start_mode_set(true, "1");
4277 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004278 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004279}
4280
Neels Hofmeyr21863562020-11-26 00:34:33 +00004281function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4282 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004283runs on test_CT {
4284
4285 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4286 var MSC_ConnHdlr vc_conn;
4287
4288 /* See note above */
4289 var RSL_IE_Body mr_conf := {
4290 other := {
4291 len := lengthof(mrconf),
4292 payload := mrconf
4293 }
4294 };
4295
4296 if (fr) {
4297 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4298 } else {
4299 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4300 }
4301 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4302 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4303 pars.expect_mr_conf_ie := mr_conf;
4304 pars.expect_mr_s0_s7 := exp_s8_s0;
4305
4306 f_init(1, true);
4307 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004308 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004309 f_sleep(1.0);
4310
4311 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4312 vc_conn.done;
4313 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004314 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004315}
4316
4317function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4318runs on test_CT {
4319
4320 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4321 var MSC_ConnHdlr vc_conn;
4322
4323 if (fr) {
4324 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4325 } else {
4326 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4327 }
4328 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4329 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4330
4331 f_init(1, true);
4332 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004333 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004334 f_sleep(1.0);
4335
4336 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4337 vc_conn.done;
4338 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004339 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004340}
4341
4342
4343/* Set S1, we expect an AMR multirate configuration IE with all four rates
4344 * set. */
4345testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004346 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004347 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004348}
4349
4350/* Set S1, we expect an AMR multirate configuration IE with the lower three
4351 * rates set. */
4352testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004353 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004354 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004355}
4356
4357/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4358 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4359testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004360 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004361 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004362}
4363
4364/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4365 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4366testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004367 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004368 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004369}
4370
4371/* The following block of tests selects more and more rates until all four
4372 * possible rates are in the active set (full rate) */
4373testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004374 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004375 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004376}
4377
4378testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004379 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004380 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004381}
4382
4383testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004384 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004385 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004386}
4387
4388testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004389 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004390 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004391}
4392
4393/* The following block of tests selects more and more rates until all three
4394 * possible rates are in the active set (half rate) */
4395testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004396 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004397 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004398}
4399
4400testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004401 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004402 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004403}
4404
4405testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004406 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004407 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004408}
4409
4410/* The following block tests what happens when the MSC does offer rate
4411 * configurations that are not supported by the BSC. Normally such situations
4412 * should not happen because the MSC gets informed by the BSC in advance via
4413 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4414 * to offer rates that are not applicable anyway. */
4415
4416testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004417 /* Try to include 12,2k in into the active set even though the channel
4418 * is half rate only. The BSC is expected to remove the 12,0k */
4419 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004420 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004421}
4422
4423testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004424 /* See what happens when all rates are selected at once. Since then
4425 * Also S1 is selected, this setting will be prefered and we should
4426 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4427 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004428 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004429}
4430
4431testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004432 /* Same as above, but with S1 missing, the MSC is then expected to
4433 * select the currently supported rates, which are also 12.2k, 7,40k,
4434 * 5,90k, and 4,75k, into the active set. */
4435 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004436 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004437}
4438
4439testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004440 /* Try to select no rates at all */
4441 f_TC_assignment_codec_amr_fail(true, '00000000'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_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004446 /* Try to select only unsupported rates */
4447 f_TC_assignment_codec_amr_fail(true, '01101000'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_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004452 /* Try to select 12,2k for half rate */
4453 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004454 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004455}
4456
Neels Hofmeyr21863562020-11-26 00:34:33 +00004457testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4458 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4459 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004460 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004461}
4462
4463testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4464 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'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
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004469testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004470 /* "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 +00004471 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4472 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004473 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004474}
4475
4476testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004477 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4478 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004479 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004480 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004481}
4482
Philipp Maierac09bfc2019-01-08 13:41:39 +01004483private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004484 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4485 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4486 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4487 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004488}
4489
4490private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004491 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4492 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004493}
4494
4495private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004496 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4497 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4498 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4499 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4500 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4501 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004502}
4503
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004504private function f_disable_all_sdcch() runs on test_CT {
4505 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4506 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4507 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4508 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4509}
4510
4511private function f_enable_all_sdcch() runs on test_CT {
4512 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4513 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4514 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4515 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4516}
4517
Philipp Maierac09bfc2019-01-08 13:41:39 +01004518/* Allow HR only */
4519private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4520 g_pars := f_gen_test_hdlr_pars();
4521 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4522 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4523 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4524 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4525 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4526 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4527 f_establish_fully(ass_cmd, exp_compl);
4528}
4529
4530/* Allow FR only */
4531private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4532 g_pars := f_gen_test_hdlr_pars();
4533 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4534 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4535 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4536 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4537 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4538 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4539 f_establish_fully(ass_cmd, exp_compl);
4540}
4541
4542/* Allow HR only (expect assignment failure) */
4543private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4544 g_pars := f_gen_test_hdlr_pars();
4545 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4546 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4547 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4548 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4549 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4550 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4551 f_establish_fully(ass_cmd, exp_fail);
4552}
4553
4554/* Allow FR only (expect assignment failure) */
4555private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4556 g_pars := f_gen_test_hdlr_pars();
4557 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4558 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4559 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4560 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4561 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4562 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4563 f_establish_fully(ass_cmd, exp_fail);
4564}
4565
4566/* Allow FR and HR, but prefer FR */
4567private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4568 g_pars := f_gen_test_hdlr_pars();
4569 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4570 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4571 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4572 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4573 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4574 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4575 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4576 f_establish_fully(ass_cmd, exp_compl);
4577}
4578
4579/* Allow FR and HR, but prefer HR */
4580private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4581 g_pars := f_gen_test_hdlr_pars();
4582 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4583 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4584 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4585 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4586 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4587 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4588 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4589 f_establish_fully(ass_cmd, exp_compl);
4590}
4591
4592/* Allow FR and HR, but prefer FR */
4593private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4594 g_pars := f_gen_test_hdlr_pars();
4595 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4596 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4597 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4598 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4599 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4600 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4601 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4602 f_establish_fully(ass_cmd, exp_compl);
4603}
4604
4605/* Allow FR and HR, but prefer HR */
4606private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4607 g_pars := f_gen_test_hdlr_pars();
4608 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4609 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4610 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4611 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4612 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4613 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4614 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4615 f_establish_fully(ass_cmd, exp_compl);
4616}
4617
4618/* Request a HR channel while all FR channels are exhausted, this is expected
4619 * to work without conflicts */
4620testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4621 var MSC_ConnHdlr vc_conn;
4622 f_init(1, true);
4623 f_sleep(1.0);
4624 f_enable_all_tch();
4625 f_disable_all_tch_f();
4626 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4627 vc_conn.done;
4628 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004629 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004630}
4631
4632/* Request a FR channel while all FR channels are exhausted, this is expected
4633 * to fail. */
4634testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4635 var MSC_ConnHdlr vc_conn;
4636 f_init(1, true);
4637 f_sleep(1.0);
4638 f_enable_all_tch();
4639 f_disable_all_tch_f();
4640 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4641 vc_conn.done;
4642 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004643 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004644}
4645
4646/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4647 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4648testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4649 var MSC_ConnHdlr vc_conn;
4650 f_init(1, true);
4651 f_sleep(1.0);
4652 f_enable_all_tch();
4653 f_disable_all_tch_f();
4654 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4655 vc_conn.done;
4656 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004657 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004658}
4659
4660/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4661 * are exhausted, this is expected to work without conflicts. */
4662testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4663 var MSC_ConnHdlr vc_conn;
4664 f_init(1, true);
4665 f_sleep(1.0);
4666 f_enable_all_tch();
4667 f_disable_all_tch_f();
4668 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4669 vc_conn.done;
4670 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004671 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004672}
4673
4674/* Request a FR channel while all HR channels are exhausted, this is expected
4675 * to work without conflicts */
4676testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4677 var MSC_ConnHdlr vc_conn;
4678 f_init(1, true);
4679 f_sleep(1.0);
4680 f_enable_all_tch();
4681 f_disable_all_tch_h();
4682 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4683 vc_conn.done;
4684 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004685 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004686}
4687
4688/* Request a HR channel while all HR channels are exhausted, this is expected
4689 * to fail. */
4690testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4691 var MSC_ConnHdlr vc_conn;
4692 f_init(1, true);
4693 f_sleep(1.0);
4694 f_enable_all_tch();
4695 f_disable_all_tch_h();
4696 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4697 vc_conn.done;
4698 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004699 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004700}
4701
4702/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4703 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4704testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4705 var MSC_ConnHdlr vc_conn;
4706 f_init(1, true);
4707 f_sleep(1.0);
4708 f_enable_all_tch();
4709 f_disable_all_tch_h();
4710 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4711 vc_conn.done;
4712 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004713 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004714}
4715
4716/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4717 * are exhausted, this is expected to work without conflicts. */
4718testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4719 var MSC_ConnHdlr vc_conn;
4720 f_init(1, true);
4721 f_sleep(1.0);
4722 f_enable_all_tch();
4723 f_disable_all_tch_h();
4724 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4725 vc_conn.done;
4726 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004727 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004728}
4729
4730/* Allow FR and HR, but prefer HR */
4731private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4732 g_pars := f_gen_test_hdlr_pars();
4733 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4734 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4735 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4736 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4737 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4738 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4739 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4740 f_establish_fully(ass_cmd, exp_compl);
4741}
4742
4743/* Allow FR and HR, but prefer FR */
4744private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4745 g_pars := f_gen_test_hdlr_pars();
4746 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4747 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4748 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4749 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4750 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4751 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4752 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4753 f_establish_fully(ass_cmd, exp_compl);
4754}
4755
4756/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4757 * HR, which is the prefered type, is selected. */
4758testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4759 var MSC_ConnHdlr vc_conn;
4760 f_init(1, true);
4761 f_sleep(1.0);
4762 f_enable_all_tch();
4763 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4764 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004765 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004766}
4767
4768/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4769 * FR, which is the prefered type, is selected. */
4770testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4771 var MSC_ConnHdlr vc_conn;
4772 f_init(1, true);
4773 f_sleep(1.0);
4774 f_enable_all_tch();
4775 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4776 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004777 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004778}
4779
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004780/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4781private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4782 g_pars := f_gen_test_hdlr_pars();
4783 g_pars.ra := '02'O; /* RA containing reason=LU */
4784
4785 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4786 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4787 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4788 var template uint3_t tsc := ?;
4789
4790 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4791 f_create_bssmap_exp(l3_enc);
4792 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4793 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4794
4795 /* we should now have a COMPL_L3 at the MSC */
4796 timer T := 10.0;
4797 T.start;
4798 alt {
4799 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4800 [] T.timeout {
4801 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4802 }
4803 }
4804}
4805testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4806 var MSC_ConnHdlr vc_conn;
4807 f_init(1, true);
4808 f_sleep(1.0);
4809 f_disable_all_sdcch();
4810 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4811 vc_conn.done;
4812 f_enable_all_sdcch();
4813 f_shutdown_helper();
4814}
4815
4816/* Request a signalling channel with all SDCCH exhausted, it is
4817 expected that no TCH will be selected for signalling and assigment will fail
4818 because it's dictated by VTY config */
4819testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4820 var RSL_Message rsl_unused, rsl_msg;
4821 var GsmRrMessage rr;
4822 f_init(1, false);
4823 f_sleep(1.0);
4824 f_vty_allow_tch_for_signalling(false, 0);
4825 f_disable_all_sdcch();
4826
4827 /* RA containing reason=LU */
4828 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4829 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4830 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4831 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4832 setverdict(fail, "Expected reject");
4833 }
4834
4835 f_vty_allow_tch_for_signalling(true, 0);
4836 f_enable_all_sdcch();
4837 f_shutdown_helper();
4838}
4839
4840/* Request a voice channel with all SDCCH exhausted, it is
4841 * expected that TCH channel will be allocated since the VTY option is only
4842 * aimed at signalling requests */
4843private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4844 g_pars := f_gen_test_hdlr_pars();
4845 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4846
4847 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4848 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4849 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4850 var template uint3_t tsc := ?;
4851
4852 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4853 f_create_bssmap_exp(l3_enc);
4854 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4855 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4856
4857 /* we should now have a COMPL_L3 at the MSC */
4858 timer T := 10.0;
4859 T.start;
4860 alt {
4861 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4862 [] T.timeout {
4863 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4864 }
4865 }
4866}
4867testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4868 var MSC_ConnHdlr vc_conn;
4869 f_init(1, true);
4870 f_sleep(1.0);
4871 f_vty_allow_tch_for_signalling(false, 0);
4872 f_disable_all_sdcch();
4873
4874 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4875 vc_conn.done;
4876
4877 f_vty_allow_tch_for_signalling(true, 0);
4878 f_enable_all_sdcch();
4879 f_shutdown_helper();
4880}
4881
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004882testcase TC_assignment_osmux() runs on test_CT {
4883 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4884 var MSC_ConnHdlr vc_conn;
4885
4886 /* See note above */
4887 var RSL_IE_Body mr_conf := {
4888 other := {
4889 len := 2,
4890 payload := '2804'O
4891 }
4892 };
4893
4894 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4895 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4896 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4897 pars.expect_mr_conf_ie := mr_conf;
4898 pars.use_osmux := true;
4899
4900 f_init(1, true, true);
4901 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004902 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004903
4904 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4905 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004906
4907 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004908 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004909}
4910
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004911/* test the procedure of the MSC requesting a Classmark Update:
4912 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4913 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004914private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004915 g_pars := f_gen_test_hdlr_pars();
4916
Harald Weltea0630032018-03-20 21:09:55 +01004917 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004918 /* we should now have a COMPL_L3 at the MSC */
4919 BSSAP.receive(tr_BSSMAP_ComplL3);
4920
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004921 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4922 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4923
Harald Welte898113b2018-01-31 18:32:21 +01004924 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4925 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4926 setverdict(pass);
4927}
4928testcase TC_classmark() runs on test_CT {
4929 var MSC_ConnHdlr vc_conn;
4930 f_init(1, true);
4931 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004932 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004933 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004934 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004935}
4936
Harald Welteeddf0e92020-06-21 19:42:15 +02004937/* Send a CommonID from the simulated MSC and verify that the information is used to
4938 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4939private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4940 g_pars := f_gen_test_hdlr_pars();
4941 f_MscConnHdlr_init_vty();
4942
4943 f_create_chan_and_exp();
4944 /* we should now have a COMPL_L3 at the MSC */
4945 BSSAP.receive(tr_BSSMAP_ComplL3);
4946
4947 /* Send CommonID */
4948 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4949
4950 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4951 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4952 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4953
4954 setverdict(pass);
4955}
4956testcase TC_common_id() runs on test_CT {
4957 var MSC_ConnHdlr vc_conn;
4958 f_init(1, true);
4959 f_sleep(1.0);
4960 vc_conn := f_start_handler(refers(f_tc_common_id));
4961 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004962 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004963}
4964
Harald Weltee3bd6582018-01-31 22:51:25 +01004965private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004966 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004967 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004968 /* we should now have a COMPL_L3 at the MSC */
4969 BSSAP.receive(tr_BSSMAP_ComplL3);
4970
Harald Weltee3bd6582018-01-31 22:51:25 +01004971 /* send the single message we want to send */
4972 f_rsl_send_l3(l3);
4973}
4974
4975private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4976 timer T := sec;
4977 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004978 T.start;
4979 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004980 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4981 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004982 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004983 }
4984 [] T.timeout {
4985 setverdict(pass);
4986 }
4987 }
4988}
4989
Harald Weltee3bd6582018-01-31 22:51:25 +01004990/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4991private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4992 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4993 f_bssap_expect_nothing();
4994}
Harald Welte898113b2018-01-31 18:32:21 +01004995testcase TC_unsol_ass_fail() runs on test_CT {
4996 var MSC_ConnHdlr vc_conn;
4997 f_init(1, true);
4998 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004999 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005000 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005001 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005002}
Harald Welte552620d2017-12-16 23:21:36 +01005003
Harald Welteea99a002018-01-31 20:46:43 +01005004
5005/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5006private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005007 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5008 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01005009}
5010testcase TC_unsol_ass_compl() runs on test_CT {
5011 var MSC_ConnHdlr vc_conn;
5012 f_init(1, true);
5013 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005014 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005015 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005016 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005017}
5018
5019
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005020/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5021private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005022 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5023 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005024}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005025testcase TC_unsol_ho_fail() runs on test_CT {
5026 var MSC_ConnHdlr vc_conn;
5027 f_init(1, true);
5028 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005029 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005030 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005031 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005032}
5033
5034
Harald Weltee3bd6582018-01-31 22:51:25 +01005035/* short message from MS should be ignored */
5036private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005037 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005038 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005039 /* we should now have a COMPL_L3 at the MSC */
5040 BSSAP.receive(tr_BSSMAP_ComplL3);
5041
5042 /* send short message */
5043 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5044 f_bssap_expect_nothing();
5045}
5046testcase TC_err_82_short_msg() runs on test_CT {
5047 var MSC_ConnHdlr vc_conn;
5048 f_init(1, true);
5049 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005050 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005051 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005052 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005053}
5054
5055
Harald Weltee9e02e42018-01-31 23:36:25 +01005056/* 24.008 8.4 Unknown message must trigger RR STATUS */
5057private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5058 f_est_single_l3(ts_RRM_UL_REL('00'O));
5059 timer T := 3.0
5060 alt {
5061 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5062 setverdict(pass);
5063 }
5064 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005065 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005066 }
5067}
5068testcase TC_err_84_unknown_msg() runs on test_CT {
5069 var MSC_ConnHdlr vc_conn;
5070 f_init(1, true);
5071 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005072 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005073 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005074 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005075}
5076
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005077/***********************************************************************
5078 * Handover
5079 ***********************************************************************/
5080
Harald Welte94e0c342018-04-07 11:33:23 +02005081/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5082private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5083runs on test_CT {
5084 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5085 " timeslot "&int2str(ts_nr)&" ";
5086 f_vty_transceive(BSCVTY, cmd & suffix);
5087}
5088
Harald Welte261af4b2018-02-12 21:20:39 +01005089/* 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 +07005090private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5091 uint8_t bts_nr, uint8_t trx_nr,
5092 in RslChannelNr chan_nr)
5093{
Harald Welte261af4b2018-02-12 21:20:39 +01005094 /* FIXME: resolve those from component-global state */
5095 var integer ts_nr := chan_nr.tn;
5096 var integer ss_nr;
5097 if (ischosen(chan_nr.u.ch0)) {
5098 ss_nr := 0;
5099 } else if (ischosen(chan_nr.u.lm)) {
5100 ss_nr := chan_nr.u.lm.sub_chan;
5101 } else if (ischosen(chan_nr.u.sdcch4)) {
5102 ss_nr := chan_nr.u.sdcch4.sub_chan;
5103 } else if (ischosen(chan_nr.u.sdcch8)) {
5104 ss_nr := chan_nr.u.sdcch8.sub_chan;
5105 } else {
5106 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005107 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005108 }
5109
5110 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5111 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005112 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005113}
5114
Neels Hofmeyr91401012019-07-11 00:42:35 +02005115/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5116 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5117 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5118 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5119 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005120private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5121 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5122{
5123 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005124}
5125
5126/* intra-BSC hand-over between BTS0 and BTS1 */
5127private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005128 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5129 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005130
5131 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5132 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5133
Harald Weltea0630032018-03-20 21:09:55 +01005134 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005135 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005136
5137 var HandoverState hs := {
5138 rr_ho_cmpl_seen := false,
5139 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005140 old_chan_nr := -,
5141 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005142 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005143 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005144 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005145 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5146 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005147
5148 /* From the MGW perspective, a handover is is characterized by
5149 * performing one MDCX operation with the MGW. So we expect to see
5150 * one more MDCX during handover. */
5151 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5152
Harald Welte261af4b2018-02-12 21:20:39 +01005153 alt {
5154 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005155 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005156
Philipp Maier4dae0652018-11-12 12:03:26 +01005157 /* Since this is an internal handover we expect the BSC to inform the
5158 * MSC about the event */
5159 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5160
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005161 /* Check the amount of MGCP transactions is still consistant with the
5162 * test expectation */
5163 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005164
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005165 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5166
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005167 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5168 * 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 +02005169 f_verify_encr_info(chan_act);
5170
5171 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005172
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005173 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005174}
5175
5176testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005177 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005178 var MSC_ConnHdlr vc_conn;
5179 f_init(2, true);
5180 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005181
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005182 pars.expect_tsc := BTS_TSC[0];
5183
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005184 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005185
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005186 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005187 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005188
5189 /* from f_establish_fully() */
5190 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5191 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5192 /* from handover */
5193 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5194 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5195 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5196 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005197 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5198 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005199 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005200 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005201}
Harald Weltee9e02e42018-01-31 23:36:25 +01005202
Oliver Smith7eabd312021-07-12 14:18:56 +02005203function 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 +02005204 var MSC_ConnHdlr vc_conn;
5205 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5206 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5207
5208 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005209 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005210 f_sleep(1.0);
5211
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005212 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005213
5214 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5215 vc_conn.done;
5216
5217 /* from f_establish_fully() */
5218 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5219 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5220 /* from handover */
5221 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5222 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5223 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5224 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005225 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5226 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005227 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005228 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005229 f_shutdown_helper();
5230}
5231
5232testcase TC_ho_int_a5_0() runs on test_CT {
5233 f_tc_ho_int_a5('01'O);
5234}
5235
5236testcase TC_ho_int_a5_1() runs on test_CT {
5237 f_tc_ho_int_a5('02'O);
5238}
5239
5240testcase TC_ho_int_a5_3() runs on test_CT {
5241 f_tc_ho_int_a5('08'O);
5242}
5243
5244testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005245 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005246}
5247
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005248/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5249private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5250 g_pars := f_gen_test_hdlr_pars();
5251 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5252 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005253
5254 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5255 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5256
5257 f_establish_fully(ass_cmd, exp_compl);
5258 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5259
5260 var HandoverState hs := {
5261 rr_ho_cmpl_seen := false,
5262 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005263 old_chan_nr := -,
5264 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005265 };
5266 /* issue hand-over command on VTY */
5267 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5268 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5269 f_rslem_suspend(RSL1_PROC);
5270
5271 /* From the MGW perspective, a handover is is characterized by
5272 * performing one MDCX operation with the MGW. So we expect to see
5273 * one more MDCX during handover. */
5274 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5275
5276 var RSL_Message rsl;
5277 var PDU_ML3_NW_MS l3;
5278 var RslChannelNr new_chan_nr;
5279 var GsmArfcn arfcn;
5280 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5281 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5282 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5283 setverdict(fail, "Expected handoverCommand");
5284 mtc.stop;
5285 }
5286 }
5287 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5288 new_chan_nr, arfcn);
5289
5290 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5291
5292 /* resume processing of RSL DChan messages, which was temporarily suspended
5293 * before performing a hand-over */
5294 f_rslem_resume(RSL1_PROC);
5295 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5296
5297 f_sleep(1.0);
5298
5299 /* Handover fails because no HANDO DET appears on the new lchan,
5300 * and the old lchan reports a Radio Link Failure. */
5301 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5302
5303 var PDU_BSSAP rx_clear_request;
5304 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5305 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5306 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5307
5308 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5309
5310 var MgcpCommand mgcp;
5311 interleave {
5312 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5313 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005314 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005315 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005316 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005317 }
5318 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005319 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005320 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005321 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005322 }
5323 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5324 }
5325
5326 f_sleep(0.5);
5327 setverdict(pass);
5328}
5329testcase TC_ho_int_radio_link_failure() runs on test_CT {
5330 var MSC_ConnHdlr vc_conn;
5331 f_init(2, true);
5332 f_sleep(1.0);
5333
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005334 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005335
5336 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5337 vc_conn.done;
5338
5339 /* from f_establish_fully() */
5340 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5341 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5342 /* from handover */
5343 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5344 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5345 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5346 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005347 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5348 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005349 f_ctrs_bsc_and_bts_verify();
5350 f_shutdown_helper();
5351}
5352
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005353/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005354private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005355 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005356 var template MgcpResponse mgcp_resp;
5357 var MGCP_RecvFrom mrf;
5358 var template MgcpMessage msg_resp;
5359 var template MgcpMessage msg_dlcx := {
5360 command := tr_DLCX()
5361 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005362
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005363 if (g_pars.aoip) {
5364 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005365 log("Got first DLCX: ", mgcp);
5366 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005367 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005368
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005369 MGCP.receive(tr_DLCX()) -> value mgcp {
5370 log("Got second DLCX: ", mgcp);
5371 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5372 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005373 } else {
5374 /* For SCCPLite, BSC doesn't handle the MSC-side */
5375 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5376 log("Got first DLCX: ", mrf.msg.command);
5377 msg_resp := {
5378 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5379 }
5380 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5381 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005382 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005383}
5384
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005385private 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 +01005386
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005387 var NcellReports neighbor_rep := {
5388 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5389 };
5390 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5391 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5392 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005393
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005394 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005395
5396 f_sleep(0.5);
5397 /* The MSC negotiates Handover Request and Handover Request Ack with
5398 * the other BSS and comes back with a BSSMAP Handover Command
5399 * containing an RR Handover Command coming from the target BSS... */
5400
5401 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5402 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5403 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5404 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5405 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5406
5407 /* expect the Handover Command to go out on RR */
5408 var RSL_Message rsl_ho_cmd
5409 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5410 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5411 var RSL_IE_Body rsl_ho_cmd_l3;
5412 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5413 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5414 setverdict(fail);
5415 } else {
5416 log("Found L3 Info: ", rsl_ho_cmd_l3);
5417 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5418 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5419 setverdict(fail);
5420 } else {
5421 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5422 setverdict(pass);
5423 }
5424 }
5425
5426 /* When the other BSS has reported a completed handover, this side is
5427 * torn down. */
5428
5429 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5430 var BssmapCause cause := enum2int(cause_val);
5431 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5432
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005433 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005434
5435 interleave {
5436 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5437 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5438 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005439 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005440 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005441 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005442}
5443
5444private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5445 g_pars := f_gen_test_hdlr_pars();
5446 var PDU_BSSAP ass_req := f_gen_ass_req();
5447 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5448 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5449 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5450 f_establish_fully(ass_req, exp_compl);
5451
5452 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005453}
5454testcase TC_ho_out_of_this_bsc() runs on test_CT {
5455 var MSC_ConnHdlr vc_conn;
5456
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005457 f_init_vty();
5458 f_bts_0_cfg(BSCVTY,
5459 {"neighbor-list mode automatic",
5460 "handover 1",
5461 "handover algorithm 2",
5462 "handover2 window rxlev averaging 1",
5463 "neighbor lac 99 arfcn 123 bsic any"});
5464 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5465
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005466 f_init(1, true);
5467 f_sleep(1.0);
5468
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005469 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005470
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005471 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5472 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005473
5474 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5475 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5476 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5477 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5478 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5479 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5480 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005481 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005482}
5483
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005484private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5485 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005486 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005487 octetstring l3 := '0123456789'O)
5488runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005489 /* The old lchan and conn should still be active. See that arbitrary L3
5490 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005491 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005492 var template PDU_BSSAP exp_data := {
5493 discriminator := '1'B,
5494 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005495 dlci := dlci,
5496 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005497 pdu := {
5498 dtap := l3
5499 }
5500 };
5501 BSSAP.receive(exp_data);
5502 setverdict(pass);
5503}
5504
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005505private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5506 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005507 template (value) OCT1 dlci := '00'O,
5508 octetstring l3 := '0123456789'O)
5509runs on MSC_ConnHdlr {
5510 BSSAP.send(PDU_BSSAP:{
5511 discriminator := '1'B,
5512 spare := '0000000'B,
5513 dlci := dlci,
5514 lengthIndicator := lengthof(l3),
5515 pdu := {
5516 dtap := l3
5517 }
5518 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005519 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005520 setverdict(pass);
5521}
5522
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005523/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5524 * simply never sends a BSSMAP Handover Command. */
5525private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005526 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005527
5528 var PDU_BSSAP ass_req := f_gen_ass_req();
5529 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5530 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5531 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5532 f_establish_fully(ass_req, exp_compl);
5533
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005534 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005535 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5536
5537 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5538
5539 /* osmo-bsc should time out 10 seconds after the handover started.
5540 * Let's give it a bit extra. */
5541 f_sleep(15.0);
5542
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005543 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005544 f_sleep(1.0);
5545}
5546testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5547 var MSC_ConnHdlr vc_conn;
5548
5549 f_init(1, true);
5550 f_sleep(1.0);
5551
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005552 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005553
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005554 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5555 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005556
5557 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5558 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5559 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5560 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5561 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5562 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5563 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005564 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005565}
5566
5567/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5568 * RR Handover Failure. */
5569private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005570 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005571
5572 var PDU_BSSAP ass_req := f_gen_ass_req();
5573 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5574 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5575 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5576 f_establish_fully(ass_req, exp_compl);
5577
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005578 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005579 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5580
5581 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5582
5583 f_sleep(0.5);
5584 /* The MSC negotiates Handover Request and Handover Request Ack with
5585 * the other BSS and comes back with a BSSMAP Handover Command
5586 * containing an RR Handover Command coming from the target BSS... */
5587
5588 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5589 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5590 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5591 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5592 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5593
5594 /* expect the Handover Command to go out on RR */
5595 var RSL_Message rsl_ho_cmd
5596 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5597 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5598 var RSL_IE_Body rsl_ho_cmd_l3;
5599 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5600 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5601 setverdict(fail);
5602 } else {
5603 log("Found L3 Info: ", rsl_ho_cmd_l3);
5604 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5605 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5606 setverdict(fail);
5607 } else {
5608 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5609 setverdict(pass);
5610 }
5611 }
5612
5613 f_sleep(0.2);
5614 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5615
5616 /* Should tell the MSC about the failure */
5617 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5618
5619 f_sleep(1.0);
5620
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005621 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005622 f_sleep(1.0);
5623
5624 setverdict(pass);
5625 f_sleep(1.0);
5626}
5627testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5628 var MSC_ConnHdlr vc_conn;
5629
5630 f_init(1, true);
5631 f_sleep(1.0);
5632
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005633 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005634
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005635 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5636 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005637
5638 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5639 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5640 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5641 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5642 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5643 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5644 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005645 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005646}
5647
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005648/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5649 * (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 +02005650 * and the lchan is released. */
5651private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005652 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005653
5654 var PDU_BSSAP ass_req := f_gen_ass_req();
5655 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5656 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5657 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5658 f_establish_fully(ass_req, exp_compl);
5659
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005660 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005661 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5662
5663 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5664
5665 f_sleep(0.5);
5666 /* The MSC negotiates Handover Request and Handover Request Ack with
5667 * the other BSS and comes back with a BSSMAP Handover Command
5668 * containing an RR Handover Command coming from the target BSS... */
5669
5670 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5671 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5672 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5673 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5674 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5675
5676 /* expect the Handover Command to go out on RR */
5677 var RSL_Message rsl_ho_cmd
5678 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5679 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5680 var RSL_IE_Body rsl_ho_cmd_l3;
5681 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5682 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5683 setverdict(fail);
5684 } else {
5685 log("Found L3 Info: ", rsl_ho_cmd_l3);
5686 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5687 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5688 setverdict(fail);
5689 } else {
5690 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5691 setverdict(pass);
5692 }
5693 }
5694
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005695 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5696 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5697 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005698
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005699 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005700 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5701 log("Got BSSMAP Clear Request");
5702 /* Instruct BSC to clear channel */
5703 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5704 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5705
5706 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005707 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005708 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5709 log("Got Deact SACCH");
5710 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005711 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005712 log("Got RR Release");
5713 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005714 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005715 log("Got RF Chan Rel");
5716 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005717 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005718 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005719 }
5720
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005721 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005722 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005723
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005724 setverdict(pass);
5725 f_sleep(1.0);
5726}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005727testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005728 var MSC_ConnHdlr vc_conn;
5729
5730 f_init(1, true);
5731 f_sleep(1.0);
5732
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005733 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005734
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005735 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005736 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005737
5738 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5739 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5740 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5741 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5742 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5743 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5744 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005745 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005746}
5747
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005748private 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 +01005749 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5750 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5751 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5752 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5753 * before we get started. */
5754 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5755 f_rslem_register(0, new_chan_nr);
5756 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005757 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005758 f_sleep(1.0);
5759
5760 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5761 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5762 activate(as_Media());
5763
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005764 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005765 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005766 oldToNewBSSIEs := oldToNewBSSIEs,
5767 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005768 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005769
5770 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5771
5772 var PDU_BSSAP rx_bssap;
5773 var octetstring ho_command_str;
5774
5775 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005776
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005777 /* we're sure that the channel activation is done now, verify the parameters in it */
5778 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
5779 f_verify_encr_info(chan_act);
5780 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005781
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005782 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5783 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5784 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5785 log("L3 Info in HO Request Ack is ", ho_command);
5786
5787 var GsmArfcn arfcn;
5788 var RslChannelNr actual_new_chan_nr;
5789 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5790 actual_new_chan_nr, arfcn);
5791
5792 if (actual_new_chan_nr != new_chan_nr) {
5793 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5794 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5795 setverdict(fail);
5796 return;
5797 }
5798 log("Handover Command chan_nr is", actual_new_chan_nr);
5799
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005800 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
5801 if (not match(got_tsc, expect_target_tsc)) {
5802 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
5803 expect_target_tsc, " got ", got_tsc);
5804 mtc.stop;
5805 } else {
5806 log("handoverCommand: verified TSC = ", got_tsc);
5807 }
5808
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005809 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5810 * tells the MS to handover to the new lchan. Here comes the new MS on
5811 * the new lchan with a Handover RACH: */
5812
5813 /* send handover detect */
5814
5815 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5816
5817 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5818
5819 /* send handover complete over the new channel */
5820
5821 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5822 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5823 enc_PDU_ML3_MS_NW(l3_tx)));
5824
5825 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005826 setverdict(pass);
5827}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005828
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005829private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005830 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005831 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5832 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5833 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005834 }
5835 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005836 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005837 } else {
5838 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005839 }
5840 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005841 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005842 setverdict(pass);
5843}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005844function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005845 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005846
5847 f_init(1, true);
5848 f_sleep(1.0);
5849
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005850 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005851
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005852 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5853 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005854
5855 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5856 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005857
5858 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5859 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5860 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5861 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5862 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005863}
5864
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005865testcase TC_ho_into_this_bsc() runs on test_CT {
5866 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5867 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005868 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005869}
5870
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005871function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5872 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5873 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5874 f_tc_ho_into_this_bsc_main(pars);
5875 f_shutdown_helper();
5876}
5877
5878testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5879 f_tc_ho_into_this_bsc_a5('01'O);
5880}
5881
5882testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5883 f_tc_ho_into_this_bsc_a5('02'O);
5884}
5885
5886testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5887 f_tc_ho_into_this_bsc_a5('08'O);
5888}
5889
5890testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5891 f_tc_ho_into_this_bsc_a5('10'O);
5892}
5893
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005894testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5895 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5896 pars.host_aoip_tla := "::6";
5897 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005898 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005899}
5900
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005901/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005902 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005903 channel is later released (RR CHannel Release), should trigger inclusion of
5904 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5905 neighbors. */
5906testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5907 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5908 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005909 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005910 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005911
5912 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5913 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5914 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005915 f_shutdown_helper();
5916}
5917
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005918/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5919 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5920 list when the channel is released. */
5921testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5922 f_init_vty();
5923 f_vty_allow_srvcc_fast_return(true, 0)
5924
5925 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5926 pars.last_used_eutran_plmn := '323454'O;
5927 pars.exp_fast_return := false;
5928 f_tc_ho_into_this_bsc_main(pars);
5929 f_vty_allow_srvcc_fast_return(false, 0);
5930 f_shutdown_helper();
5931}
5932
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005933private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5934 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5935 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5936 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5937 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5938 setverdict(pass);
5939}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005940
5941private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5942 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005943 var MSC_ConnHdlr vc_conn;
5944 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5945
5946 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005947 if (disable_fast_return) {
5948 f_vty_allow_srvcc_fast_return(true, 0);
5949 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005950 f_sleep(1.0);
5951
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005952 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005953
5954 pars.last_used_eutran_plmn := '323454'O;
5955 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5956 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5957
5958 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5959 vc_conn.done;
5960
5961 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5962 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5963 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5964 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5965 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5966 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005967
5968 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5969 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005970 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005971
5972 if (disable_fast_return) {
5973 f_vty_allow_srvcc_fast_return(false, 0);
5974 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005975 f_shutdown_helper();
5976}
5977
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005978/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5979 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5980 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5981 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5982testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5983 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5984}
5985/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5986 * independently of fast-reture allowed/forbidden in local BTS */
5987testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5988 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5989}
5990
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005991private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5992 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5993 f_rslem_register(0, new_chan_nr);
5994 g_chan_nr := new_chan_nr;
5995 f_sleep(1.0);
5996
5997 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5998 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5999 activate(as_Media());
6000
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006001 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006002 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006003 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006004
6005 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6006
6007 var PDU_BSSAP rx_bssap;
6008 var octetstring ho_command_str;
6009
6010 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6011
6012 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6013 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6014 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6015 log("L3 Info in HO Request Ack is ", ho_command);
6016
6017 var GsmArfcn arfcn;
6018 var RslChannelNr actual_new_chan_nr;
6019 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6020 actual_new_chan_nr, arfcn);
6021
6022 if (actual_new_chan_nr != new_chan_nr) {
6023 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6024 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6025 setverdict(fail);
6026 return;
6027 }
6028 log("Handover Command chan_nr is", actual_new_chan_nr);
6029
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006030 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6031 f_sleep(1.0);
6032
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006033 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6034 * tells the MS to handover to the new lchan. In this case, the MS
6035 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6036 * Handover Failure to the MSC. The procedure according to 3GPP TS
6037 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6038 * BSSMAP Clear Command: */
6039
6040 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6041 var BssmapCause cause := enum2int(cause_val);
6042 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6043
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006044 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006045 BSSAP.receive(tr_BSSMAP_ClearComplete);
6046
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006047 setverdict(pass);
6048 f_sleep(1.0);
6049
6050 setverdict(pass);
6051}
6052testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6053 var MSC_ConnHdlr vc_conn;
6054 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6055
6056 f_init(1, true);
6057 f_sleep(1.0);
6058
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006059 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006060
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006061 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6062 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006063
6064 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6065 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006066
6067 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6068 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6069 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6070 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6071 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006072 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006073}
6074
6075private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6076 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6077 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6078 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6079 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6080 * before we get started. */
6081 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6082 f_rslem_register(0, new_chan_nr);
6083 g_chan_nr := new_chan_nr;
6084 f_sleep(1.0);
6085
6086 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6087 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6088 activate(as_Media());
6089
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006090 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006091 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006092 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006093
6094 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6095
6096 var PDU_BSSAP rx_bssap;
6097 var octetstring ho_command_str;
6098
6099 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6100
6101 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6102 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6103 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6104 log("L3 Info in HO Request Ack is ", ho_command);
6105
6106 var GsmArfcn arfcn;
6107 var RslChannelNr actual_new_chan_nr;
6108 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6109 actual_new_chan_nr, arfcn);
6110
6111 if (actual_new_chan_nr != new_chan_nr) {
6112 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6113 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6114 setverdict(fail);
6115 return;
6116 }
6117 log("Handover Command chan_nr is", actual_new_chan_nr);
6118
6119 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6120 * tells the MS to handover to the new lchan. Here comes the new MS on
6121 * the new lchan with a Handover RACH: */
6122
6123 /* send handover detect */
6124
6125 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6126
6127 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6128
6129 /* The MSC chooses to clear the connection now, maybe we got the
6130 * Handover RACH on the new cell but the MS still signaled Handover
6131 * Failure to the old BSS? */
6132
6133 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6134 var BssmapCause cause := enum2int(cause_val);
6135 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6136
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006137 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006138 BSSAP.receive(tr_BSSMAP_ClearComplete);
6139
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006140 f_sleep(1.0);
6141}
6142testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6143 var MSC_ConnHdlr vc_conn;
6144 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6145
6146 f_init(1, true);
6147 f_sleep(1.0);
6148
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006149 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006150
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006151 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6152 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006153
6154 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6155 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006156
6157 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6158 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6159 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6160 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6161 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006162 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006163}
6164
6165/* The new BSS's lchan times out before the MSC decides that handover failed. */
6166private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6167 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6168 f_rslem_register(0, new_chan_nr);
6169 g_chan_nr := new_chan_nr;
6170 f_sleep(1.0);
6171
6172 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6173 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6174 activate(as_Media());
6175
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006176 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006177 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006178 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006179
6180 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6181
6182 var PDU_BSSAP rx_bssap;
6183 var octetstring ho_command_str;
6184
6185 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6186
6187 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6188 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6189 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6190 log("L3 Info in HO Request Ack is ", ho_command);
6191
6192 var GsmArfcn arfcn;
6193 var RslChannelNr actual_new_chan_nr;
6194 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6195 actual_new_chan_nr, arfcn);
6196
6197 if (actual_new_chan_nr != new_chan_nr) {
6198 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6199 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6200 setverdict(fail);
6201 return;
6202 }
6203 log("Handover Command chan_nr is", actual_new_chan_nr);
6204
6205 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6206 * tells the MS to handover to the new lchan. But the MS never shows up
6207 * on the new lchan. */
6208
6209 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6210
6211 /* Did osmo-bsc also send a Clear Request? */
6212 timer T := 0.5;
6213 T.start;
6214 alt {
6215 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6216 [] T.timeout { }
6217 }
6218
6219 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6220 * asked for it, this is a Handover Failure after all). */
6221
6222 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6223 var BssmapCause cause := enum2int(cause_val);
6224 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6225
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006226 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006227 BSSAP.receive(tr_BSSMAP_ClearComplete);
6228
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006229 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006230}
6231testcase TC_ho_in_fail_no_detect() runs on test_CT {
6232 var MSC_ConnHdlr vc_conn;
6233 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6234
6235 f_init(1, true);
6236 f_sleep(1.0);
6237
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006238 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006239
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006240 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6241 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006242
6243 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6244 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006245
6246 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6247 f_ctrs_bsc_and_bts_add(0, "handover:error");
6248 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6249 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6250 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006251 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006252}
6253
6254/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6255private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6256 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6257 f_rslem_register(0, new_chan_nr);
6258 g_chan_nr := new_chan_nr;
6259 f_sleep(1.0);
6260
6261 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6262 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6263 activate(as_Media());
6264
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006265 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006266 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006267 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006268
6269 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6270
6271 var PDU_BSSAP rx_bssap;
6272 var octetstring ho_command_str;
6273
6274 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6275
6276 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6277 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6278 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6279 log("L3 Info in HO Request Ack is ", ho_command);
6280
6281 var GsmArfcn arfcn;
6282 var RslChannelNr actual_new_chan_nr;
6283 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6284 actual_new_chan_nr, arfcn);
6285
6286 if (actual_new_chan_nr != new_chan_nr) {
6287 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6288 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6289 setverdict(fail);
6290 return;
6291 }
6292 log("Handover Command chan_nr is", actual_new_chan_nr);
6293
6294 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6295 * tells the MS to handover to the new lchan. But the MS never shows up
6296 * on the new lchan. */
6297
6298 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6299
6300 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006301 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006302
6303 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006304 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6305 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6306 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006307 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006308 BSSAP.receive(tr_BSSMAP_ClearComplete);
6309
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006310 f_sleep(1.0);
6311}
6312testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6313 var MSC_ConnHdlr vc_conn;
6314 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6315
6316 f_init(1, true);
6317 f_sleep(1.0);
6318
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006319 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006320
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006321 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6322 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006323
6324 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6325 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006326
6327 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6328 f_ctrs_bsc_and_bts_add(0, "handover:error");
6329 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6330 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6331 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006332 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006333}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006334
Neels Hofmeyr91401012019-07-11 00:42:35 +02006335type record of charstring Commands;
6336
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006337private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006338{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006339 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006340 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006341 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006342 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006343 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006344}
6345
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006346private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6347{
6348 f_vty_enter_cfg_cs7_inst(pt, 0);
6349 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6350 f_vty_transceive(pt, cmds[i]);
6351 }
6352 f_vty_transceive(pt, "end");
6353}
6354
Neels Hofmeyr91401012019-07-11 00:42:35 +02006355private function f_probe_for_handover(charstring log_label,
6356 charstring log_descr,
6357 charstring handover_vty_cmd,
6358 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006359 boolean is_inter_bsc_handover := false,
6360 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006361runs on MSC_ConnHdlr
6362{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006363 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6364 * lchans to be established on bts 1 or bts 2. */
6365 f_rslem_suspend(RSL1_PROC);
6366 f_rslem_suspend(RSL2_PROC);
6367
Neels Hofmeyr91401012019-07-11 00:42:35 +02006368 var RSL_Message rsl;
6369
6370 var charstring log_msg := " (expecting handover)"
6371 if (not expect_handover) {
6372 log_msg := " (expecting NO handover)";
6373 }
6374 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6375 f_vty_transceive(BSCVTY, handover_vty_cmd);
6376
Neels Hofmeyr91401012019-07-11 00:42:35 +02006377 timer T := 2.0;
6378 T.start;
6379
6380 alt {
6381 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6382 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6383 log("Rx L3 from net: ", l3);
6384 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6385 var RslChannelNr new_chan_nr;
6386 var GsmArfcn arfcn;
6387 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6388 new_chan_nr, arfcn);
6389 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6390 log(l3.msgs.rrm.handoverCommand);
6391
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006392 /* Verify correct TSC in handoverCommand */
6393 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6394 if (not match(got_tsc, expect_target_tsc)) {
6395 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6396 expect_target_tsc, " got ", got_tsc);
6397 mtc.stop;
6398 } else {
6399 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6400 expect_target_tsc, ")");
6401 }
6402
Neels Hofmeyr91401012019-07-11 00:42:35 +02006403 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6404 * matter on which BTS it really is, we're not going to follow through an entire handover
6405 * anyway. */
6406 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6407 f_rslem_resume(RSL1_PROC);
6408 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6409 f_rslem_resume(RSL2_PROC);
6410
6411 if (expect_handover and not is_inter_bsc_handover) {
6412 setverdict(pass);
6413 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6414 } else {
6415 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6416 & log_label & ": " & log_descr);
6417 }
6418
6419 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6420 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6421 * Handover Failure. */
6422 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6423
6424 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6425 f_sleep(0.5);
6426 RSL1.clear;
6427 RSL2.clear;
6428 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6429 break;
6430 } else {
6431 repeat;
6432 }
6433 }
6434 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6435 if (expect_handover and is_inter_bsc_handover) {
6436 setverdict(pass);
6437 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6438 } else {
6439 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6440 & log_label & ": " & log_descr);
6441 }
6442
6443 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6444
6445 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6446 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6447 * setting a short timeout and waiting is the only way. */
6448 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6449 f_sleep(1.5);
6450 log("f_probe_for_handover(" & log_label & "): ...done");
6451
6452 break;
6453 }
6454 [] T.timeout {
6455 if (expect_handover) {
6456 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6457 & log_label & ": " & log_descr);
6458 } else {
6459 setverdict(pass);
6460 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6461 }
6462 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6463 break;
6464 }
6465 }
6466
6467 f_rslem_resume(RSL1_PROC);
6468 f_rslem_resume(RSL2_PROC);
6469 f_sleep(3.0);
6470 RSL.clear;
6471
6472 log("f_probe_for_handover(" & log_label & "): done clearing");
6473}
6474
6475/* Test the effect of various neighbor configuration scenarios:
6476 *
6477 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6478 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6479 */
6480private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6481 g_pars := f_gen_test_hdlr_pars();
6482 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6483 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006484
6485 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6486 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6487
6488 /* Establish lchan at bts 0 */
6489 f_establish_fully(ass_cmd, exp_compl);
6490
6491 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6492 f_vty_enter_cfg_network(BSCVTY);
6493 f_vty_transceive(BSCVTY, "timer T7 1");
6494 f_vty_transceive(BSCVTY, "end");
6495}
6496
6497private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6498 f_tc_ho_neighbor_config_start();
6499
6500 /*
6501 * bts 0 ARFCN 871 BSIC 10
6502 * bts 1 ARFCN 871 BSIC 11
6503 * bts 2 ARFCN 871 BSIC 12
6504 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6505 */
6506
6507 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006508 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006509 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6510 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006511 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006512
6513 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6514 "handover any to arfcn 13 bsic 39",
6515 false);
6516
6517 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6518 "handover any to arfcn 871 bsic 12",
6519 false);
6520
6521 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6522 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006523 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006524}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006525testcase TC_ho_neighbor_config_1() runs on test_CT {
6526 var MSC_ConnHdlr vc_conn;
6527 f_init(3, true, guard_timeout := 60.0);
6528 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006529 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006530 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6531 vc_conn.done;
6532
6533 /* f_tc_ho_neighbor_config_start() */
6534 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6535 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6536
6537 /* 1.a */
6538 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6539 * handover quickly by sending a Handover Failure message. */
6540 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6541 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6542 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6543 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006544 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6545 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006546
6547 /* 1.b */
6548 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6549 f_ctrs_bsc_and_bts_add(0, "handover:error");
6550
6551 /* 1.c */
6552 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6553 f_ctrs_bsc_and_bts_add(0, "handover:error");
6554
6555 /* 1.d */
6556 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6557 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6558 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6559 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006560 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6561 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006562
6563 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006564 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006565}
6566
Neels Hofmeyr91401012019-07-11 00:42:35 +02006567private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6568 f_tc_ho_neighbor_config_start();
6569
6570 /*
6571 * bts 0 ARFCN 871 BSIC 10
6572 * bts 1 ARFCN 871 BSIC 11
6573 * bts 2 ARFCN 871 BSIC 12
6574 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6575 */
6576
6577 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006578 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006579 f_sleep(0.5);
6580
6581 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6582 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006583 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006584
6585 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6586 "handover any to arfcn 871 bsic 12",
6587 false);
6588}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006589testcase TC_ho_neighbor_config_2() runs on test_CT {
6590 var MSC_ConnHdlr vc_conn;
6591 f_init(3, true, guard_timeout := 50.0);
6592 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006593 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006594 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6595 vc_conn.done;
6596
6597 /* f_tc_ho_neighbor_config_start() */
6598 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6599 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6600
6601 /* 2.a */
6602 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6603 * handover quickly by sending a Handover Failure message. */
6604 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6605 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6606 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6607 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006608 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6609 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006610
6611 /* 2.b */
6612 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6613 f_ctrs_bsc_and_bts_add(0, "handover:error");
6614
6615 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006616 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006617}
6618
Neels Hofmeyr91401012019-07-11 00:42:35 +02006619private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6620 f_tc_ho_neighbor_config_start();
6621
6622 /*
6623 * bts 0 ARFCN 871 BSIC 10
6624 * bts 1 ARFCN 871 BSIC 11
6625 * bts 2 ARFCN 871 BSIC 12
6626 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6627 */
6628
6629 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006630 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006631 f_sleep(0.5);
6632
6633 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6634 "handover any to arfcn 871 bsic 11",
6635 false);
6636 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",
6637 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006638 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006639}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006640testcase TC_ho_neighbor_config_3() runs on test_CT {
6641 var MSC_ConnHdlr vc_conn;
6642 f_init(3, true, guard_timeout := 50.0);
6643 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006644 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006645 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6646 vc_conn.done;
6647
6648 /* f_tc_ho_neighbor_config_start() */
6649 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6650 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6651
6652 /* 3.a */
6653 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6654 f_ctrs_bsc_and_bts_add(0, "handover:error");
6655
6656 /* 3.b */
6657 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6658 * handover quickly by sending a Handover Failure message. */
6659 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6660 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6661 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6662 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006663 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
6664 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006665
6666 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006667 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006668}
6669
Neels Hofmeyr91401012019-07-11 00:42:35 +02006670private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6671 f_tc_ho_neighbor_config_start();
6672
6673 /*
6674 * bts 0 ARFCN 871 BSIC 10
6675 * bts 1 ARFCN 871 BSIC 11
6676 * bts 2 ARFCN 871 BSIC 12
6677 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6678 */
6679
6680 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006681 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006682 f_sleep(0.5);
6683
6684 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6685 "handover any to arfcn 871 bsic 11",
6686 false);
6687 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6688 "handover any to arfcn 871 bsic 12",
6689 false);
6690 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6691 "handover any to arfcn 123 bsic 45",
6692 true, true);
6693}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006694testcase TC_ho_neighbor_config_4() runs on test_CT {
6695 var MSC_ConnHdlr vc_conn;
6696 f_init(3, true, guard_timeout := 50.0);
6697 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006698 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006699 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6700 vc_conn.done;
6701
6702 /* f_tc_ho_neighbor_config_start() */
6703 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6704 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6705
6706 /* 4.a */
6707 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6708 f_ctrs_bsc_and_bts_add(0, "handover:error");
6709
6710 /* 4.b */
6711 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6712 f_ctrs_bsc_and_bts_add(0, "handover:error");
6713
6714 /* 4.c */
6715 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6716 * handover quickly by timing out after the Handover Required message */
6717 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6718 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6719 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6720 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6721
6722 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006723 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006724}
6725
Neels Hofmeyr91401012019-07-11 00:42:35 +02006726private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6727 f_tc_ho_neighbor_config_start();
6728
6729 /*
6730 * bts 0 ARFCN 871 BSIC 10
6731 * bts 1 ARFCN 871 BSIC 11
6732 * bts 2 ARFCN 871 BSIC 12
6733 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6734 */
6735
6736 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 +02006737 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006738 f_sleep(0.5);
6739
6740 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6741 "handover any to arfcn 871 bsic 12",
6742 true, true);
6743}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006744testcase TC_ho_neighbor_config_5() runs on test_CT {
6745 var MSC_ConnHdlr vc_conn;
6746 f_init(3, true);
6747 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006748 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006749 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6750 vc_conn.done;
6751
6752 /* f_tc_ho_neighbor_config_start() */
6753 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6754 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6755
6756 /* 5 */
6757 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6758 * handover quickly by timing out after the Handover Required message */
6759 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6760 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6761 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6762 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6763
6764 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006765 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006766}
6767
Neels Hofmeyr91401012019-07-11 00:42:35 +02006768private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6769 f_tc_ho_neighbor_config_start();
6770
6771 /*
6772 * bts 0 ARFCN 871 BSIC 10
6773 * bts 1 ARFCN 871 BSIC 11
6774 * bts 2 ARFCN 871 BSIC 12
6775 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6776 */
6777
6778 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6779 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006780 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006781 f_sleep(0.5);
6782
6783 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6784 "handover any to arfcn 871 bsic 12",
6785 false);
6786}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006787testcase TC_ho_neighbor_config_6() runs on test_CT {
6788 var MSC_ConnHdlr vc_conn;
6789 f_init(3, true);
6790 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006791 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006792 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6793 vc_conn.done;
6794
6795 /* f_tc_ho_neighbor_config_start() */
6796 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6797 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6798
6799 /* 6.a */
6800 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6801 * handover quickly by timing out after the Handover Required message */
6802 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6803 f_ctrs_bsc_and_bts_add(0, "handover:error");
6804
6805 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006806 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006807}
6808
Neels Hofmeyr91401012019-07-11 00:42:35 +02006809private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6810 f_tc_ho_neighbor_config_start();
6811
6812 /*
6813 * bts 0 ARFCN 871 BSIC 10
6814 * bts 1 ARFCN 871 BSIC 11
6815 * bts 2 ARFCN 871 BSIC 12
6816 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6817 */
6818
6819 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6820 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006821 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006822 f_sleep(0.5);
6823
6824 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6825 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006826 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006827 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6828 "handover any to arfcn 123 bsic 45",
6829 true, true);
6830}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006831testcase TC_ho_neighbor_config_7() runs on test_CT {
6832 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006833 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006834 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006835 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006836 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6837 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006838
6839 /* f_tc_ho_neighbor_config_start() */
6840 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6841 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6842
6843 /* 7.a */
6844 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6845 * handover quickly by sending a Handover Failure message. */
6846 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6847 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6848 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6849 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006850 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
6851 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006852
6853 /* 7.b */
6854 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6855 * handover quickly by timing out after the Handover Required message */
6856 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6857 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6858 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6859 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6860
6861 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006862 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006863}
6864
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006865/* OS#3041: Open and close N connections in a normal fashion, and expect no
6866 * BSSMAP Reset just because of that. */
6867testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6868 var default d;
6869 var integer i;
6870 var DchanTuple dt;
6871
6872 f_init();
6873
6874 /* Wait for initial BSSMAP Reset to pass */
6875 f_sleep(4.0);
6876
6877 d := activate(no_bssmap_reset());
6878
6879 /* Setup up a number of connections and RLSD them again from the MSC
6880 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6881 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006882 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006883 /* Since we're doing a lot of runs, give each one a fresh
6884 * T_guard from the top. */
6885 T_guard.start;
6886
6887 /* Setup a BSSAP connection and clear it right away. This is
6888 * the MSC telling the BSC about a planned release, it's not an
6889 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006890 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006891
6892 /* MSC disconnects (RLSD). */
6893 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6894 }
6895
6896 /* In the buggy behavior, a timeout of 2 seconds happens between above
6897 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6898 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6899 f_sleep(4.0);
6900
6901 deactivate(d);
6902 f_shutdown_helper();
6903}
Harald Welte552620d2017-12-16 23:21:36 +01006904
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006905/* OS#3041: Open and close N connections in a normal fashion, and expect no
6906 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6907 * the MSC. */
6908testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6909 var default d;
6910 var integer i;
6911 var DchanTuple dt;
6912 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006913 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6914 var BssmapCause cause := enum2int(cause_val);
6915
6916 f_init();
6917
6918 /* Wait for initial BSSMAP Reset to pass */
6919 f_sleep(4.0);
6920
6921 d := activate(no_bssmap_reset());
6922
6923 /* Setup up a number of connections and RLSD them again from the MSC
6924 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6925 * Let's do it some more times for good measure. */
6926 for (i := 0; i < 8; i := i+1) {
6927 /* Since we're doing a lot of runs, give each one a fresh
6928 * T_guard from the top. */
6929 T_guard.start;
6930
6931 /* Setup a BSSAP connection and clear it right away. This is
6932 * the MSC telling the BSC about a planned release, it's not an
6933 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006934 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006935
6936 /* Instruct BSC to clear channel */
6937 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6938
6939 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006940 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006941 }
6942
6943 /* In the buggy behavior, a timeout of 2 seconds happens between above
6944 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6945 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6946 f_sleep(4.0);
6947
6948 deactivate(d);
6949 f_shutdown_helper();
6950}
6951
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006952/* OS#3041: Open and close N connections in a normal fashion, and expect no
6953 * BSSMAP Reset just because of that. Close connections from the MS side with a
6954 * Release Ind on RSL. */
6955testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6956 var default d;
6957 var integer i;
6958 var DchanTuple dt;
6959 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006960 var integer j;
6961
6962 f_init();
6963
6964 /* Wait for initial BSSMAP Reset to pass */
6965 f_sleep(4.0);
6966
6967 d := activate(no_bssmap_reset());
6968
6969 /* Setup up a number of connections and RLSD them again from the MSC
6970 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6971 * Let's do it some more times for good measure. */
6972 for (i := 0; i < 8; i := i+1) {
6973 /* Since we're doing a lot of runs, give each one a fresh
6974 * T_guard from the top. */
6975 T_guard.start;
6976
6977 /* Setup a BSSAP connection and clear it right away. This is
6978 * the MSC telling the BSC about a planned release, it's not an
6979 * erratic loss of a connection. */
6980 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6981
6982 /* simulate RLL REL IND */
6983 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6984
6985 /* expect Clear Request on MSC side */
6986 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6987
6988 /* Instruct BSC to clear channel */
6989 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6990 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6991
6992 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006993 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006994 }
6995
6996 /* In the buggy behavior, a timeout of 2 seconds happens between above
6997 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6998 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6999 f_sleep(4.0);
7000
7001 deactivate(d);
7002 f_shutdown_helper();
7003}
7004
Harald Welte94e0c342018-04-07 11:33:23 +02007005/***********************************************************************
7006 * IPA style dynamic PDCH
7007 ***********************************************************************/
7008
7009private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7010 template (omit) RSL_Cause nack := omit)
7011runs on test_CT {
7012 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7013 var RSL_Message rsl_unused;
7014 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7015 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7016 /* expect the BSC to issue the related RSL command */
7017 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7018 if (istemplatekind(nack, "omit")) {
7019 /* respond with a related acknowledgement */
7020 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7021 } else {
7022 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
7023 }
7024}
7025
7026private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7027 template (omit) RSL_Cause nack := omit)
7028runs on test_CT {
7029 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7030 var RSL_Message rsl_unused;
7031 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7032 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7033 /* expect the BSC to issue the related RSL command */
7034 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
7035 if (istemplatekind(nack, "omit")) {
7036 /* respond with a related acknowledgement */
7037 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
7038 } else {
7039 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
7040 }
7041}
7042
7043private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7044runs on test_CT return charstring {
7045 var charstring cmd, resp;
7046 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007047 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007048}
7049
7050private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7051 template charstring exp)
7052runs on test_CT {
7053 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7054 if (not match(mode, exp)) {
7055 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007056 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007057 }
7058}
7059
7060private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7061runs on test_CT {
7062 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7063 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7064 f_vty_transceive(BSCVTY, "end");
7065}
7066
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007067
7068private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7069 var integer i;
7070 for (i := 0; i < 8; i := i + 1) {
7071 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7072 }
7073}
7074
Harald Welte94e0c342018-04-07 11:33:23 +02007075private const charstring TCHF_MODE := "TCH/F mode";
7076private const charstring TCHH_MODE := "TCH/H mode";
7077private const charstring PDCH_MODE := "PDCH mode";
7078private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007079private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007080
7081/* Test IPA PDCH activation / deactivation triggered by VTY */
7082testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7083 var RSL_Message rsl_unused;
7084
7085 /* change Timeslot 6 before f_init() starts RSL */
7086 f_init_vty();
7087 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7088 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7089
7090 f_init(1, false);
7091 f_sleep(1.0);
7092
7093 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7094
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007095 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007096 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7097 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7098 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7099 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7100 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007101 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007102 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7103
7104 /* De-activate it via VTY */
7105 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7106 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007107 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007108 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7109
7110 /* re-activate it via VTY */
7111 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7112 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007113 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007114 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7115
7116 /* and finally de-activate it again */
7117 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7118 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007119 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007120 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7121
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007122 /* clean up config */
7123 f_ts_set_chcomb(0, 0, 6, "PDCH");
7124
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007125 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007126}
7127
7128/* Test IPA PDCH activation NACK */
7129testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7130 var RSL_Message rsl_unused;
7131
7132 /* change Timeslot 6 before f_init() starts RSL */
7133 f_init_vty();
7134 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7135 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7136
7137 f_init(1, false);
7138 f_sleep(1.0);
7139
7140 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7141
7142 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7143 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7144 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7145 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7146 f_sleep(1.0);
7147 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7148
7149 /* De-activate it via VTY */
7150 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7151 f_sleep(1.0);
7152 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7153
7154 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7155 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7156 f_sleep(1.0);
7157 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7158
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007159 /* clean up config */
7160 f_ts_set_chcomb(0, 0, 6, "PDCH");
7161
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007162 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007163}
7164
7165
7166/***********************************************************************
7167 * Osmocom style dynamic PDCH
7168 ***********************************************************************/
7169
7170private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7171 template (omit) RSL_Cause nack := omit)
7172runs on test_CT {
7173 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7174 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007175 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007176 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7177 /* expect the BSC to issue the related RSL command */
7178 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7179 if (istemplatekind(nack, "omit")) {
7180 /* respond with a related acknowledgement */
7181 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7182 } else {
7183 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7184 }
7185}
7186
7187private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7188 template (omit) RSL_Cause nack := omit)
7189runs on test_CT {
7190 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7191 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007192 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007193 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7194 /* expect the BSC to issue the related RSL command */
7195 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7196 if (istemplatekind(nack, "omit")) {
7197 /* respond with a related acknowledgement */
7198 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7199 } else {
7200 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7201 }
7202}
7203
7204/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7205testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7206 var RSL_Message rsl_unused;
7207
7208 /* change Timeslot 6 before f_init() starts RSL */
7209 f_init_vty();
7210 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7211 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7212
7213 f_init(1, false);
7214 f_sleep(1.0);
7215
7216 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7217
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007218 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007219 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7220 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7221 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7222
7223 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7224 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007225 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 +02007226 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7227
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007228 /* clean up config */
7229 f_ts_set_chcomb(0, 0, 6, "PDCH");
7230
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007231 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007232}
7233
7234/* Test Osmocom dyn PDCH activation NACK behavior */
7235testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7236 var RSL_Message rsl_unused;
7237
7238 /* change Timeslot 6 before f_init() starts RSL */
7239 f_init_vty();
7240 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7241 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7242
7243 f_init(1, false);
7244 f_sleep(1.0);
7245
7246 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7247
7248 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7249 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7250 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7251
7252 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7253 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7254 f_sleep(1.0);
7255 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7256
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007257 /* clean up config */
7258 f_ts_set_chcomb(0, 0, 6, "PDCH");
7259
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007260 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007261}
7262
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007263/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7264testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7265 var RSL_Message rsl_unused, rsl_msg;
7266 var DchanTuple dt;
7267 var BSSAP_N_CONNECT_ind rx_c_ind;
7268
7269 /* change Timeslot 6 before f_init() starts RSL */
7270 f_init_vty();
7271 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7272 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7273
7274 f_init(1, false);
7275 f_sleep(1.0);
7276
7277 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7278
7279 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7280 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7281 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7282 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7283
7284 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7285 f_sleep(1.0);
7286 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7287 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7288
7289 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7290 * on CCCH+SDCCH4+CBCH) */
7291 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007292 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007293 dt := f_est_dchan('23'O, i, '00010203040506'O);
7294 }
7295
7296 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7297 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7298 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7299 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7300
7301 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7302 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7303
7304 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7305 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7306 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7307 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7308
7309 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7310 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7311 dt.sccp_conn_id := rx_c_ind.connectionId;
7312 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7313
7314 /* Instruct BSC to clear channel */
7315 var BssmapCause cause := 0;
7316 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7317 f_exp_chan_rel_and_clear(dt, 0);
7318
7319 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7320 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7321 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7322 f_sleep(1.0);
7323 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7324
7325 /* clean up config */
7326 f_ts_set_chcomb(0, 0, 6, "PDCH");
7327
7328 f_shutdown_helper();
7329}
7330
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007331/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7332testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7333 var ASP_RSL_Unitdata rsl_ud;
7334 var integer i;
7335 var integer chreq_total, chreq_nochan;
7336
7337 f_init_vty();
7338 for (i := 1; i < 8; i := i + 1) {
7339 if (i == 2) {
7340 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7341 } else {
7342 f_ts_set_chcomb(0, 0, i, "PDCH");
7343 }
7344 }
7345 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7346
7347 f_init(1);
7348
7349 /* The dyn TS want to activate PDCH mode, ACK that. */
7350 var RslChannelNr chan_nr;
7351 chan_nr := valueof(t_RslChanNr_PDCH(2));
7352 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7353 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7354
7355 f_sleep(1.0);
7356
7357 /* Exhaust all dedicated SDCCH lchans.
7358 /* GSM 44.018 Table 9.1.8.2:
7359 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7360 */
7361 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
7362 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7363 }
7364
7365 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
7366 f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7367 /* Also occupy the seven other SDCCH of the dyn TS */
7368 for (i := 0; i < 7; i := i+1) {
7369 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7370 }
7371
7372 /* clean up config */
7373 f_ts_reset_chcomb(0);
7374
7375 f_shutdown_helper();
7376}
7377
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007378/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7379 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7380 it as TCH directly instead. SYS#5309. */
7381testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7382 var RSL_Message rsl_unused, rsl_msg;
7383 var DchanTuple dt;
7384 var BSSAP_N_CONNECT_ind rx_c_ind;
7385 var integer i;
7386
7387 /* change Timeslot 6 before f_init() starts RSL */
7388 f_init_vty();
7389 for (i := 1; i < 8; i := i + 1) {
7390 if (i == 6) {
7391 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7392 } else {
7393 f_ts_set_chcomb(0, 0, i, "PDCH");
7394 }
7395 }
7396 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7397
7398 f_init(1, false);
7399 f_sleep(1.0);
7400
7401 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7402
7403 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7404 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7405 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7406 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7407
7408 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7409 f_sleep(1.0);
7410 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7411 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7412
7413 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7414 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007415 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007416 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007417 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007418 }
7419
7420 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007421 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007422 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7423 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7424
7425 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7426 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7427
7428 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7429 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7430 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7431 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7432
7433 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7434 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7435 dt.sccp_conn_id := rx_c_ind.connectionId;
7436 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7437
7438 /* Instruct BSC to clear channel */
7439 var BssmapCause cause := 0;
7440 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7441 f_exp_chan_rel_and_clear(dt, 0);
7442
7443 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7444 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7445 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7446 f_sleep(1.0);
7447 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7448
7449 /* clean up config */
7450 f_ts_reset_chcomb(0);
7451 /* TODO: clean up other channels? */
7452
7453 f_shutdown_helper();
7454}
7455
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007456/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7457testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7458 var RSL_Message rsl_unused, rsl_msg;
7459 var DchanTuple dt;
7460 var BSSAP_N_CONNECT_ind rx_c_ind;
7461 var GsmRrMessage rr;
7462
7463 /* change Timeslot 6 before f_init() starts RSL */
7464 f_init_vty();
7465 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7466 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7467
7468 f_init(1, false);
7469 f_sleep(1.0);
7470
7471 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7472
7473 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7474 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7475 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7476 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7477
7478 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7479 f_sleep(1.0);
7480 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7481 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7482
7483 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7484 * on CCCH+SDCCH4+CBCH) */
7485 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007486 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007487 dt := f_est_dchan('23'O, i, '00010203040506'O);
7488 }
7489
7490 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7491 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7492 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7493 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7494
7495 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7496 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7497
7498 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7499 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7500 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7501 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7502 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7503 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7504 }
7505
7506 /* FIXME? Currently the TS stays in state BORKEN: */
7507
7508 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7509 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7510 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7511 * f_sleep(1.0);
7512 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7513 */
7514
7515 /* clean up config */
7516 f_ts_set_chcomb(0, 0, 6, "PDCH");
7517
7518 f_shutdown_helper();
7519}
7520
Stefan Sperling0796a822018-10-05 13:01:39 +02007521testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007522 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007523 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7524 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7525 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007526 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007527}
7528
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007529testcase TC_chopped_ipa_payload() runs on test_CT {
7530 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7531 /* TODO: mp_bsc_ctrl_port does not work yet */};
7532 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7533 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7534 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007535 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007536}
7537
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007538/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7539 the BTS does autonomous MS power control loop */
7540testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7541 var MSC_ConnHdlr vc_conn;
7542 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7543 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7544 pars.exp_ms_power_params := true;
7545
7546 f_init(1, true);
7547 f_sleep(1.0);
7548 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7549 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007550 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007551}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007552
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007553/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7554testcase TC_c0_power_red_mode() runs on test_CT {
7555 f_init(1);
7556
7557 for (var integer red := 6; red >= 0; red := red - 2) {
7558 /* Configure BCCH carrier power reduction mode via the VTY */
7559 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7560
7561 /* Expect Osmocom specific BS Power Control message on the RSL */
7562 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7563 chan_nr := t_RslChanNr_BCCH(0),
7564 bs_power := tr_RSL_IE_BS_Power(red / 2));
7565 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7566 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7567
7568 /* Additionally verify the applied value over the CTRL interface */
7569 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7570 if (cred != int2str(red)) {
7571 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7572 cred, " (expected ", red, ")");
7573 }
7574 }
7575
7576 f_shutdown_helper();
7577}
7578
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007579/***********************************************************************
7580 * MSC Pooling
7581 ***********************************************************************/
7582
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007583template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007584 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 +02007585
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007586private 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 +02007587runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007588 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007589 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007590 f_logp(BSCVTY, "Got RSL RR Release");
7591 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007592 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007593 f_logp(BSCVTY, "Got RSL Deact SACCH");
7594 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007595 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007596 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007597 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7598 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007599 break;
7600 }
7601 }
7602}
7603
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007604friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7605 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007606runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007607 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007608 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7609 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007610 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007611 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007612 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007613 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007614 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007615 }
7616 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007617 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007618 /* Also drop the SCCP connection */
7619 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7620 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007621 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007622 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007623 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7624 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007625 }
7626 }
7627}
7628
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007629private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7630 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007631runs on MSC_ConnHdlr {
7632 timer T := 10.0;
7633 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7634
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007635 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007636 f_create_bssmap_exp(l3_enc);
7637
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007638 /* RSL_Emulation.f_chan_est() on rsl_pt:
7639 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007640 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7641 */
7642 var RSL_Message rx_rsl;
7643 var GsmRrMessage rr;
7644
7645 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007646 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007647 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007648 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007649 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7650 */
7651 timer Tt := 10.0;
7652
7653 /* request a channel to be established */
7654 Tt.start;
7655 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007656 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007657 Tt.stop;
7658 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007659 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007660 setverdict(fail, "Unexpected RSL message on DCHAN");
7661 mtc.stop;
7662 }
7663 [] Tt.timeout {
7664 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7665 mtc.stop;
7666 }
7667 }
7668 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7669 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007670 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007671
7672
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007673 if (expect_bssmap_l3) {
7674 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7675 var template PDU_BSSAP exp_l3_compl;
7676 exp_l3_compl := tr_BSSMAP_ComplL3()
7677 if (g_pars.aoip == false) {
7678 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7679 } else {
7680 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7681 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007682
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007683 var PDU_BSSAP bssap;
7684 T.start;
7685 alt {
7686 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7687 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7688 log("rx exp_l3_compl = ", bssap);
7689 }
7690 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7691 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7692 }
7693 [] T.timeout {
7694 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7695 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007696 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007697
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007698 /* start ciphering, if requested */
7699 if (ispresent(g_pars.encr)) {
7700 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007701 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007702 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007703 }
7704
7705 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007706 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007707 }
7708 setverdict(pass);
7709 f_sleep(1.0);
7710}
7711
7712private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7713 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7714 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007715 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007716 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007717 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007718 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007719 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007720 }
7721}
7722
7723/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7724private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7725 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007726 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7727 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7728 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7729 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 +02007730}
7731testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7732
7733 f_init(1, true);
7734 f_sleep(1.0);
7735 var MSC_ConnHdlr vc_conn;
7736 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007737
7738 f_ctrs_msc_init();
7739
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007740 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7741 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007742
7743 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007744 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007745}
7746
7747/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7748/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7749 * just as well using only RSL. */
7750testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7751
7752 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7753 f_sleep(1.0);
7754
7755 /* Control which MSC gets chosen next by the round-robin, otherwise
7756 * would be randomly affected by which other tests ran before this. */
7757 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7758
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007759 f_ctrs_msc_init();
7760
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007761 var MSC_ConnHdlr vc_conn1;
7762 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7763 pars1.mscpool.rsl_idx := 0;
7764 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7765 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7766 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007767 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007768
7769 var MSC_ConnHdlr vc_conn2;
7770 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7771 pars2.mscpool.rsl_idx := 1;
7772 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7773 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7774 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007775 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007776
7777 /* Test round-robin wrap to the first MSC */
7778 var MSC_ConnHdlr vc_conn3;
7779 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7780 pars3.mscpool.rsl_idx := 2;
7781 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7782 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7783 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007784 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007785 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007786}
7787
7788/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7789 * (configured in osmo-bsc.cfg). */
7790/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7791 * just as well using only RSL. */
7792testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7793
7794 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7795 f_sleep(1.0);
7796
7797 /* Control which MSC gets chosen next by the round-robin, otherwise
7798 * would be randomly affected by which other tests ran before this. */
7799 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7800
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007801 f_ctrs_msc_init();
7802
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007803 var MSC_ConnHdlr vc_conn1;
7804 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7805 pars1.mscpool.rsl_idx := 0;
7806 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7807 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7808 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007809 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007810
7811 var MSC_ConnHdlr vc_conn2;
7812 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7813 pars2.mscpool.rsl_idx := 1;
7814 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7815 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7816 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007817 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007818
7819 /* Test round-robin wrap to the first MSC */
7820 var MSC_ConnHdlr vc_conn3;
7821 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7822 pars3.mscpool.rsl_idx := 2;
7823 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7824 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7825 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007826 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007827 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007828}
7829
7830/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7831 * (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
7832 * NULL-NRI setting is stronger than that. */
7833/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7834 * just as well using only RSL. */
7835testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7836
7837 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7838 f_sleep(1.0);
7839
7840 /* Control which MSC gets chosen next by the round-robin, otherwise
7841 * would be randomly affected by which other tests ran before this. */
7842 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7843
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007844 f_ctrs_msc_init();
7845
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007846 var MSC_ConnHdlr vc_conn1;
7847 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7848 pars1.mscpool.rsl_idx := 0;
7849 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7850 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7851 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007852 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007853
7854 var MSC_ConnHdlr vc_conn2;
7855 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7856 pars2.mscpool.rsl_idx := 1;
7857 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7858 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7859 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007860 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007861
7862 /* Test round-robin wrap to the first MSC */
7863 var MSC_ConnHdlr vc_conn3;
7864 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7865 pars3.mscpool.rsl_idx := 2;
7866 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7867 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7868 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007869 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007870 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007871}
7872
7873/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7874 * assigned to any MSC (configured in osmo-bsc.cfg). */
7875/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7876 * just as well using only RSL. */
7877testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7878
7879 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7880 f_sleep(1.0);
7881
7882 /* Control which MSC gets chosen next by the round-robin, otherwise
7883 * would be randomly affected by which other tests ran before this. */
7884 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7885
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007886 f_ctrs_msc_init();
7887
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007888 var MSC_ConnHdlr vc_conn1;
7889 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7890 pars1.mscpool.rsl_idx := 0;
7891 /* An NRI that is not assigned to any MSC */
7892 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7893 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7894 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007895 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007896
7897 var MSC_ConnHdlr vc_conn2;
7898 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7899 pars2.mscpool.rsl_idx := 1;
7900 /* An NRI that is not assigned to any MSC */
7901 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7902 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7903 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007904 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007905
7906 /* Test round-robin wrap to the first MSC */
7907 var MSC_ConnHdlr vc_conn3;
7908 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7909 pars3.mscpool.rsl_idx := 2;
7910 /* An NRI that is not assigned to any MSC */
7911 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7912 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7913 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007914 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007915 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007916}
7917
7918/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7919 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7920/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7921 * just as well using only RSL. */
7922testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7923
7924 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7925 f_sleep(1.0);
7926
7927 /* Control which MSC gets chosen next by the round-robin, otherwise
7928 * would be randomly affected by which other tests ran before this. */
7929 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7930
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007931 f_ctrs_msc_init();
7932
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007933 var MSC_ConnHdlr vc_conn1;
7934 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7935 pars1.mscpool.rsl_idx := 0;
7936 /* An NRI that is assigned to an unconnected MSC */
7937 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7938 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7939 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007940 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7941 f_ctrs_msc_add(0, "mscpool:subscr:new");
7942 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007943
7944 var MSC_ConnHdlr vc_conn2;
7945 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7946 pars2.mscpool.rsl_idx := 1;
7947 /* An NRI that is assigned to an unconnected MSC */
7948 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7949 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7950 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007951 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7952 f_ctrs_msc_add(1, "mscpool:subscr:new");
7953 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007954
7955 /* Test round-robin wrap to the first MSC */
7956 var MSC_ConnHdlr vc_conn3;
7957 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7958 pars3.mscpool.rsl_idx := 2;
7959 /* An NRI that is assigned to an unconnected MSC */
7960 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7961 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7962 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007963 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7964 f_ctrs_msc_add(0, "mscpool:subscr:new");
7965 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007966 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007967}
7968
7969/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7970 * osmo-bsc.cfg). */
7971/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7972 * just as well using only RSL. */
7973testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7974
7975 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7976 f_sleep(1.0);
7977
7978 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7979 * this is not using round-robin. */
7980 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7981
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007982 f_ctrs_msc_init();
7983
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007984 var MSC_ConnHdlr vc_conn1;
7985 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7986 pars1.mscpool.rsl_idx := 0;
7987 /* An NRI of the second MSC's range (256-511) */
7988 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7989 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7990 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007991 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007992
7993 var MSC_ConnHdlr vc_conn2;
7994 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7995 pars2.mscpool.rsl_idx := 1;
7996 /* An NRI of the second MSC's range (256-511) */
7997 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7998 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7999 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008000 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008001
8002 var MSC_ConnHdlr vc_conn3;
8003 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8004 pars3.mscpool.rsl_idx := 2;
8005 /* An NRI of the second MSC's range (256-511) */
8006 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8007 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8008 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008009 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008010 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008011}
8012
8013/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8014 * while a round-robin remains unaffected by that. */
8015/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8016 * just as well using only RSL. */
8017testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8018
8019 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8020 f_sleep(1.0);
8021
8022 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8023 * this is not using round-robin. */
8024 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8025
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008026 f_ctrs_msc_init();
8027
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008028 var MSC_ConnHdlr vc_conn1;
8029 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8030 pars1.mscpool.rsl_idx := 0;
8031 /* An NRI of the third MSC's range (512-767) */
8032 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8033 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8034 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008035 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008036
8037 var MSC_ConnHdlr vc_conn2;
8038 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8039 pars2.mscpool.rsl_idx := 1;
8040 /* An NRI of the third MSC's range (512-767) */
8041 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8042 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8043 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008044 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008045
8046 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8047 var MSC_ConnHdlr vc_conn3;
8048 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8049 pars3.mscpool.rsl_idx := 2;
8050 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8051 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8052 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008053 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008054 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008055}
8056
8057/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8058/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8059 * just as well using only RSL. */
8060testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8061
8062 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8063 f_sleep(1.0);
8064
8065 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8066 * instead, and hits msc 0. */
8067 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8068
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008069 f_ctrs_msc_init();
8070
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008071 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8072 var MSC_ConnHdlr vc_conn1;
8073 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8074 pars1.mscpool.rsl_idx := 0;
8075 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8076 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8077 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008078 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008079
8080 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8081 var MSC_ConnHdlr vc_conn2;
8082 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8083 pars2.mscpool.rsl_idx := 1;
8084 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8085 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8086 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008087 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008088 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008089}
8090
8091/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8092 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8093private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8094 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8095 //cid_list := { cIl_allInBSS := ''O };
8096 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8097 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8098 var BSSAP_N_UNITDATA_req paging;
8099 var hexstring imsi := '001010000000123'H;
8100
8101 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8102
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008103 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008104 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8105 BSSAP.send(paging);
8106
8107 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8108 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8109 * channel number is picked here. */
8110 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8111 f_rslem_register(0, new_chan_nr);
8112 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8113 f_rslem_unregister(0, new_chan_nr);
8114
8115 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8116 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008117 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008118 f_sleep(1.0);
8119}
8120testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8121 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8122 f_sleep(1.0);
8123
8124 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8125 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8126 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8127
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008128 f_ctrs_msc_init();
8129
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008130 var MSC_ConnHdlr vc_conn1;
8131 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8132 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008133 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8134 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008135 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8136 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008137 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008138 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008139}
8140
8141/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8142 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8143private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8144 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8145 //cid_list := { cIl_allInBSS := ''O };
8146 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8147 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8148 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008149 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008150 var BSSAP_N_UNITDATA_req paging;
8151
8152 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8153
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008154 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008155 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8156 BSSAP.send(paging);
8157
8158 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8159 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8160 * channel number is picked here. */
8161 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8162 f_rslem_register(0, new_chan_nr);
8163 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8164 f_rslem_unregister(0, new_chan_nr);
8165
8166 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8167 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8168 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008169 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 +02008170 f_sleep(1.0);
8171}
8172testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8173 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8174 f_sleep(1.0);
8175
8176 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8177 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8178 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8179
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008180 f_ctrs_msc_init();
8181
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008182 var MSC_ConnHdlr vc_conn1;
8183 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8184 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008185 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8186 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008187 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8188 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008189 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008190 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008191}
8192
8193/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8194/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8195 * just as well using only RSL. */
8196testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8197
8198 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8199 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008200 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8201 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008202
8203 /* Control which MSC gets chosen next by the round-robin, otherwise
8204 * would be randomly affected by which other tests ran before this. */
8205 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8206
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008207 f_ctrs_msc_init();
8208
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008209 var MSC_ConnHdlr vc_conn1;
8210 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8211 pars1.mscpool.rsl_idx := 0;
8212 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8213 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8214 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008215 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008216
8217 var MSC_ConnHdlr vc_conn2;
8218 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8219 pars2.mscpool.rsl_idx := 1;
8220 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8221 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8222 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008223 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008224
8225 var MSC_ConnHdlr vc_conn3;
8226 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8227 pars3.mscpool.rsl_idx := 2;
8228 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8229 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8230 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008231 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008232 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008233}
8234
8235/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8236 * TMSI NRI. */
8237testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8238
8239 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8240 f_sleep(1.0);
8241
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008242 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8243 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8244
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008245 /* Control which MSC gets chosen next by the round-robin, otherwise
8246 * would be randomly affected by which other tests ran before this. */
8247 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8248
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008249 f_ctrs_msc_init();
8250
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008251 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8252 var MSC_ConnHdlr vc_conn1;
8253 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8254 pars1.mscpool.rsl_idx := 0;
8255 /* An NRI of the second MSC's range (256-511) */
8256 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8257 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8258 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008259 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008260
8261 var MSC_ConnHdlr vc_conn2;
8262 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8263 pars2.mscpool.rsl_idx := 1;
8264 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8265 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8266 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008267 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008268
8269 var MSC_ConnHdlr vc_conn3;
8270 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8271 pars3.mscpool.rsl_idx := 2;
8272 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8273 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8274 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008275 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008276 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008277}
8278
Philipp Maier783681c2020-07-16 16:47:06 +02008279/* Allow/Deny emergency calls globally via VTY */
8280private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8281 f_vty_enter_cfg_msc(BSCVTY, 0);
8282 if (allow) {
8283 f_vty_transceive(BSCVTY, "allow-emergency allow");
8284 } else {
8285 f_vty_transceive(BSCVTY, "allow-emergency deny");
8286 }
8287 f_vty_transceive(BSCVTY, "exit");
8288 f_vty_transceive(BSCVTY, "exit");
8289}
8290
8291/* Allow/Deny emergency calls per BTS via VTY */
8292private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8293 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8294 if (allow) {
8295 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8296 } else {
8297 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8298 }
8299 f_vty_transceive(BSCVTY, "exit");
8300 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008301 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008302}
8303
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008304/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8305private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8306 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8307 if (allow) {
8308 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8309 } else {
8310 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8311 }
8312 f_vty_transceive(BSCVTY, "exit");
8313 f_vty_transceive(BSCVTY, "exit");
8314 f_vty_transceive(BSCVTY, "exit");
8315}
8316
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008317/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8318private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8319 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8320 if (allow) {
8321 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8322 } else {
8323 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8324 }
8325 f_vty_transceive(BSCVTY, "exit");
8326 f_vty_transceive(BSCVTY, "exit");
8327 f_vty_transceive(BSCVTY, "exit");
8328}
8329
Philipp Maier783681c2020-07-16 16:47:06 +02008330/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8331private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8332 var PDU_ML3_MS_NW emerg_setup;
8333 var octetstring emerg_setup_enc;
8334 var RSL_Message emerg_setup_data_ind;
8335
8336 f_establish_fully(omit, omit);
8337
8338 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8339 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8340 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8341
8342 RSL.send(emerg_setup_data_ind);
8343}
8344
8345/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8346 * CALLS are permitted by the BSC config. */
8347private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8348 var PDU_BSSAP emerg_setup_data_ind_bssap;
8349 var PDU_ML3_MS_NW emerg_setup;
8350 timer T := 3.0;
8351
8352 f_assignment_emerg_setup()
8353
8354 T.start;
8355 alt {
8356 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8357 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8358 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8359 setverdict(fail, "no emergency setup");
8360 }
8361 }
8362 [] BSSAP.receive {
8363 setverdict(fail, "unexpected BSSAP message!");
8364 }
8365 [] T.timeout {
8366 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8367 }
8368 }
8369
8370 setverdict(pass);
8371}
8372
8373/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8374 * forbidden by the BSC config. */
8375private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8376 var PDU_BSSAP emerg_setup_data_ind_bssap;
8377 timer T := 3.0;
8378
8379 f_assignment_emerg_setup()
8380
8381 T.start;
8382 alt {
8383 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8384 setverdict(pass);
8385 }
8386 [] RSL.receive {
8387 setverdict(fail, "unexpected RSL message!");
8388 }
8389 [] T.timeout {
8390 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8391 }
8392 }
8393}
8394
8395/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8396testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8397 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8398 var MSC_ConnHdlr vc_conn;
8399
8400 f_init(1, true);
8401 f_sleep(1.0);
8402
8403 f_vty_allow_emerg_msc(true);
8404 f_vty_allow_emerg_bts(true, 0);
8405 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8406 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008407 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008408}
8409
8410/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8411testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8412 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8413 var MSC_ConnHdlr vc_conn;
8414
8415 f_init(1, true);
8416 f_sleep(1.0);
8417
8418 f_vty_allow_emerg_msc(false);
8419 f_vty_allow_emerg_bts(true, 0);
8420 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8421 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008422 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008423}
8424
8425/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8426testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8427 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8428 var MSC_ConnHdlr vc_conn;
8429
8430 /* Note: This simulates a spec violation by the MS, correct MS
8431 * implementations would not try to establish an emergency call because
8432 * the system information tells in advance that emergency calls are
8433 * not forbidden */
8434
8435 f_init(1, true);
8436 f_sleep(1.0);
8437
8438 f_vty_allow_emerg_msc(true);
8439 f_vty_allow_emerg_bts(false, 0);
8440 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8441 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008442 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008443}
8444
Philipp Maier82812002020-08-13 18:48:27 +02008445/* Test what happens when an emergency call arrives while all TCH channels are
8446 * busy, the BSC is expected to terminate one call in favor of the incoming
8447 * emergency call */
8448testcase TC_emerg_premption() runs on test_CT {
8449 var ASP_RSL_Unitdata rsl_ud;
8450 var integer i;
8451 var integer chreq_total, chreq_nochan;
8452 var RSL_Message rx_rsl;
8453 var RslChannelNr chan_nr;
8454
8455 f_init(1);
8456 f_sleep(1.0);
8457
8458 f_vty_allow_emerg_msc(true);
8459 f_vty_allow_emerg_bts(true, 0);
8460
8461 /* Fill up all channels on the BTS */
8462 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8463 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8464 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8465 chan_nr := f_chreq_act_ack('33'O, i);
8466 }
8467 IPA_RSL[0].clear;
8468 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8469 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8470
8471 /* Send Channel request for emegergency call */
8472 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8473
8474 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8475 chan_nr := valueof(t_RslChanNr_Bm(1));
8476 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8477
8478 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8479 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8480 chan_nr := rx_rsl.ies[0].body.chan_nr;
8481 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8482 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008483
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008484 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008485}
8486
8487/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008488private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008489private type record FHParamsTs {
8490 boolean enabled,
8491 uint6_t hsn,
8492 uint6_t maio,
8493 ArfcnList ma
8494};
8495
8496/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008497private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02008498 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008499 FHParamsTs ts[8]
8500};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008501
8502/* Randomly generate the hopping parameters for the given timeslot numbers */
8503private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8504runs on test_CT return FHParamsTrx {
8505 var FHParamsTrx fhp;
8506
Philipp Maier798d8952021-10-19 14:43:19 +02008507 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
8508 * fall in the GSM900 band. */
8509 fhp.arfcn.arfcn := f_rnd_int(3);
8510 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008511
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008512 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8513 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008514 fhp.ts[tn].enabled := false;
8515 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008516 continue;
8517 }
8518
8519 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008520 fhp.ts[tn].hsn := f_rnd_int(64);
8521 fhp.ts[tn].maio := f_rnd_int(64);
8522 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008523
8524 /* Random Mobile Allocation (hopping channels) */
8525 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8526 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8527 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008528 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008529 }
8530
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008531 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008532 }
8533
8534 log("f_TC_fh_params_gen(): ", fhp);
8535 return fhp;
8536}
8537
8538/* Make sure that the given Channel Description IE matches the hopping configuration */
8539private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8540{
8541 var template (present) ChannelDescription tr_cd;
8542 var template (present) MaioHsn tr_maio_hsn;
8543 var uint3_t tn := cd.chan_nr.tn;
8544
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008545 if (fhp.ts[tn].enabled) {
8546 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008547 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8548 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02008549 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008550 }
8551
8552 if (not match(cd, tr_cd)) {
8553 setverdict(fail, "Channel Description IE does not match: ",
8554 cd, " vs expected ", tr_cd);
8555 }
8556}
8557
8558/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8559private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8560 in MobileAllocationLV ma)
8561{
8562 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8563
8564 if (not match(ma, tr_ma)) {
8565 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8566 tn, "): ", ma, " vs expected: ", tr_ma);
8567 } else {
8568 setverdict(pass);
8569 }
8570}
8571
8572private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8573 in MobileAllocationLV ma)
8574return template MobileAllocationLV {
8575 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008576 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008577 return { len := 0, ma := ''B };
8578 }
8579
8580 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8581 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8582 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008583
8584 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008585 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8586 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8587 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008588 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008589 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008590 }
8591 }
8592
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008593 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02008594 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008595
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008596 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008597 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8598 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008599 }
8600
8601 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008602 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008603 if (full_mask[i] != '1'B)
8604 { continue; }
8605
8606 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8607 if (slot_mask[i] == '1'B) {
8608 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008609 } else {
8610 ma_mask := ma_mask & '0'B;
8611 }
8612 }
8613
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008614 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8615 if (full_mask[0] == '1'B) {
8616 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8617 if (slot_mask[0] == '1'B) {
8618 ma_mask := ma_mask & '1'B;
8619 } else {
8620 ma_mask := ma_mask & '0'B;
8621 }
8622 }
8623
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008624 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008625 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008626 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8627
8628 return { len := ma_mask_len, ma := ma_mask };
8629}
8630
Philipp Maier798d8952021-10-19 14:43:19 +02008631/* Configure the appropriate band for a given arfcn, exc */
8632private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
8633{
8634 var charstring band;
8635 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
8636
8637 select (arfcn_) {
8638 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
8639 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
8640 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
8641 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
8642 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
8643 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
8644 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
8645 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
8646 case else { return; }
8647 }
8648
8649 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8650 f_vty_transceive(BSCVTY, "band " & band);
8651 f_vty_transceive(BSCVTY, "end");
8652}
8653
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008654/* Configure the hopping parameters in accordance with the given record */
8655private function f_TC_fh_params_set(in FHParamsTrx fhp,
8656 uint8_t bts_nr := 0,
8657 uint8_t trx_nr := 0)
8658runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008659
8660 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
8661
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008662 /* Enter the configuration node for the given BTS/TRX numbers */
8663 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8664
Philipp Maier798d8952021-10-19 14:43:19 +02008665 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008666
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008667 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008668 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8669
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008670 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008671 f_vty_transceive(BSCVTY, "hopping enabled 0");
8672 f_vty_transceive(BSCVTY, "exit"); /* go back */
8673 continue;
8674 }
8675
8676 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008677 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8678 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008679
8680 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008681 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8682 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008683 }
8684
8685 f_vty_transceive(BSCVTY, "hopping enabled 1");
8686 f_vty_transceive(BSCVTY, "exit"); /* go back */
8687 }
8688
8689 f_vty_transceive(BSCVTY, "end");
8690}
8691
8692/* Disable frequency hopping on all timeslots */
8693private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8694 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008695 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02008696 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008697runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008698
8699 f_TC_set_band_by_arfcn(bts_nr, arfcn);
8700
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008701 /* Enter the configuration node for the given BTS/TRX numbers */
8702 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8703
Philipp Maier798d8952021-10-19 14:43:19 +02008704 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008705
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008706 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008707 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8708
8709 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008710 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8711 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008712 }
8713
8714 f_vty_transceive(BSCVTY, "hopping enabled 0");
8715 f_vty_transceive(BSCVTY, "exit"); /* go back */
8716 }
8717
8718 f_vty_transceive(BSCVTY, "end");
8719 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8720}
8721
8722/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8723 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8724testcase TC_fh_params_chan_activ() runs on test_CT {
8725 var FHParamsTrx fhp := f_TC_fh_params_gen();
8726 var RSL_Message rsl_msg;
8727 var RSL_IE_Body ie;
8728
8729 f_init_vty();
8730
8731 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8732 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8733
8734 f_init(1);
8735
8736 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8737 for (var integer i := 0; i < 9; i := i + 1) {
8738 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8739 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8740
8741 /* Make sure that Channel Identification IE is present */
8742 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8743 setverdict(fail, "RSL Channel Identification IE is absent");
8744 continue;
8745 }
8746
8747 /* Make sure that hopping parameters (HSN/MAIO) match */
8748 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8749
8750 /* "Mobile Allocation shall be included but empty" - let's check this */
8751 if (ie.chan_ident.ma.v.len != 0) {
8752 setverdict(fail, "Mobile Allocation IE is not empty: ",
8753 ie.chan_ident.ma, ", despite it shall be");
8754 continue;
8755 }
8756 }
8757
8758 /* Disable frequency hopping */
8759 f_TC_fh_params_unset(fhp);
8760
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008761 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008762}
8763
8764/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8765testcase TC_fh_params_imm_ass() runs on test_CT {
8766 var FHParamsTrx fhp := f_TC_fh_params_gen();
8767 var RSL_Message rsl_msg;
8768 var RSL_IE_Body ie;
8769
8770 f_init_vty();
8771
8772 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8773 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8774
8775 f_init(1);
8776
8777 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8778 for (var integer i := 0; i < 9; i := i + 1) {
8779 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8780 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8781
8782 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8783 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8784
8785 /* Make sure that Full Immediate Assign Info IE is present */
8786 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8787 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8788 continue;
8789 }
8790
8791 /* Decode the actual Immediate Assignment message */
8792 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8793 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8794 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8795 continue;
8796 }
8797
8798 /* Make sure that hopping parameters (HSN/MAIO) match */
8799 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8800
8801 /* Make sure that the Mobile Allocation IE matches */
8802 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8803 rr_msg.payload.imm_ass.mobile_allocation);
8804 }
8805
8806 /* Disable frequency hopping */
8807 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008808
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008809 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008810}
8811
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008812/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8813testcase TC_fh_params_assignment_cmd() runs on test_CT {
8814 var FHParamsTrx fhp := f_TC_fh_params_gen();
8815 var RSL_Message rsl_msg;
8816 var RSL_IE_Body ie;
8817
8818 f_init_vty();
8819
8820 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8821 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8822
8823 f_init(1);
8824
8825 /* HACK: work around "Couldn't find Expect for CRCX" */
8826 vc_MGCP.stop;
8827
8828 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8829 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8830
8831 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8832 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8833 for (var integer i := 0; i < 3; i := i + 1) {
8834 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8835 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8836
8837 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8838 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8839 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8840
8841 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8842 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8843 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8844
8845 /* Make sure that L3 Information IE is present */
8846 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8847 setverdict(fail, "RSL L3 Information IE is absent");
8848 continue;
8849 }
8850
8851 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8852 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8853 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8854 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8855 continue;
8856 }
8857
8858 /* Make sure that hopping parameters (HSN/MAIO) match */
8859 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8860 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8861
8862 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8863 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008864 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008865 continue;
8866 }
8867
8868 /* Make sure that the Mobile Allocation IE matches (if present) */
8869 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8870 if (chan_desc.h and ma_present) {
8871 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8872 l3_msg.payload.ass_cmd.mobile_allocation.v);
8873 } else if (chan_desc.h and not ma_present) {
8874 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8875 continue;
8876 } else if (not chan_desc.h and ma_present) {
8877 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8878 continue;
8879 }
8880 }
8881
8882 /* Give the IUT some time to release all channels */
8883 f_sleep(3.0);
8884
8885 /* Disable frequency hopping */
8886 f_TC_fh_params_unset(fhp);
8887
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008888 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008889}
8890
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008891/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8892private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8893runs on test_CT {
8894 var RSL_Message rsl_msg;
8895 var RSL_IE_Body ie;
8896 var DchanTuple dt;
8897
8898 /* Establish a dedicated channel, so we can trigger handover */
8899 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03008900 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008901
8902 /* Trigger handover from BTS0 to BTS1 */
8903 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8904 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8905
8906 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8907 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8908
8909 /* ACKnowledge channel activation and expect (RR) Handover Command */
8910 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8911 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8912
8913 /* Make sure that L3 Information IE is present */
8914 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8915 setverdict(fail, "RSL L3 Information IE is absent");
8916 return;
8917 }
8918
8919 /* Decode the L3 message and make sure it is (RR) Handover Command */
8920 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8921 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8922 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8923 return;
8924 }
8925
8926 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8927 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8928 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8929 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8930 return;
8931 }
8932
8933 /* Make sure that hopping parameters (HSN/MAIO) match */
8934 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8935
8936 /* Make sure that Cell Channel Description IE is present */
8937 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8938 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8939 return;
8940 }
8941
8942 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8943 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8944 if (ma_present) {
8945 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8946 l3_msg.payload.ho_cmd.mobile_allocation.v);
8947 } else {
8948 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8949 return;
8950 }
8951}
8952testcase TC_fh_params_handover_cmd() runs on test_CT {
8953 var FHParamsTrx fhp := f_TC_fh_params_gen();
8954
8955 f_init_vty();
8956
8957 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8958 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8959
8960 f_vty_transceive(BSCVTY, "timeslot 0");
8961 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8962 f_vty_transceive(BSCVTY, "exit"); /* go back */
8963
8964 f_vty_transceive(BSCVTY, "timeslot 1");
8965 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8966 f_vty_transceive(BSCVTY, "end"); /* we're done */
8967
8968 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8969 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8970
8971 f_init(2);
8972
8973 f_TC_fh_params_handover_cmd(fhp);
8974
8975 /* Disable frequency hopping on BTS1 */
8976 f_TC_fh_params_unset(fhp, 1);
8977
8978 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8979 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8980
8981 f_vty_transceive(BSCVTY, "timeslot 0");
8982 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8983 f_vty_transceive(BSCVTY, "exit"); /* go back */
8984
8985 f_vty_transceive(BSCVTY, "timeslot 1");
8986 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8987 f_vty_transceive(BSCVTY, "end"); /* we're done */
8988
8989 f_shutdown_helper();
8990}
8991
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008992/* Verify the hopping parameters in System Information Type 4 */
8993testcase TC_fh_params_si4_cbch() runs on test_CT {
8994 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8995 var ASP_RSL_Unitdata rx_rsl_ud;
8996 timer T := 5.0;
8997
8998 f_init_vty();
8999
9000 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9001 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9002
9003 f_vty_transceive(BSCVTY, "timeslot 0");
9004 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9005 f_vty_transceive(BSCVTY, "exit"); /* go back */
9006
9007 f_vty_transceive(BSCVTY, "timeslot 1");
9008 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9009 f_vty_transceive(BSCVTY, "end"); /* we're done */
9010
9011 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9012 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9013
9014 f_init(1);
9015
9016 T.start;
9017 alt {
9018 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
9019 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9020 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9021
9022 /* Make sure that what we decoded is System Information Type 4 */
9023 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9024 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9025 repeat;
9026 }
9027
9028 /* Make sure that CBCH Channel Description IE is present */
9029 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9030 setverdict(fail, "CBCH Channel Description IE is absent");
9031 break;
9032 }
9033
9034 /* Finally, check the hopping parameters (HSN, MAIO) */
9035 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9036 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9037
9038 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9039 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9040 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9041 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9042 break;
9043 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9044 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9045 si.payload.si4.cbch_mobile_alloc.v);
9046 }
9047 }
9048 [] IPA_RSL[0].receive { repeat; }
9049 [] T.timeout {
9050 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9051 }
9052 }
9053
9054 /* Disable frequency hopping */
9055 f_TC_fh_params_unset(fhp);
9056
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009057 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009058 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9059
9060 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009061 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009062 f_vty_transceive(BSCVTY, "exit"); /* go back */
9063
9064 f_vty_transceive(BSCVTY, "timeslot 1");
9065 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9066 f_vty_transceive(BSCVTY, "end"); /* we're done */
9067
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009068 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009069}
9070
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009071template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9072 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9073
9074private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9075 template (present) BSSLAP_PDU expect_bsslap)
9076{
9077 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9078 if (not match(bsslap, expect_bsslap)) {
9079 log("EXPECTING BSSLAP: ", expect_bsslap);
9080 log("GOT BSSLAP: ", bsslap);
9081 setverdict(fail, "BSSLAP is not as expected");
9082 mtc.stop;
9083 }
9084 setverdict(pass);
9085}
9086
9087/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9088const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9089
9090private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9091 var PDU_BSSAP_LE rx_bsslap;
9092 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9093 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9094}
9095
9096/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9097 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9098private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9099 f_sleep(1.0);
9100
9101 f_establish_fully(omit, omit);
9102 f_bssap_le_register_imsi(g_pars.imsi, omit);
9103
9104 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9105 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9106
9107 var PDU_BSSAP_LE plr;
9108 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9109
9110 if (not do_ta_request) {
9111 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9112 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9113 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9114 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9115 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9116 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9117 mtc.stop;
9118 }
9119 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9120 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9121 if (not match(bsslap, expect_ta_layer3)) {
9122 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9123 log("GOT BSSLAP: ", bsslap);
9124 setverdict(fail, "BSSLAP is not as expected");
9125 mtc.stop;
9126 }
9127 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9128 * has no need to request the TA from the BSC and directly responds. */
9129 } else {
9130 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9131 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9132 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9133 }
9134
9135 /* SMLC got the TA from the BSC, now responds with geo information data. */
9136 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9137 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9138 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9139
9140 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9141 f_mo_l3_transceive();
9142
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009143 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009144
9145 f_sleep(2.0);
9146 setverdict(pass);
9147}
9148
9149/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9150 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9151private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9152 f_lcs_loc_req_for_active_ms(false);
9153}
9154testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9155 var MSC_ConnHdlr vc_conn;
9156 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9157
9158 f_init(1, true);
9159 f_sleep(1.0);
9160 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9161 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009162 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009163}
9164
9165/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9166 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9167private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9168 f_lcs_loc_req_for_active_ms(true);
9169}
9170testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9171 var MSC_ConnHdlr vc_conn;
9172 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9173
9174 f_init(1, true);
9175 f_sleep(1.0);
9176 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9177 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009178 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009179}
9180
9181/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9182 * conn without an active lchan. */
9183private function f_clear_A_conn() runs on MSC_ConnHdlr
9184{
9185 var BssmapCause cause := 0;
9186 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9187 BSSAP.receive(tr_BSSMAP_ClearComplete);
9188 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9189
9190 timer no_more_bssap := 5.0;
9191 no_more_bssap.start;
9192 alt {
9193 [] no_more_bssap.timeout { break; }
9194 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9195 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9196 mtc.stop;
9197 }
9198 }
9199 setverdict(pass);
9200}
9201
9202/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9203 * for LCS, for cases where there is only an A conn without an active lchan. */
9204private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9205{
9206 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9207
9208 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9209 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9210 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9211 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9212 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9213 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9214
9215 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9216 f_clear_A_conn();
9217 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9218 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9219}
9220
9221/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9222 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9223 */
9224private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9225 f_sleep(1.0);
9226
9227 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9228 f_bssap_le_register_imsi(g_pars.imsi, omit);
9229
9230 /* Register to receive the Paging Command */
9231 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9232 g_chan_nr := new_chan_nr;
9233 f_rslem_register(0, g_chan_nr);
9234
9235 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9236 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9237 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9238 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9239
9240 var PDU_BSSAP_LE plr;
9241 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9242
9243 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9244 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9245
9246 /* OsmoBSC needs to Page */
9247 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9248 f_logp(BSCVTY, "got Paging Command");
9249
9250 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9251 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009252 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);
9253 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009254
9255 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9256
9257 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9258
9259 /* SMLC got the TA from the BSC, now responds with geo information data. */
9260 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9261 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9262
9263 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9264
9265 /* The lchan is gone, the A-interface conn was created for the LCS only.
9266 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9267 f_verify_active_A_conn_and_clear();
9268
9269 f_sleep(2.0);
9270 setverdict(pass);
9271}
9272testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9273 var MSC_ConnHdlr vc_conn;
9274 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9275
9276 f_init(1, true);
9277 f_sleep(1.0);
9278
9279 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9280 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9281
9282 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9283 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009284 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009285}
9286
9287/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9288 */
9289private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9290 f_sleep(1.0);
9291
9292 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9293 f_bssap_le_register_imsi(g_pars.imsi, omit);
9294
9295 /* provoke an abort by omitting both IMSI and IMEI */
9296 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9297 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9298 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9299 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9300
9301 /* BSC tells MSC about failure */
9302 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9303 locationEstimate := omit, positioningData := omit,
9304 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9305
9306 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9307 f_verify_active_A_conn_and_clear();
9308
9309 f_sleep(2.0);
9310 setverdict(pass);
9311}
9312testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9313 var MSC_ConnHdlr vc_conn;
9314 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9315
9316 f_init(1, true);
9317 f_sleep(1.0);
9318
9319 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9320 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9321
9322 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9323 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009324 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009325}
9326
9327/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9328 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9329private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9330 f_sleep(1.0);
9331
9332 f_establish_fully(omit, omit);
9333 f_bssap_le_register_imsi(g_pars.imsi, omit);
9334
9335 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9336 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9337
9338 var PDU_BSSAP_LE plr;
9339 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9340
9341 if (do_ta) {
9342 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9343 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9344 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9345 }
9346
9347 /* SMLC fails to respond, BSC runs into timeout */
9348 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9349 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9350
9351 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9352 locationEstimate := omit, positioningData := omit,
9353 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9354
9355 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9356 f_verify_active_A_conn_and_clear();
9357
9358 f_sleep(2.0);
9359 setverdict(pass);
9360}
9361
9362/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9363 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9364private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9365 f_lcs_loc_req_for_active_ms_le_timeout(false);
9366}
9367
9368testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9369 var MSC_ConnHdlr vc_conn;
9370 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9371
9372 f_init(1, true);
9373 f_sleep(1.0);
9374 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9375 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009376 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009377}
9378
9379/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9380 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9381private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9382 f_lcs_loc_req_for_active_ms_le_timeout(true);
9383}
9384
9385testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9386 var MSC_ConnHdlr vc_conn;
9387 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9388
9389 f_init(1, true);
9390 f_sleep(1.0);
9391 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9392 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009393 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009394}
9395
9396/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9397private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9398 f_sleep(1.0);
9399
9400 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9401 f_bssap_le_register_imsi(g_pars.imsi, omit);
9402
9403 /* Register to receive the Paging Command */
9404 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9405 g_chan_nr := new_chan_nr;
9406 f_rslem_register(0, g_chan_nr);
9407
9408 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9409 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9410 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9411 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9412
9413 var PDU_BSSAP_LE plr;
9414 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9415
9416 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9417 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9418
9419 /* OsmoBSC needs to Page */
9420 var PDU_BSSAP_LE rx_bsslap;
9421 alt {
9422 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9423 f_logp(BSCVTY, "got Paging Command");
9424 repeat;
9425 }
9426 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9427 /* MS does not respond to Paging, TA Req runs into timeout. */
9428 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9429 }
9430 }
9431
9432 /* SMLC responds with failure */
9433 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9434 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9435
9436 /* BSC tells MSC about failure */
9437 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9438 locationEstimate := omit, positioningData := omit,
9439 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9440
9441 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9442 f_verify_active_A_conn_and_clear();
9443
9444 f_sleep(2.0);
9445 setverdict(pass);
9446}
9447testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9448 var MSC_ConnHdlr vc_conn;
9449 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9450
9451 f_init(1, true);
9452 f_sleep(1.0);
9453
9454 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9455 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9456
9457 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9458 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009459 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009460}
9461
9462/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9463 * over. */
9464private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9465 f_sleep(1.0);
9466
9467 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9468 f_bssap_le_register_imsi(g_pars.imsi, omit);
9469
9470 /* Register to receive the Paging Command */
9471 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9472 g_chan_nr := new_chan_nr;
9473 f_rslem_register(0, g_chan_nr);
9474
9475 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9476 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9477 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9478 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9479
9480 var PDU_BSSAP_LE plr;
9481 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9482
9483 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9484 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009485 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 +02009486 do_clear := false, expect_bssmap_l3 := true);
9487
9488 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9489 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9490
9491 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9492 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9493
9494 /* SMLC got the TA from the BSC, now responds with geo information data. */
9495 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9496 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9497 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9498
9499 /* The lchan should still exist, it was from a CM Service Request. */
9500 f_mo_l3_transceive();
9501
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009502 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009503
9504 f_sleep(2.0);
9505 setverdict(pass);
9506}
9507testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9508 var MSC_ConnHdlr vc_conn;
9509 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9510
9511 f_init(1, true);
9512 f_sleep(1.0);
9513
9514 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9515 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9516
9517 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9518 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009519 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009520}
9521
9522/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9523 * the new lchan after handover. */
9524private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9525 f_sleep(1.0);
9526
9527 f_establish_fully(omit, omit);
9528 f_bssap_le_register_imsi(g_pars.imsi, omit);
9529
9530 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9531 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9532
9533 var PDU_BSSAP_LE plr;
9534 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9535
9536 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9537 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9538
9539 var HandoverState hs := {
9540 rr_ho_cmpl_seen := false,
9541 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02009542 old_chan_nr := -,
9543 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009544 };
9545 /* issue hand-over command on VTY */
9546 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9547 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9548 f_rslem_suspend(RSL1_PROC);
9549
9550 /* From the MGW perspective, a handover is is characterized by
9551 * performing one MDCX operation with the MGW. So we expect to see
9552 * one more MDCX during handover. */
9553 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9554
9555 alt {
9556 [] as_handover(hs);
9557 }
9558
9559 var PDU_BSSAP_LE rx_bsslap;
9560
9561 interleave {
9562 /* Expect the BSC to inform the MSC about the handover */
9563 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9564
9565 /* Expect the BSC to inform the SMLC about the handover */
9566 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9567 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9568 }
9569 }
9570
9571 /* SMLC now responds with geo information data. */
9572 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9573 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9574 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9575
9576 /* lchan still active */
9577 f_mo_l3_transceive(RSL1);
9578
9579 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009580 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009581
9582 f_sleep(2.0);
9583 setverdict(pass);
9584}
9585testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9586 var MSC_ConnHdlr vc_conn;
9587 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9588
9589 f_init(2, true);
9590 f_sleep(1.0);
9591 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9592 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009593 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009594}
9595
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009596/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9597private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9598 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9599
9600 /* Also disable attach for the single connected MSC */
9601 f_vty_msc_allow_attach(BSCVTY, { false });
9602
9603 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) ));
9604 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9605
9606 /* No MSC is found, expecting a proper release on RSL */
9607 interleave {
9608 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9609 f_logp(BSCVTY, "Got RSL RR Release");
9610 }
9611 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9612 f_logp(BSCVTY, "Got RSL Deact SACCH");
9613 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009614 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009615 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9616 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009617 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009618 }
9619 }
9620 setverdict(pass);
9621}
9622testcase TC_no_msc() runs on test_CT {
9623
9624 f_init(1, true);
9625 f_sleep(1.0);
9626 var MSC_ConnHdlr vc_conn;
9627 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9628
9629 f_ctrs_bsc_init(counternames_bsc_mscpool);
9630
9631 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9632 vc_conn.done;
9633
9634 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9635 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009636 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009637}
9638
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009639/* Dyn PDCH todo:
9640 * activate OSMO as TCH/F
9641 * activate OSMO as TCH/H
9642 * does the BSC-located PCU socket get the updated INFO?
9643 * what if no PCU is connected at the time?
9644 * is the info correct on delayed PCU (re)connect?
9645 */
Harald Welte94e0c342018-04-07 11:33:23 +02009646
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009647private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9648 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9649 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9650
9651 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9652 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9653 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9654 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9655 g_pars.ass_codec_list.codecElements[0];
9656 if (isvalue(g_pars.expect_mr_s0_s7)) {
9657 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9658 g_pars.expect_mr_s0_s7;
9659 }
9660 }
9661 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9662 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9663 log("expecting ASS COMPL like this: ", exp_compl);
9664
9665 f_establish_fully(ass_cmd, exp_compl);
9666
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009667 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 +00009668
9669 var RSL_Message rsl;
9670
9671 timer T := 5.0;
9672 T.start;
9673 alt {
9674 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9675 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9676 log("Rx L3 from net: ", l3);
9677 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9678 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9679 mtc.stop;
9680 }
9681 }
9682 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9683 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9684 mtc.stop;
9685 }
9686 [] T.timeout {
9687 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9688 setverdict(pass);
9689 }
9690 }
9691 T.stop;
9692}
9693
9694/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9695 * osmo-bsc. */
9696testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9697 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9698 var MSC_ConnHdlr vc_conn;
9699
9700 f_init(1, true);
9701 f_sleep(1.0);
9702
9703 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9704 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9705 vc_conn.done;
9706 f_shutdown_helper();
9707}
9708
9709/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9710 */
9711testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9712 f_init_vty();
9713
9714 f_init(1, false);
9715 f_sleep(1.0);
9716
9717 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9718
9719 var ASP_RSL_Unitdata rx_rsl_ud;
9720 timer T := 5.0;
9721
9722 T.start;
9723 alt {
9724 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9725 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9726 T.stop;
9727 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9728 mtc.stop;
9729 }
9730 repeat;
9731 }
9732 [] T.timeout {
9733 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9734 setverdict(pass);
9735 }
9736 }
9737}
9738
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009739private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9740 /* First fully set up a speech lchan */
9741 f_TC_assignment_codec(id);
9742
9743 /* Trigger re-assignment to another lchan */
9744 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9745
9746 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9747 * one MDCX on MGCP. */
9748 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9749
9750 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9751 * as the old lchan used. */
9752 g_media.bts.ipa_crcx_seen := false;
9753 g_media.bts.ipa_mdcx_seen := false;
9754
9755 /* Send different BTS side RTP port number for the new lchan */
9756 g_media.bts.bts.port_nr := 4223;
9757
9758 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9759
9760 /* Trigger re-assignment. */
9761 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9762
9763 timer T := 5.0;
9764 T.start;
9765 alt {
9766 [] as_assignment(assignment_st);
9767 [] as_Media();
9768 [] T.timeout {
9769 break;
9770 }
9771 }
9772
9773 if (not assignment_st.assignment_done) {
9774 setverdict(fail, "Assignment did not complete");
9775 mtc.stop;
9776 }
9777
9778 f_check_mgcp_expectations()
9779 setverdict(pass);
9780
9781 f_sleep(2.0);
9782 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9783
9784 /* Instruct BSC to clear channel */
9785 var BssmapCause cause := 0;
9786 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9787 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009788 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9789 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009790 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009791 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009792 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009793 }
9794 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9795 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9796 }
9797 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +02009798 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009799
9800 f_sleep(0.5);
9801}
9802
9803testcase TC_reassignment_fr() runs on test_CT {
9804 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9805 var MSC_ConnHdlr vc_conn;
9806
9807 f_init(1, true);
9808 f_sleep(1.0);
9809
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01009810 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009811
9812 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9813 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9814 vc_conn.done;
9815
9816 /* from f_establish_fully() */
9817 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9818 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9819 /* from re-assignment */
9820 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9821 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9822 f_ctrs_bsc_and_bts_verify();
9823 f_shutdown_helper();
9824}
9825
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009826const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9827const charstring REEST_CLEAR := "REEST_CLEAR";
9828const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9829
9830/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9831 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9832 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9833 * the MSC as the CM Re-Establishment is handled.
9834 *
9835 * MS bts0 bts1 bsc msc test-component
9836 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9837 * | | _1 wait a bit, to settle down
9838 * |<-x x--| | _1 "lose connection"
9839 * | | REEST_LOST_CONNECTION
9840 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9841 * | | REEST_CLEAR
9842 * | |<-0---| _1 Clear Command on first A-conn
9843 * | |--0-->| _1 Clear Complete
9844 * | |<----------------->| | _1 Release first channel
9845 * | | REEST_CLEAR_DONE
9846 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9847 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9848 *
9849 */
9850private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9851 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9852 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9853
9854 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9855 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9856
9857 f_establish_fully(ass_cmd, exp_compl);
9858
9859 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9860 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9861 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9862 f_sleep(2.0);
9863 COORD.send(REEST_LOST_CONNECTION);
9864
9865 alt {
9866 [] COORD.receive(REEST_CLEAR);
9867 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9868 setverdict(fail, "Unexpected channel release");
9869 mtc.stop;
9870 }
9871 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9872 setverdict(fail, "Unexpected channel release");
9873 mtc.stop;
9874 }
9875 }
9876 f_perform_clear()
9877 f_expect_dlcx_conns();
Neels Hofmeyr969abd02021-09-23 22:24:08 +02009878 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009879 COORD.send(REEST_CLEAR_DONE);
9880}
9881
9882private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9883 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9884
9885 /* The MS lost the connection on the first channel, now establishes another one */
9886 COORD.receive(REEST_LOST_CONNECTION);
9887
9888 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9889 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9890 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9891
9892 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009893 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 +02009894 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9895
9896 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9897 COORD.send(REEST_CLEAR);
9898 COORD.receive(REEST_CLEAR_DONE);
9899
9900 f_sleep(2.0);
9901
9902 /* Answer the CM Re-Establishment with an Assignment Command. */
9903 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9904 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9905 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9906 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9907
9908 var AssignmentState st := valueof(ts_AssignmentStateInit);
9909 st.voice_call := true;
9910 st.is_assignment := true;
9911
9912 var ExpectCriteria mgcpcrit := {
9913 connid := omit,
9914 endpoint := omit,
9915 transid := omit
9916 };
9917 f_create_mgcp_expect(mgcpcrit);
9918
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009919 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009920
9921 BSSAP.send(ass_cmd);
9922
9923 var PDU_BSSAP bssap;
9924
9925 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009926 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9927 [] as_Media_ipacc(RSL1, RSL2);
9928 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009929 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9930 break;
9931 }
9932 }
9933
9934 f_sleep(3.0);
9935
9936 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009937 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009938 f_expect_dlcx_conns();
9939}
9940
9941testcase TC_cm_reestablishment() runs on test_CT {
9942 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9943 var MSC_ConnHdlr vc_conn1;
9944
9945 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9946 var MSC_ConnHdlr vc_conn2;
9947 pars2.imsi := pars1.imsi;
9948 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +02009949 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009950
9951 f_init(2, true, guard_timeout := 40.0);
9952 f_sleep(1.0);
9953
9954 vc_conn1 := f_start_handler_create(pars1);
9955 vc_conn2 := f_start_handler_create(pars2);
9956 connect(vc_conn1:COORD, vc_conn2:COORD);
9957 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9958 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9959 vc_conn1.done;
9960 vc_conn2.done;
9961
9962 f_shutdown_helper();
9963}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009964
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009965function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9966 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9967runs on test_CT return template (omit) RSL_Message {
9968 var ASP_RSL_Unitdata rx_rsl_ud;
9969 timer T := t_secs;
9970
9971 T.start;
9972 alt {
9973 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9974 T.stop;
9975 }
9976 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9977 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9978 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9979 T.stop;
9980 return omit;
9981 }
9982 [] T.timeout {
9983 return omit;
9984 }
9985 }
9986 return rx_rsl_ud.rsl;
9987}
9988
9989private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9990 f_vty_enter_cfg_bts(pt, bts_nr);
9991 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9992 f_vty_transceive(pt, "exit");
9993 f_vty_transceive(pt, "exit");
9994 f_vty_transceive(pt, "exit");
9995}
9996
9997private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009998 template RslChannelNr chan_nr := ?,
9999 template (present) uint12_t arfcn := ?,
10000 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010001{
10002 var RSL_IE_Body full_imm_ass_info;
10003 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10004 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10005 mtc.stop;
10006 }
10007
10008 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10009 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10010 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010011 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010012 page_mode := ?);
10013 if (not match(rr_imm_ass, expect_imm_ass)) {
10014 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10015 setverdict(fail, "Failed to match Immediate Assignment");
10016 mtc.stop;
10017 }
10018}
10019
10020testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10021 var RSL_Message chan_act;
10022 var RSL_Message imm_ass;
10023
10024 f_init(1, false);
10025 f_sleep(1.0);
10026
10027 /* (should be the default anyway, just to make things clear) */
10028 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10029
10030 /* RA containing reason=LU */
10031 var GsmFrameNumber fn := 2342;
10032 var uint8_t ra := 2;
10033 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10034
10035 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10036
10037 /* First send the Chan Act ACK */
10038 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010039 var RSL_IE_Body chan_ident_ie;
10040 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10041 setverdict(fail, "RSL Channel Identification IE is absent");
10042 mtc.stop;
10043 }
10044
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010045 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
10046
10047 /* Then expect the Immediate Assignment, after we ACKed the chan act */
10048 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10049
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010050 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10051 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010052
10053 /* Check that the lchan is working */
10054 var octetstring l3 := '00010203040506'O;
10055 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10056
10057 var BSSAP_N_CONNECT_ind rx_c_ind;
10058 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10059 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10060
10061 f_sleep(1.0);
10062 f_shutdown_helper();
10063}
10064
10065testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10066 var RSL_Message chan_act;
10067 var RSL_Message imm_ass;
10068
10069 f_init(1, false);
10070 f_sleep(1.0);
10071
10072 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10073
10074 /* RA containing reason=LU */
10075 var GsmFrameNumber fn := 2342;
10076 var uint8_t ra := 2;
10077 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10078
10079 /* (set bts 0 cfg back to default) */
10080 f_vty_set_imm_ass(BSCVTY);
10081
10082 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10083 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010084 var RSL_IE_Body chan_ident_ie;
10085 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10086 setverdict(fail, "RSL Channel Identification IE is absent");
10087 mtc.stop;
10088 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010089
10090 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10091 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010092 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10093 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010094
10095 /* Only now send the Chan Act ACK */
10096 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10097
10098 /* Check that the lchan is working */
10099 var octetstring l3 := '00010203040506'O;
10100 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10101
10102 var BSSAP_N_CONNECT_ind rx_c_ind;
10103 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10104 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10105
10106 f_sleep(1.0);
10107 f_shutdown_helper();
10108}
10109
Neels Hofmeyr23158742021-09-07 19:08:07 +020010110testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10111 var RSL_Message chan_act;
10112 var RSL_Message imm_ass;
10113
10114 f_init(1, false);
10115 f_sleep(1.0);
10116
10117 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10118
10119 /* RA containing reason=LU */
10120 var GsmFrameNumber fn := 2342;
10121 var uint8_t ra := 2;
10122 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10123
10124 /* (set bts 0 cfg back to default) */
10125 f_vty_set_imm_ass(BSCVTY);
10126
10127 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10128 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
10129 var RSL_IE_Body chan_ident_ie;
10130 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10131 setverdict(fail, "RSL Channel Identification IE is absent");
10132 mtc.stop;
10133 }
10134
10135 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10136 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10137 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10138 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10139
10140 /* Only now send the Chan Act ACK */
10141 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10142
10143 /* Check that the lchan is working */
10144 var octetstring l3 := '00010203040506'O;
10145 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10146
10147 var BSSAP_N_CONNECT_ind rx_c_ind;
10148 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10149 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10150
10151 f_sleep(1.0);
10152 f_shutdown_helper();
10153}
10154
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010155testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10156 /* change Timeslot 6 before f_init() starts RSL */
10157 f_init_vty();
10158 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10159 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10160
10161 f_init(1, false);
10162 f_sleep(1.0);
10163
10164 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10165 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10166 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10167 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10168
10169 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10170 f_ts_set_chcomb(0, 0, 6, "PDCH");
10171
10172 /* block all static timeslots so that the dyn TS will be used */
10173 f_disable_all_tch_f();
10174 f_disable_all_tch_h();
10175 f_disable_all_sdcch();
10176
10177 var RSL_Message chan_act;
10178 var RSL_Message imm_ass;
10179
10180 f_init(1, false);
10181 f_sleep(1.0);
10182
10183 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10184
10185 /* RA containing reason=LU */
10186 var GsmFrameNumber fn := 2342;
10187 var uint8_t ra := 2;
10188 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10189
10190 /* (set bts 0 cfg back to default) */
10191 f_vty_set_imm_ass(BSCVTY);
10192
10193 /* Expect the dyn TS to deactivate PDCH first */
10194 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10195 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10196
10197 /* Now activation as SDCCH8 */
10198 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10199
10200 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010201 var RSL_IE_Body chan_ident_ie;
10202 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10203 setverdict(fail, "RSL Channel Identification IE is absent");
10204 mtc.stop;
10205 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010206
10207 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10208 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010209 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10210 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010211
10212 /* Only now send the Chan Act ACK */
10213 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10214
10215 /* Check that the lchan is working */
10216 var octetstring l3 := '00010203040506'O;
10217 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10218
10219 var BSSAP_N_CONNECT_ind rx_c_ind;
10220 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10221 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10222
10223 f_sleep(1.0);
10224 f_shutdown_helper();
10225}
10226
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010227testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10228 /* change Timeslot 6 before f_init() starts RSL */
10229 f_init_vty();
10230 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10231 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10232
10233 f_init(1, false);
10234 f_sleep(1.0);
10235
10236 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10237 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10238 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10239 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10240
10241 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10242 f_ts_set_chcomb(0, 0, 6, "PDCH");
10243
10244 /* block all static timeslots so that the dyn TS will be used */
10245 f_disable_all_tch_f();
10246 f_disable_all_tch_h();
10247 f_disable_all_sdcch();
10248
10249 var RSL_Message chan_act;
10250 var RSL_Message imm_ass;
10251
10252 f_init(1, false);
10253 f_sleep(1.0);
10254
10255 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10256
10257 /* RA containing reason=LU */
10258 var GsmFrameNumber fn := 2342;
10259 var uint8_t ra := 2;
10260 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10261
10262 /* (set bts 0 cfg back to default) */
10263 f_vty_set_imm_ass(BSCVTY);
10264
10265 /* Expect the dyn TS to deactivate PDCH first */
10266 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10267
10268 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10269 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10270
10271 /* continue the Osmo style PDCH Deact (usual chan rel) */
10272 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10273
10274 /* Now activation as SDCCH8 */
10275 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10276
10277 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010278 var RSL_IE_Body chan_ident_ie;
10279 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10280 setverdict(fail, "RSL Channel Identification IE is absent");
10281 mtc.stop;
10282 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010283 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10284
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010285 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10286 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010287
10288 /* Check that the lchan is working */
10289 var octetstring l3 := '00010203040506'O;
10290 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10291
10292 var BSSAP_N_CONNECT_ind rx_c_ind;
10293 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10294 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10295
10296 f_sleep(1.0);
10297 f_shutdown_helper();
10298}
10299
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010300/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10301testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10302 var MSC_ConnHdlr vc_conn;
10303
10304 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10305 f_sleep(1.0);
10306
10307 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10308 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10309 "0,0,operational,unlocked,on,rsl-up;" &
10310 "1,0,operational,unlocked,on,rsl-up;" &
10311 "2,0,operational,unlocked,on,rsl-down;" &
10312 "3,0,inoperational,locked,on,rsl-down;");
10313
10314 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10315 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10316 /* give it a moment to settle the FSM status */
10317 f_sleep(1.0);
10318
10319 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10320 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10321 * of "off"? But that's for a future patch if at all. */
10322 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10323 "0,0,operational,unlocked,on,rsl-up;" &
10324 "1,0,operational,locked,on,rsl-up;" &
10325 "2,0,operational,unlocked,on,rsl-down;" &
10326 "3,0,inoperational,locked,on,rsl-down;");
10327
10328 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10329 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10330 f_sleep(1.0);
10331 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10332 "0,0,operational,unlocked,on,rsl-up;" &
10333 "1,0,operational,locked,on,rsl-up;" &
10334 "2,0,operational,unlocked,on,rsl-down;" &
10335 "3,0,inoperational,locked,on,rsl-down;");
10336
10337 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10338 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10339 f_sleep(1.0);
10340 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10341 "0,0,operational,unlocked,on,rsl-up;" &
10342 "1,0,operational,unlocked,on,rsl-up;" &
10343 "2,0,operational,unlocked,on,rsl-down;" &
10344 "3,0,inoperational,locked,on,rsl-down;");
10345
10346 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10347 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10348 f_sleep(1.0);
10349 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10350 "0,0,operational,unlocked,on,rsl-up;" &
10351 "1,0,operational,unlocked,on,rsl-up;" &
10352 "2,0,operational,unlocked,on,rsl-down;" &
10353 "3,0,inoperational,locked,on,rsl-down;");
10354
10355 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10356 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10357 f_sleep(1.0);
10358 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10359 "0,0,operational,unlocked,on,rsl-up;" &
10360 "1,0,operational,unlocked,on,rsl-up;" &
10361 "2,0,operational,unlocked,on,rsl-down;" &
10362 "3,0,inoperational,locked,on,rsl-down;");
10363
10364 f_shutdown_helper();
10365}
10366
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010367const CounterNameVals counternames_cm_serv_rej := {
10368 { "cm_serv_rej", 0 },
10369 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
10370 { "cm_serv_rej:illegal_ms", 0 },
10371 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
10372 { "cm_serv_rej:imei_not_accepted", 0 },
10373 { "cm_serv_rej:illegal_me", 0 },
10374 { "cm_serv_rej:plmn_not_allowed", 0 },
10375 { "cm_serv_rej:loc_not_allowed", 0 },
10376 { "cm_serv_rej:roaming_not_allowed", 0 },
10377 { "cm_serv_rej:network_failure", 0 },
10378 { "cm_serv_rej:synch_failure", 0 },
10379 { "cm_serv_rej:congestion", 0 },
10380 { "cm_serv_rej:srv_opt_not_supported", 0 },
10381 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
10382 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
10383 { "cm_serv_rej:call_can_not_be_identified", 0 },
10384 { "cm_serv_rej:incorrect_message", 0 },
10385 { "cm_serv_rej:invalid_mandantory_inf", 0 },
10386 { "cm_serv_rej:msg_type_not_implemented", 0 },
10387 { "cm_serv_rej:msg_type_not_compatible", 0 },
10388 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
10389 { "cm_serv_rej:condtional_ie_error", 0 },
10390 { "cm_serv_rej:msg_not_compatible", 0 },
10391 { "cm_serv_rej:protocol_error", 0 },
10392 { "cm_serv_rej:retry_in_new_cell", 0 }
10393};
10394
10395private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
10396{
10397 f_create_chan_and_exp();
10398 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010399 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010400}
10401testcase TC_cm_serv_rej() runs on test_CT {
10402 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10403 var MSC_ConnHdlr vc_conn;
10404
10405 f_init(1, true);
10406 f_sleep(1.0);
10407
10408 f_ctrs_bts_init(1, counternames_cm_serv_rej);
10409
10410 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
10411 vc_conn.done;
10412
10413 f_ctrs_bts_add(0, "cm_serv_rej", 1);
10414 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
10415 f_ctrs_bts_verify();
10416
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010417 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010418 f_shutdown_helper();
10419}
10420
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010421/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10422 * Activ Ack (SYS#5627). */
10423private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10424 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030010425
10426 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10427 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010428
10429 var BSSMAP_FIELD_CodecType codecType;
10430 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
10431
10432 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
10433
10434 /* First establish a signalling lchan */
10435 f_create_chan_and_exp();
10436 f_rslem_dchan_queue_enable();
10437
10438 /* we should now have a COMPL_L3 at the MSC */
10439 var template PDU_BSSAP exp_l3_compl;
10440 exp_l3_compl := tr_BSSMAP_ComplL3()
10441 if (g_pars.aoip == false) {
10442 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
10443 } else {
10444 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
10445 }
10446 timer T := 10.0;
10447 T.start;
10448 alt {
10449 [] BSSAP.receive(exp_l3_compl);
10450 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
10451 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
10452 }
10453 [] T.timeout {
10454 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
10455 }
10456 }
10457
10458 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
10459 activate(as_Media_mgw());
10460
10461 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
10462 f_rslem_register(0, chan_nr);
10463
10464 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
10465 BSSAP.send(ass_cmd);
10466
10467
10468 /* Wait for the Channel Activ for the TCH channel */
10469 var ASP_RSL_Unitdata rx_rsl_ud;
10470 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
10471
10472 /* make the original SDCCH disappear */
10473 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10474
10475 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
10476 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
10477
10478 interleave {
10479 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
10480 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
10481 }
10482
10483 BSSAP.send(ts_BSSMAP_ClearCommand(0));
10484 BSSAP.receive(tr_BSSMAP_ClearComplete);
10485 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10486
10487 var MgcpCommand mgcp;
10488 MGCP.receive(tr_DLCX()) -> value mgcp {
10489 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
10490 };
10491
10492 f_sleep(0.5);
10493}
10494testcase TC_lost_sdcch_during_assignment() runs on test_CT {
10495 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10496 var MSC_ConnHdlr vc_conn;
10497
10498 f_init(1, true);
10499 f_sleep(1.0);
10500
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010501 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
10502 vc_conn.done;
10503
10504 f_shutdown_helper();
10505}
10506
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010507const CounterNameVals counternames_bsc_bts_all_available_allocated := {
10508 { "all_allocated:sdcch", 0 },
10509 { "all_allocated:static_sdcch", 0 },
10510 { "all_allocated:tch", 0 },
10511 { "all_allocated:static_tch", 0 }
10512}
10513
10514private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
10515{
10516 /* Make sure counters settle first */
10517 f_sleep(1.0);
10518
10519 /* Take a baseline of counters */
10520 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
10521
10522 /* Elapse some time so that we see changes in counters, hopefully where expected */
10523 f_sleep(2.0);
10524
10525 /* Get new counters */
10526 var charstring_list all_changed := {};
10527 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
10528 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
10529
10530 /* Compare with expectations */
10531 var charstring_list all_expect_changed := {};
10532 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
10533 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
10534 }
10535 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
10536}
10537
10538testcase TC_ratectr_all_available_allocated() runs on test_CT {
10539 var ASP_RSL_Unitdata rsl_ud;
10540 var integer i;
10541 var integer chreq_total, chreq_nochan;
10542
10543 f_init(1);
10544 f_sleep(1.0);
10545
10546 /* Exhaust all dedicated SDCCH lchans.
10547 /* GSM 44.018 Table 9.1.8.2:
10548 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10549 */
10550 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10551 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10552 }
10553
10554 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
10555 * level.
10556 * All SDCCH are now occupied. */
10557 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10558
10559 /* Also fill up all remaining (TCH) channels */
10560 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
10561 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10562 }
10563
10564 /* All TCH are now also occupied */
10565 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10566 "all_allocated:tch", "all_allocated:static_tch"});
10567
10568 f_shutdown_helper();
10569}
10570
10571testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
10572 var ASP_RSL_Unitdata rsl_ud;
10573 var integer i;
10574 var integer chreq_total, chreq_nochan;
10575
10576 f_init_vty();
10577 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
10578 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10579 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
10580
10581 f_init(1, guard_timeout := 60.0);
10582 f_sleep(1.0);
10583
10584 /* The dyn TS wants to activate PDCH mode, ACK that. */
10585 var RslChannelNr chan_nr;
10586 chan_nr := valueof(t_RslChanNr_PDCH(2));
10587 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10588 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10589
10590 /* Exhaust all dedicated SDCCH lchans.
10591 /* GSM 44.018 Table 9.1.8.2:
10592 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10593 */
10594 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10595 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10596 }
10597
10598 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
10599 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
10600 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
10601
10602 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
10603 * Will release them later, so remember all the DchanTuples. */
10604 var DchanTuples dyn_sddch := {};
10605 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10606
10607 /* Also occupy the seven other SDCCH of the dyn TS */
10608 for (i := 0; i < 7; i := i+1) {
10609 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10610 }
10611
10612 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
10613 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10614
10615 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
10616 for (i := 0; i < 5; i := i+1) {
10617 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10618 }
10619
10620 /* All TCH lchans are now also occupied, both static and dynamic */
10621 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10622 "all_allocated:tch", "all_allocated:static_tch"});
10623
10624 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
10625 * incrementing. */
10626 var BssmapCause cause := 0;
10627 var DchanTuple dt := dyn_sddch[0];
10628 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10629 f_exp_chan_rel_and_clear(dt, 0);
10630
10631 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
10632 * count as occupied, so those still both increment. */
10633 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
10634 "all_allocated:tch", "all_allocated:static_tch"});
10635
10636 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
10637 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
10638 dt := dyn_sddch[i];
10639 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10640 f_exp_chan_rel_and_clear(dt, 0);
10641 }
10642
10643 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
10644 chan_nr := valueof(t_RslChanNr_PDCH(2));
10645 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10646 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10647
10648 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
10649 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
10650
10651 /* clean up config */
10652 f_ts_reset_chcomb(0);
10653
10654 f_shutdown_helper();
10655}
10656
Harald Welte28d943e2017-11-25 15:00:50 +010010657control {
Harald Welte898113b2018-01-31 18:32:21 +010010658 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010659 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010660 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020010661 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
10662 * these in the AoIP test suite. */
10663 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10664 execute( TC_stat_num_msc_connected_1() );
10665 execute( TC_stat_num_msc_connected_2() );
10666 execute( TC_stat_num_msc_connected_3() );
10667 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020010668 execute( TC_stat_num_bts_connected_1() );
10669 execute( TC_stat_num_bts_connected_2() );
10670 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010671 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010672 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010673 execute( TC_ctrl_location() );
10674 }
Harald Welte898113b2018-01-31 18:32:21 +010010675
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010676 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010677 execute( TC_si2quater_2_earfcns() );
10678 execute( TC_si2quater_3_earfcns() );
10679 execute( TC_si2quater_4_earfcns() );
10680 execute( TC_si2quater_5_earfcns() );
10681 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010682 execute( TC_si2quater_12_earfcns() );
10683 execute( TC_si2quater_23_earfcns() );
10684 execute( TC_si2quater_32_earfcns() );
10685 execute( TC_si2quater_33_earfcns() );
10686 execute( TC_si2quater_42_earfcns() );
10687 execute( TC_si2quater_48_earfcns() );
10688 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010689 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010690 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010691
Harald Welte898113b2018-01-31 18:32:21 +010010692 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010693 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010694 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010695 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010696 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010697 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010698 execute( TC_chan_act_ack_est_ind_noreply() );
10699 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010700 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010701 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010702 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010703 execute( TC_chan_rel_rll_rel_ind() );
10704 execute( TC_chan_rel_conn_fail() );
10705 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010706 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10707 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010708 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010709 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010710 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010711 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010712 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010713 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010714
Harald Weltecfe2c962017-12-15 12:09:32 +010010715 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010716
10717 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010718 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010719 execute( TC_assignment_csd() );
10720 execute( TC_assignment_ctm() );
10721 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010722 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10723 execute( TC_assignment_aoip_tla_v6() );
10724 }
Harald Welte235ebf12017-12-15 14:18:16 +010010725 execute( TC_assignment_fr_a5_0() );
10726 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010727 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010728 execute( TC_assignment_fr_a5_1_codec_missing() );
10729 }
Harald Welte235ebf12017-12-15 14:18:16 +010010730 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010731 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010732 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010733 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010734 execute( TC_ciph_mode_a5_0() );
10735 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010736 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010737 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010738 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010739 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010740
Harald Welte60aa5762018-03-21 19:33:13 +010010741 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010742 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010743 execute( TC_assignment_codec_hr() );
10744 execute( TC_assignment_codec_efr() );
10745 execute( TC_assignment_codec_amr_f() );
10746 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010747
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010748 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010749 execute( TC_assignment_codec_amr_f_S1() );
10750 execute( TC_assignment_codec_amr_h_S1() );
10751 execute( TC_assignment_codec_amr_f_S124() );
10752 execute( TC_assignment_codec_amr_h_S124() );
10753 execute( TC_assignment_codec_amr_f_S0() );
10754 execute( TC_assignment_codec_amr_f_S02() );
10755 execute( TC_assignment_codec_amr_f_S024() );
10756 execute( TC_assignment_codec_amr_f_S0247() );
10757 execute( TC_assignment_codec_amr_h_S0() );
10758 execute( TC_assignment_codec_amr_h_S02() );
10759 execute( TC_assignment_codec_amr_h_S024() );
10760 execute( TC_assignment_codec_amr_h_S0247() );
10761 execute( TC_assignment_codec_amr_f_S01234567() );
10762 execute( TC_assignment_codec_amr_f_S0234567() );
10763 execute( TC_assignment_codec_amr_f_zero() );
10764 execute( TC_assignment_codec_amr_f_unsupp() );
10765 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010766 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10767 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010768 execute( TC_assignment_codec_amr_f_start_mode_4() );
10769 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010770 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010771 }
Harald Welte60aa5762018-03-21 19:33:13 +010010772
Philipp Maierac09bfc2019-01-08 13:41:39 +010010773 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10774 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10775 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10776 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10777 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10778 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10779 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10780 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10781 execute( TC_assignment_codec_req_hr_fr() );
10782 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010783 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10784 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10785 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010786
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010787 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010788
Harald Welte898113b2018-01-31 18:32:21 +010010789 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010790 execute( TC_rll_est_ind_inact_lchan() );
10791 execute( TC_rll_est_ind_inval_sapi1() );
10792 execute( TC_rll_est_ind_inval_sapi3() );
10793 execute( TC_rll_est_ind_inval_sacch() );
10794
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010795 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10796 execute( TC_tch_dlci_link_id_sapi() );
10797
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010798 /* SAPI N Reject triggered by RLL establishment failures */
10799 execute( TC_rll_rel_ind_sapi_n_reject() );
10800 execute( TC_rll_err_ind_sapi_n_reject() );
10801 execute( TC_rll_timeout_sapi_n_reject() );
10802
Harald Welte898113b2018-01-31 18:32:21 +010010803 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010804 execute( TC_paging_imsi_nochan() );
10805 execute( TC_paging_tmsi_nochan() );
10806 execute( TC_paging_tmsi_any() );
10807 execute( TC_paging_tmsi_sdcch() );
10808 execute( TC_paging_tmsi_tch_f() );
10809 execute( TC_paging_tmsi_tch_hf() );
10810 execute( TC_paging_imsi_nochan_cgi() );
10811 execute( TC_paging_imsi_nochan_lac_ci() );
10812 execute( TC_paging_imsi_nochan_ci() );
10813 execute( TC_paging_imsi_nochan_lai() );
10814 execute( TC_paging_imsi_nochan_lac() );
10815 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010816 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10817 execute( TC_paging_imsi_nochan_rnc() );
10818 execute( TC_paging_imsi_nochan_lac_rnc() );
10819 execute( TC_paging_imsi_nochan_lacs() );
10820 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010821 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010822 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010823 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010824 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010825 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010826
10827 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010828 execute( TC_rsl_unknown_unit_id() );
10829
10830 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010831
10832 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010833 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010834 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010835 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010836 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010837 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010838 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010839
Harald Welte261af4b2018-02-12 21:20:39 +010010840 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010841 execute( TC_ho_int_a5_0() );
10842 execute( TC_ho_int_a5_1() );
10843 execute( TC_ho_int_a5_3() );
10844 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010845 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010846
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010010847 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010848 execute( TC_ho_out_fail_no_msc_response() );
10849 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010850 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010851
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010852 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010853 execute( TC_ho_into_this_bsc_a5_0() );
10854 execute( TC_ho_into_this_bsc_a5_1() );
10855 execute( TC_ho_into_this_bsc_a5_3() );
10856 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010857 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10858 execute( TC_ho_into_this_bsc_tla_v6() );
10859 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010860 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010861 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010862 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10863 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010864 execute( TC_ho_in_fail_msc_clears() );
10865 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10866 execute( TC_ho_in_fail_no_detect() );
10867 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010868
Neels Hofmeyr91401012019-07-11 00:42:35 +020010869 execute( TC_ho_neighbor_config_1() );
10870 execute( TC_ho_neighbor_config_2() );
10871 execute( TC_ho_neighbor_config_3() );
10872 execute( TC_ho_neighbor_config_4() );
10873 execute( TC_ho_neighbor_config_5() );
10874 execute( TC_ho_neighbor_config_6() );
10875 execute( TC_ho_neighbor_config_7() );
10876
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010877 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010878 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010879 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010880
10881 execute( TC_dyn_pdch_ipa_act_deact() );
10882 execute( TC_dyn_pdch_ipa_act_nack() );
10883 execute( TC_dyn_pdch_osmo_act_deact() );
10884 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010010885 execute( TC_dyn_ts_sdcch8_act_deact() );
10886 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
10887 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
10888 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010889
Stefan Sperling0796a822018-10-05 13:01:39 +020010890 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010891 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010892
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010893 /* Power control related */
10894 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010895 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010896
10897 /* MSC pooling */
10898 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10899 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10900 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10901 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10902 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10903 execute( TC_mscpool_L3Compl_on_1_msc() );
10904 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10905 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10906 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10907 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10908 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10909 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10910 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10911 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10912 execute( TC_mscpool_paging_and_response_imsi() );
10913 execute( TC_mscpool_paging_and_response_tmsi() );
10914 execute( TC_mscpool_no_allow_attach_round_robin() );
10915 execute( TC_mscpool_no_allow_attach_valid_nri() );
10916 }
10917
Harald Welte99f3ca02018-06-14 13:40:29 +020010918 execute( TC_early_conn_fail() );
10919 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010920 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010921
Philipp Maier783681c2020-07-16 16:47:06 +020010922 /* Emergency call handling (deny / allow) */
10923 execute( TC_assignment_emerg_setup_allow() );
10924 execute( TC_assignment_emerg_setup_deny_msc() );
10925 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010926 execute( TC_emerg_premption() );
10927
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010928 /* Frequency hopping parameters handling */
10929 execute( TC_fh_params_chan_activ() );
10930 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010931 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010932 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010933 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010934
10935 if (mp_enable_lcs_tests) {
10936 execute( TC_lcs_loc_req_for_active_ms() );
10937 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10938 execute( TC_lcs_loc_req_for_idle_ms() );
10939 execute( TC_lcs_loc_req_no_subscriber() );
10940 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10941 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10942 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10943 execute( TC_cm_service_during_lcs_loc_req() );
10944 execute( TC_ho_during_lcs_loc_req() );
10945 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010946
10947 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010948
10949 execute( TC_refuse_chan_act_to_vamos() );
10950 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010951
10952 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010953
10954 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010955
10956 execute( TC_imm_ass_post_chan_ack() );
10957 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010958 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010959 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010960 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010961
10962 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010963
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010964 execute( TC_ratectr_all_available_allocated() );
10965 execute( TC_ratectr_all_available_allocated_dyn() );
10966
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010967 execute( TC_cm_serv_rej() );
10968
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010969 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010010970
10971 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
10972 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
10973 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010010974}
10975
10976}