blob: 965a4484d087276e10809917bb1a4c1391ce0d56 [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
Harald Welte5d1a2202017-12-13 19:51:29 +010078const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020079const 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 +020080const integer NUM_MSC := 3;
Harald Welteae026692017-12-09 01:03:01 +010081const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010082
Harald Welte799c97b2017-12-14 17:50:30 +010083/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020084const integer NUM_TCHH_PER_BTS := 2;
85const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020086const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010087
Harald Welte4003d112017-12-09 22:35:39 +010088
Harald Welte21b46bd2017-12-17 19:46:32 +010089/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +010090type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +010091 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +010092 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +010093}
94
Neels Hofmeyr22c3f792020-06-17 02:49:28 +020095/* Default list of counters for an 'msc' entity. */
96const CounterNameVals counternames_msc_mscpool := {
97 { "mscpool:subscr:new", 0 },
98 { "mscpool:subscr:known", 0 },
99 { "mscpool:subscr:reattach", 0 },
100 { "mscpool:subscr:attach_lost", 0 },
101 { "mscpool:subscr:paged", 0 }
102};
103
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000104/* List of global mscpool counters, not related to a specific 'msc' entity. */
105const CounterNameVals counternames_bsc_mscpool := {
106 { "mscpool:subscr:no_msc", 0 }
107};
108
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000109/* Default list of counters for 'bsc' and 'bts' entities. */
110const CounterNameVals counternames_bsc_bts_handover := {
111 { "assignment:attempted", 0 },
112 { "assignment:completed", 0 },
113 { "assignment:stopped", 0 },
114 { "assignment:no_channel", 0 },
115 { "assignment:timeout", 0 },
116 { "assignment:failed", 0 },
117 { "assignment:error", 0 },
118
119 { "handover:attempted", 0 },
120 { "handover:completed", 0 },
121 { "handover:stopped", 0 },
122 { "handover:no_channel", 0 },
123 { "handover:timeout", 0 },
124 { "handover:failed", 0 },
125 { "handover:error", 0 },
126
127 { "intra_cell_ho:attempted", 0 },
128 { "intra_cell_ho:completed", 0 },
129 { "intra_cell_ho:stopped", 0 },
130 { "intra_cell_ho:no_channel", 0 },
131 { "intra_cell_ho:timeout", 0 },
132 { "intra_cell_ho:failed", 0 },
133 { "intra_cell_ho:error", 0 },
134
135 { "intra_bsc_ho:attempted", 0 },
136 { "intra_bsc_ho:completed", 0 },
137 { "intra_bsc_ho:stopped", 0 },
138 { "intra_bsc_ho:no_channel", 0 },
139 { "intra_bsc_ho:timeout", 0 },
140 { "intra_bsc_ho:failed", 0 },
141 { "intra_bsc_ho:error", 0 },
142
143 { "interbsc_ho_out:attempted", 0 },
144 { "interbsc_ho_out:completed", 0 },
145 { "interbsc_ho_out:stopped", 0 },
146 { "interbsc_ho_out:timeout", 0 },
147 { "interbsc_ho_out:failed", 0 },
148 { "interbsc_ho_out:error", 0 },
149
150 { "interbsc_ho_in:attempted", 0 },
151 { "interbsc_ho_in:completed", 0 },
152 { "interbsc_ho_in:stopped", 0 },
153 { "interbsc_ho_in:no_channel", 0 },
154 { "interbsc_ho_in:timeout", 0 },
155 { "interbsc_ho_in:failed", 0 },
156 { "interbsc_ho_in:error", 0 }
157};
158
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200159/* Set of all System Information received during one RSL port's startup.
160 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
161 * broadcast that SI type. That will be reflected as 'omit' here.
162 */
163type record SystemInformationConfig {
164 SystemInformationType1 si1 optional,
165 SystemInformationType2 si2 optional,
166 SystemInformationType2bis si2bis optional,
167 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200168 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200169 SystemInformationType3 si3 optional,
170 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100171 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200172 SystemInformationType5 si5 optional,
173 SystemInformationType5bis si5bis optional,
174 SystemInformationType5ter si5ter optional,
175 SystemInformationType6 si6 optional
176};
177
178const SystemInformationConfig SystemInformationConfig_omit := {
179 si1 := omit,
180 si2 := omit,
181 si2bis := omit,
182 si2ter := omit,
183 si2quater := omit,
184 si3 := omit,
185 si4 := omit,
186 si13 := omit,
187 si5 := omit,
188 si5bis := omit,
189 si5ter := omit,
190 si6 := omit
191};
192
193/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
194template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
195 template uint3_t meas_bw := 3)
196:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
197 meas_bw_presence := '1'B,
198 meas_bw := meas_bw);
199
200/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200201template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200202 template uint3_t prio := 3,
203 template (present) uint5_t thresh_high := 20,
204 template uint5_t thresh_low := 10,
205 template uint5_t qrxlevmin := 22)
206:= tr_EUTRAN_NeighbourCells(
207 cell_desc_list := cell_desc_list,
208 prio_presence := '1'B,
209 prio := prio,
210 thresh_high := thresh_high,
211 thresh_low_presence := '1'B,
212 thresh_low := thresh_low,
213 qrxlevmin_presence := '1'B,
214 qrxlevmin := qrxlevmin);
215
216template SystemInformationConfig SystemInformationConfig_default := {
217 si1 := {
218 cell_chan_desc := '8FB38000000000000000000000000000'O,
219 rach_control := {
220 max_retrans := RACH_MAX_RETRANS_7,
221 tx_integer := '1001'B,
222 cell_barr_access := false,
223 re_not_allowed := true,
224 acc := '0000010000000000'B
225 },
226 rest_octets := ?
227 },
228 si2 := {
229 bcch_freq_list := '00000000000000000000000000000000'O,
230 ncc_permitted := '11111111'B,
231 rach_control := {
232 max_retrans := RACH_MAX_RETRANS_7,
233 tx_integer := '1001'B,
234 cell_barr_access := false,
235 re_not_allowed := true,
236 acc := '0000010000000000'B
237 }
238 },
239 si2bis := omit,
240 si2ter := {
241 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
242 rest_octets := ?
243 },
244 si2quater := {
245 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
246 },
247 si3 := {
248 cell_id := 0,
249 lai := {
250 mcc_mnc := '001F01'H,
251 lac := 1
252 },
253 ctrl_chan_desc := {
254 msc_r99 := true,
255 att := true,
256 bs_ag_blks_res := 1,
257 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
258 si22ind := false,
259 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
260 spare := '00'B,
261 bs_pa_mfrms := 3,
262 t3212 := 30
263 },
264 cell_options := {
265 dn_ind := false,
266 pwrc := false,
267 dtx := MS_SHALL_USE_UL_DTX,
268 radio_link_tout_div4 := 7
269 },
270 cell_sel_par := {
271 cell_resel_hyst_2dB := 2,
272 ms_txpwr_max_cch := 7,
273 acs := '0'B,
274 neci := true,
275 rxlev_access_min := 0
276 },
277 rach_control := {
278 max_retrans := RACH_MAX_RETRANS_7,
279 tx_integer := '1001'B,
280 cell_barr_access := false,
281 re_not_allowed := true,
282 acc := '0000010000000000'B
283 },
284 rest_octets := {
285 sel_params := {
286 presence := '0'B,
287 params := omit
288 },
289 pwr_offset := {
290 presence := '0'B,
291 offset := omit
292 },
293 si_2ter_ind := '1'B,
294 early_cm_ind := '0'B,
295 sched_where := {
296 presence := '0'B,
297 where := omit
298 },
299 gprs_ind := {
300 presence := '1'B,
301 ind := {
302 ra_colour := 0,
303 si13_pos := '0'B
304 }
305 },
306 umts_early_cm_ind := '1'B,
307 si2_quater_ind := {
308 presence := '1'B,
309 ind := '0'B
310 },
311 iu_mode_ind := omit,
312 si21_ind := {
313 presence := '0'B,
314 pos := omit
315 }
316 }
317 },
318 si4 := {
319 lai := {
320 mcc_mnc := '001F01'H,
321 lac := 1
322 },
323 cell_sel_par := {
324 cell_resel_hyst_2dB := 2,
325 ms_txpwr_max_cch := 7,
326 acs := '0'B,
327 neci := true,
328 rxlev_access_min := 0
329 },
330 rach_control := {
331 max_retrans := RACH_MAX_RETRANS_7,
332 tx_integer := '1001'B,
333 cell_barr_access := false,
334 re_not_allowed := true,
335 acc := '0000010000000000'B
336 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200337 cbch_chan_desc := {
338 iei := '64'O,
339 v := {
340 chan_nr := {
341 u := {
342 sdcch4 := {
343 tag := '001'B,
344 sub_chan := 2
345 }
346 },
347 tn := 0
348 },
349 tsc := 2,
350 h := false,
351 arfcn := 871,
352 maio_hsn := omit
353 }
354 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200355 cbch_mobile_alloc := omit,
356 rest_octets := {
357 sel_params := {
358 presence := '0'B,
359 params := omit
360 },
361 pwr_offset := {
362 presence := '0'B,
363 offset := omit
364 },
365 gprs_ind := {
366 presence := '1'B,
367 ind := {
368 ra_colour := 0,
369 si13_pos := '0'B
370 }
371 },
372 s_presence := '0'B,
373 s := omit
374 }
375 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100376 si13 := {
377 rest_octets := {
378 presence := '1'B,
379 bcch_change_mark := ?,
380 si_change_field := '0000'B,
381 presence2 := '0'B,
382 si13_change_mark := omit,
383 gprs_ma := omit,
384 zero := '0'B, /* PBCCH not present in cell */
385 rac := 0,
386 spgc_ccch_sup := '0'B,
387 priority_access_thr := '110'B,
388 network_control_order := '00'B,
389 gprs_cell_opts := {
390 nmo := '01'B,
391 t3168 := '011'B,
392 t3192 := '010'B,
393 drx_timer_max := '011'B,
394 access_burst_type := '0'B,
395 control_ack_type := '1'B,
396 bs_cv_max := 15,
397 pan_presence := '1'B,
398 pan_dec := 1,
399 pan_inc := 1,
400 pan_max := '111'B,
401 ext_info_presence := ?,
402 ext_info_length := *,
403 ext_info := *
404 },
405 gprs_pwr_ctrl_params := {
406 alpha := 0,
407 t_avg_w := '10000'B,
408 t_avg_t := '10000'B,
409 pc_meas_chan := '0'B,
410 n_avg_i := '1000'B
411 }
412 }
413 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200414 si5 := {
415 bcch_freq_list := '10000000000000000000000000000000'O
416 },
417 si5bis := omit,
418 si5ter := {
419 extd_bcch_freq_list := '9E050020000000000000000000000000'O
420 },
421 si6 := {
422 cell_id := 0,
423 lai := {
424 mcc_mnc := '001F01'H,
425 lac := 1
426 },
427 cell_options := {
428 dtx_ext := '1'B,
429 pwrc := false,
430 dtx := '01'B,
431 radio_link_timeout := '0111'B
432 },
433 ncc_permitted := '11111111'B,
434 rest_octets := ?
435 }
436 };
437
438
439/* List of all the System Information received on all RSL ports */
440type record of SystemInformationConfig SystemInformationConfig_list;
441
442function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
443{
444 var RSL_IE_Body sysinfo_type_ie;
445 var RSL_IE_SysinfoType si_type;
446 var octetstring data;
447
448 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
449 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
450 mtc.stop;
451 }
452 si_type := sysinfo_type_ie.sysinfo_type;
453
454 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
455 var RSL_IE_Body bcch_ie;
456 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
457 data := bcch_ie.other.payload;
458 }
459 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
460 var RSL_IE_Body l3_ie;
461 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
462 data := l3_ie.l3_info.payload;
463 }
464 } else {
465 setverdict(fail, "Don't understand this System Information message");
466 mtc.stop;
467 }
468
469 var boolean handled := false;
470
471 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
472 handled := true;
473
474 if (si_type == RSL_SYSTEM_INFO_1) {
475 if (not isbound(data)) {
476 si.si1 := omit;
477 } else {
478 si.si1 := dec_SystemInformation(data).payload.si1;
479 }
480 } else if (si_type == RSL_SYSTEM_INFO_2) {
481 if (not isbound(data)) {
482 si.si2 := omit;
483 } else {
484 si.si2 := dec_SystemInformation(data).payload.si2;
485 }
486 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
487 if (not isbound(data)) {
488 si.si2bis := omit;
489 } else {
490 si.si2bis := dec_SystemInformation(data).payload.si2bis;
491 }
492 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
493 if (not isbound(data)) {
494 si.si2ter := omit;
495 } else {
496 si.si2ter := dec_SystemInformation(data).payload.si2ter;
497 }
498 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
499 if (not isbound(data)) {
500 si.si2quater := {};
501 } else {
502 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
503 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
504 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
505 }
506 } else if (si_type == RSL_SYSTEM_INFO_3) {
507 if (not isbound(data)) {
508 si.si3 := omit;
509 } else {
510 si.si3 := dec_SystemInformation(data).payload.si3;
511 }
512 } else if (si_type == RSL_SYSTEM_INFO_4) {
513 if (not isbound(data)) {
514 si.si4 := omit;
515 } else {
516 si.si4 := dec_SystemInformation(data).payload.si4;
517 }
518 } else if (si_type == RSL_SYSTEM_INFO_13) {
519 if (not isbound(data)) {
520 si.si13 := omit;
521 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100522 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200523 }
524 } else {
525 handled := false;
526 }
527 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
528 handled := true;
529
530 if (si_type == RSL_SYSTEM_INFO_5) {
531 if (not isbound(data)) {
532 si.si5 := omit;
533 } else {
534 si.si5 := dec_SystemInformation(data).payload.si5;
535 }
536 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
537 if (not isbound(data)) {
538 si.si5bis := omit;
539 } else {
540 si.si5bis := dec_SystemInformation(data).payload.si5bis;
541 }
542 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
543 if (not isbound(data)) {
544 si.si5ter := omit;
545 } else {
546 si.si5ter := dec_SystemInformation(data).payload.si5ter;
547 }
548 } else if (si_type == RSL_SYSTEM_INFO_6) {
549 if (not isbound(data)) {
550 si.si6 := omit;
551 } else {
552 si.si6 := dec_SystemInformation(data).payload.si6;
553 }
554 } else {
555 handled := false;
556 }
557 }
558
559 if (not handled) {
560 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
561 }
562}
563
Harald Weltea4ca4462018-02-09 00:17:14 +0100564type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100565 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100566 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100567 /* RSL common Channel Port (for RSL_Emulation) */
568 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100569 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100570 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100571 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200572 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
573 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100574
Daniel Willmann191e0d92018-01-17 12:44:35 +0100575 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100576 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100577
Daniel Willmannebdecc02020-08-12 15:30:17 +0200578 /* StatsD */
579 var StatsD_Checker_CT vc_STATSD;
580
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200581 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200582 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100583 /* for old legacy-tests only */
584 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200585 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100586
Harald Welte21b46bd2017-12-17 19:46:32 +0100587 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100588 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100589
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200590 /* Osmux is enabled through VTY */
591 var boolean g_osmux_enabled := false;
592
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100593 /*Configure T(tias) over VTY, seconds */
594 var integer g_bsc_sccp_timer_ias := 7 * 60;
595 /*Configure T(tiar) over VTY, seconds */
596 var integer g_bsc_sccp_timer_iar := 15 * 60;
597
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200598 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100599 timer T_guard := 30.0;
600
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200601 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000602 var CounterNameValsList g_ctr_bsc;
603 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200604
605 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
606 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100607}
608
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200609type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100610modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100611 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100612 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100613 /* port number to which to establish the IPA OML connections */
614 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100615 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100616 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100617 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100618 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200619 /* port number to which to listen for STATSD metrics */
620 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100621 /* IP address at which the test binds */
622 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100623
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200624 RAN_Configurations mp_bssap_cfg := {
625 {
626 transport := BSSAP_TRANSPORT_AoIP,
627 sccp_service_type := "mtp3_itu",
628 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
629 own_pc := 185, /* 0.23.1 first MSC emulation */
630 own_ssn := 254,
631 peer_pc := 187, /* 0.23.3 osmo-bsc */
632 peer_ssn := 254,
633 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200634 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200635 },
636 {
637 transport := BSSAP_TRANSPORT_AoIP,
638 sccp_service_type := "mtp3_itu",
639 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
640 own_pc := 2, /* 0.0.2 second MSC emulation */
641 own_ssn := 254,
642 peer_pc := 187, /* 0.23.3 osmo-bsc */
643 peer_ssn := 254,
644 sio := '83'O,
645 rctx := 2
646 },
647 {
648 transport := BSSAP_TRANSPORT_AoIP,
649 sccp_service_type := "mtp3_itu",
650 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
651 own_pc := 3, /* 0.0.3 third MSC emulation */
652 own_ssn := 254,
653 peer_pc := 187, /* 0.23.3 osmo-bsc */
654 peer_ssn := 254,
655 sio := '83'O,
656 rctx := 3
657 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100658 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200659
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200660 /* Must match per BTS config in osmo-bsc.cfg */
661 phys_chan_configs phys_chan_config := {
662 "CCCH+SDCCH4+CBCH",
663 "TCH/F",
664 "TCH/F",
665 "TCH/F",
666 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600667 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200668 "PDCH",
669 "PDCH"
670 };
671
Harald Welte47cd0e32020-08-21 12:39:11 +0200672 BSSAP_LE_Configuration mp_bssap_le_cfg := {
673 sccp_service_type := "mtp3_itu",
674 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200675 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200676 own_ssn := 252, /* SMLC side SSN */
677 peer_pc := 187, /* 0.23.3 osmo-bsc */
678 peer_ssn := 250, /* BSC side SSN */
679 sio := '83'O,
680 rctx := 6
681 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200682 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200683
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +0200684 /* Whether to enable dyn TS SDCCH8 tests. Can be dropped completely and enable
685 unconditionally once new version of osmo-bsc is released (current
686 version: 1.7.0) */
687 boolean mp_enable_dyn_sdcch8_test := true;
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100688 /* Value set in osmo-bsc.cfg "ms max power" */
689 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100690}
691
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200692friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200693
694 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200695 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200696 pars.aoip := true;
697 } else {
698 pars.aoip := false;
699 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100700 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200701 pars.mscpool.bssap_idx := bssap_idx;
Philipp Maier48604732018-10-09 15:00:37 +0200702
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200703 /* BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2 */
704 pars.expect_tsc := 2;
705
Philipp Maier48604732018-10-09 15:00:37 +0200706 return pars;
707}
708
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200709/* Convenience functions for rate counters using g_ctr_msc. */
710
711private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
712 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
713 log("initial msc rate counters: ", g_ctr_msc);
714}
715
716private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200717 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200718}
719
720/* f_ctrs_msc_init();
721 * f_do_thing(on_msc := 0);
722 * f_do_thing(on_msc := 0);
723 * f_do_other(on_msc := 1);
724 * f_ctrs_msc_add(0, "thing", 2);
725 * f_ctrs_msc_add(1, "other");
726 * f_ctrs_msc_verify();
727 */
728private function f_ctrs_msc_verify() runs on test_CT {
729 log("verifying msc rate counters: ", g_ctr_msc);
730 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
731}
732
733/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
734 * f_ctrs_msc_init();
735 * f_do_thing(on_msc := 0);
736 * f_do_thing(on_msc := 0);
737 * f_do_thing(on_msc := 0);
738 * f_ctrs_msc_expect(0, "thing", 3);
739 */
740private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
741 f_ctrs_msc_add(msc_nr, countername, val);
742 f_ctrs_msc_verify();
743}
744
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000745/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
746
747private function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
748 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
749 log("initial bts rate counters: ", g_ctr_bts);
750 f_ctrs_bsc_init(counternames);
751}
752
753private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
754 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
755 f_ctrs_bsc_add(countername, val);
756}
757
758/* f_ctrs_bsc_and_bts_init();
759 * f_do_thing(on_bts := 0);
760 * f_do_thing(on_bts := 0);
761 * f_do_other(on_bts := 1);
762 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
763 * f_ctrs_bsc_and_bts_add(1, "other");
764 * f_ctrs_bsc_and_bts_verify();
765 */
766private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
767 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
768 f_ctrs_bsc_verify();
769}
770
771/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
772 * f_ctrs_bsc_and_bts_init();
773 * f_do_thing(on_bts := 0);
774 * f_do_thing(on_bts := 0);
775 * f_do_thing(on_bts := 0);
776 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
777 */
778private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
779 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
780 f_ctrs_bsc_and_bts_verify();
781}
782
783
784/* Convenience functions for rate counters using g_ctr_bsc. */
785
786private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
787 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
788 log("initial bsc rate counters: ", g_ctr_bsc);
789}
790
791private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
792 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
793}
794
795/* f_ctrs_bsc_init();
796 * f_do_thing();
797 * f_do_thing();
798 * f_do_other();
799 * f_ctrs_bsc_add("thing", 2);
800 * f_ctrs_bsc_add("other");
801 * f_ctrs_bsc_verify();
802 */
803private function f_ctrs_bsc_verify() runs on test_CT {
804 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
805}
806
807/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
808 * f_ctrs_bsc_init();
809 * f_do_thing();
810 * f_ctrs_bsc_expect("thing", 1);
811 */
812private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
813 f_ctrs_bsc_add(countername, val);
814 f_ctrs_bsc_verify();
815}
816
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200817
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200818friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200819 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100820 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200821 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100822}
823
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200824private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100825 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200826 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100827 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200828 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
829 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100830 T.start;
831 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200832 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
833 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200834 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100835 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200836 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200837 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100838 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200839 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200840 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100841 repeat;
842 }
843 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200844 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200845 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200846 /* If we received a RESET after ours was sent, it
847 may be a race condition where the other peer beacame
848 available after we sent it, but we are in a desired
849 state anyway, so go forward. */
850 if (not reset_received) {
851 setverdict(fail);
852 }
853 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100854 }
Harald Welte28d943e2017-11-25 15:00:50 +0100855}
856
Harald Welteae026692017-12-09 01:03:01 +0100857type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100858 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100859 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100860 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100861 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100862 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100863 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100864 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100865 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100866}
867
Harald Welte21b46bd2017-12-17 19:46:32 +0100868/*! Start the IPA/RSL related bits for one IPA_Client.
869 * \param clnt IPA_Client for which to establish
870 * \param bsc_host IP address / hostname of the BSC
871 * \param bsc_port TCP port number of the BSC
872 * \param i number identifying this BTS
873 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100874function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
875 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100876runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100877 timer T := 10.0;
878
Harald Welte96c94412017-12-09 03:12:45 +0100879 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100880 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
881 clnt.ccm_pars := c_IPA_default_ccm_pars;
882 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
883 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100884 if (handler_mode) {
885 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100886 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100887 }
Harald Welteae026692017-12-09 01:03:01 +0100888
889 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100890 if (handler_mode) {
891 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
892 } else {
893 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
894 }
Harald Welteae026692017-12-09 01:03:01 +0100895
Harald Welte5d1a2202017-12-13 19:51:29 +0100896 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100897 if (handler_mode) {
898 clnt.vc_RSL.start(RSL_Emulation.main());
899 return;
900 }
Harald Welteae026692017-12-09 01:03:01 +0100901
902 /* wait for IPA RSL link to connect and send ID ACK */
903 T.start;
904 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700905 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100906 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700907 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100908 }
Harald Welte60e823a2017-12-10 14:10:59 +0100909 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100910 [] IPA_RSL[i].receive { repeat }
911 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100912 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200913 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100914 }
915 }
916}
917
Harald Welte12055472018-03-17 20:10:08 +0100918function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
919 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
920 return;
921 }
922 clnt.vc_IPA.stop;
923 if (isbound(clnt.vc_RSL)) {
924 clnt.vc_RSL.stop;
925 }
926}
927
Harald Welte21b46bd2017-12-17 19:46:32 +0100928/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100929function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
930 timer T := secs_max;
931 T.start;
932 while (true) {
933 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
934 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100935 /* the 'degraded' state exists from OML connection time, and we have to wait
936 * until all MO's are initialized */
937 T.start(1.0);
938 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100939 return;
940 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100941 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100942 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100943 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200944 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100945 }
946 }
947}
948
Harald Welte21b46bd2017-12-17 19:46:32 +0100949/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100950altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100951 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100952 [] T_guard.timeout {
953 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200954 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100955 }
Harald Welte60e823a2017-12-10 14:10:59 +0100956 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200957 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100958 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200959 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100960 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100961 }
Harald Welte28d943e2017-11-25 15:00:50 +0100962}
963
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100964altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200965 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100966 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +0200967 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100968 }
969}
970
Daniel Willmann191e0d92018-01-17 12:44:35 +0100971function f_init_mgcp(charstring id) runs on test_CT {
972 id := id & "-MGCP";
973
974 var MGCPOps ops := {
975 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
976 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
977 };
978 var MGCP_conn_parameters mgcp_pars := {
979 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +0100980 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +0100981 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200982 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +0200983 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
984 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200985 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +0100986 };
987
988 vc_MGCP := MGCP_Emulation_CT.create(id);
989 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
990}
991
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200992/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
993 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
994 * OsmuxCID IE.
995 */
996private function f_vty_allow_osmux(boolean allow) runs on test_CT {
997 f_vty_enter_cfg_msc(BSCVTY, 0);
998 if (allow) {
999 f_vty_transceive(BSCVTY, "osmux on");
1000 } else {
1001 f_vty_transceive(BSCVTY, "osmux off");
1002 }
1003 f_vty_transceive(BSCVTY, "exit");
1004 f_vty_transceive(BSCVTY, "exit");
1005 g_osmux_enabled := allow;
1006}
1007
Max2253c0b2018-11-06 19:28:05 +01001008function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001009 if (BSCVTY.checkstate("Mapped")) {
1010 /* skip initialization if already executed once */
1011 return;
1012 }
Harald Weltebc03c762018-02-12 18:09:38 +01001013 map(self:BSCVTY, system:BSCVTY);
1014 f_vty_set_prompts(BSCVTY);
1015 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001016 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1017 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001018}
1019
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001020friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001021{
1022 // log on TTCN3 log output
1023 log(log_msg);
1024 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001025 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001026}
1027
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001028private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1029{
1030 if (rsl_idx >= lengthof(g_system_information)) {
1031 g_system_information[rsl_idx] := SystemInformationConfig_omit
1032 }
1033 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1034}
1035
1036altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1037 var ASP_RSL_Unitdata rx_rsl_ud;
1038
1039 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1040 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1041 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1042 repeat;
1043 }
1044 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1045 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1046 repeat;
1047 }
1048 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1049 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1050 repeat;
1051 }
1052 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1053 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1054 repeat;
1055 }
1056
1057 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1058 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1059 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1060 repeat;
1061 }
1062 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1063 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1064 repeat;
1065 }
1066 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1067 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1068 repeat;
1069 }
1070 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1071 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1072 repeat;
1073 }
1074}
1075
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001076/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1077private type record of boolean my_BooleanList;
1078
1079private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1080{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001081 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1082
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001083 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001084 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1085 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1086 * stepping into that config node. */
1087 log("msc ", msc_nr, " is not configured, skipping");
1088 continue;
1089 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001090 f_vty_enter_cfg_msc(pt, msc_nr);
1091 if (allow_attach_list[msc_nr]) {
1092 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1093 f_vty_transceive(pt, "allow-attach", strict := false);
1094 } else {
1095 f_vty_transceive(pt, "no allow-attach", strict := false);
1096 }
1097 f_vty_transceive(pt, "exit");
1098 f_vty_transceive(pt, "exit");
1099 }
1100}
1101
Harald Welte21b46bd2017-12-17 19:46:32 +01001102/* global initialization function
1103 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001104 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1105 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1106 */
1107function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001108 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001109 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001110
Harald Welteae026692017-12-09 01:03:01 +01001111 if (g_initialized) {
1112 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001113 }
Harald Welteae026692017-12-09 01:03:01 +01001114 g_initialized := true;
1115
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001116 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001117 activate(as_Tguard());
1118
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001119 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001120 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001121
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001122 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001123 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1124
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001125 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1126 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1127 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1128 }
1129
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001130 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001131 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001132 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1133 * MSC-side BSSAP emulation */
1134 if (handler_mode) {
1135 var RanOps ranops := MSC_RanOps;
1136 ranops.use_osmux := g_osmux_enabled;
1137 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1138 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1139 f_ran_adapter_start(g_bssap[bssap_idx]);
1140 } else {
1141 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1142 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1143 f_ran_adapter_start(g_bssap[bssap_idx]);
1144 f_legacy_bssap_reset();
1145 }
Harald Welte67089ee2018-01-17 22:19:03 +01001146 }
Harald Welted5833a82018-05-27 16:52:56 +02001147
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001148 if (mp_enable_lcs_tests) {
1149 if (handler_mode) {
1150 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1151 } else {
1152 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1153 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1154 }
1155 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001156 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001157
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001158 /* start the test with exactly all enabled MSCs allowed to attach */
1159 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1160
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001161 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001162
Daniel Willmann191e0d92018-01-17 12:44:35 +01001163 f_init_mgcp("VirtMSC");
1164
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001165 for (var integer i := 0; i < nr_bts; i := i+1) {
1166 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001167 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001168}
Harald Welte696ddb62017-12-08 14:01:43 +01001169
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001170function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1171runs on test_CT {
1172 /* wait until osmo-bts-omldummy has respawned */
1173 f_wait_oml(bts_idx, "degraded", 5.0);
1174
1175 /* start RSL connection */
1176 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1177 /* wait until BSC tells us "connected" */
1178 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001179}
1180
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001181function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1182 template SystemInformationConfig expect_si)
1183runs on test_CT {
1184 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1185
1186 f_init_bts(bts_idx, handler_mode);
1187
1188 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1189 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1190 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1191 */
1192 f_sleep(5.0);
1193 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1194
1195 deactivate(sysinfo);
1196
1197 if (match(g_system_information[bts_idx], expect_si)) {
1198 setverdict(pass);
1199 } else {
1200 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1201 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1202 setverdict(fail, "received SI does not match expectations");
1203 return;
1204 }
1205}
1206
Maxd4e56962018-10-31 19:08:25 +01001207/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001208function 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 +01001209runs on test_CT return RSL_Message {
1210 var ASP_RSL_Unitdata rx_rsl_ud;
1211 timer T := t_secs;
1212
1213 T.start;
1214 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001215 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001216 T.stop;
1217 }
1218 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001219 [] T.timeout {
1220 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001221 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001222 }
Harald Welteae026692017-12-09 01:03:01 +01001223 }
1224 return rx_rsl_ud.rsl;
1225}
1226
Harald Welte21b46bd2017-12-17 19:46:32 +01001227/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001228function 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 +01001229runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001230 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001231}
1232
1233
Harald Welte4003d112017-12-09 22:35:39 +01001234/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001235testcase TC_chan_act_noreply() runs on test_CT {
1236 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001237 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001238
Harald Welte89d42e82017-12-17 16:42:41 +01001239 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001240
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001241 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001242 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001243 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001244}
1245
Harald Welte4003d112017-12-09 22:35:39 +01001246/* verify if the "chreq:total" counter increments as expected */
1247testcase TC_chan_act_counter() runs on test_CT {
1248 var BSSAP_N_UNITDATA_ind ud_ind;
1249 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001250 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001251
Harald Welte89d42e82017-12-17 16:42:41 +01001252 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001253
1254 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001255 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001256 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001257 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1258
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001259 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001260}
1261
Harald Welteae026692017-12-09 01:03:01 +01001262/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001263private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001264 var RSL_Message rx_rsl;
1265
Harald Welteae026692017-12-09 01:03:01 +01001266 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001267 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001268
1269 /* expect BSC to disable the channel again if there's no RLL EST IND */
1270 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1271
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001272 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001273}
1274
Philipp Maier9c60a622020-07-09 15:08:46 +02001275/* Normal variant */
1276testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001277 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001278 f_TC_chan_act_ack_noest();
1279}
1280
1281/* Emergency call variant */
1282testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1283 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001284 f_init(1);
1285 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001286 f_TC_chan_act_ack_noest(ra := 'A5'O);
1287}
1288
Philipp Maier606f07d2020-08-12 17:21:58 +02001289/* Emergency call variant, but emergency calls are not allowed */
1290testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1291 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1292
1293 var RSL_Message rx_rsl;
1294 var GsmRrMessage rr;
1295
1296 f_init(1);
1297 f_vty_allow_emerg_bts(false, 0);
1298
1299 IPA_RSL[0].clear;
1300 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1301
1302 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1303 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1304 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1305 setverdict(pass);
1306 } else {
1307 setverdict(fail, "immediate assignment not rejected");
1308 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001309
1310 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001311}
1312
Harald Welteae026692017-12-09 01:03:01 +01001313/* Test behavior if MSC never answers to CR */
1314testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001315 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1316 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001317 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001318 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001319
Harald Welte89d42e82017-12-17 16:42:41 +01001320 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001321
1322 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001323 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001324
1325 var octetstring l3 := '00010203040506'O
1326 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1327
1328 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1329
1330 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001331 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001332 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001333 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001334}
1335
1336/* Test behavior if MSC answers with CREF to CR */
1337testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1338 var BSSAP_N_CONNECT_ind rx_c_ind;
1339 var RSL_Message rx_rsl;
1340
Harald Welte89d42e82017-12-17 16:42:41 +01001341 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001342
1343 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001344 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001345
1346 var octetstring l3 := '00010203040506'O
1347 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1348
1349 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1350 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1351
1352 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001353 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001354 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001355}
1356
Harald Welte618ef642017-12-14 14:58:20 +01001357/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1358testcase TC_chan_act_nack() runs on test_CT {
1359 var RSL_Message rx_rsl;
1360 var integer chact_nack;
1361
Harald Welte89d42e82017-12-17 16:42:41 +01001362 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001363
1364 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1365
1366 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1367 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1368 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1369
1370 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1371
1372 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1373 f_sleep(0.5);
1374
1375 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1376
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001377 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001378}
1379
Harald Welte799c97b2017-12-14 17:50:30 +01001380/* Test for channel exhaustion due to RACH overload */
1381testcase TC_chan_exhaustion() runs on test_CT {
1382 var ASP_RSL_Unitdata rsl_ud;
1383 var integer i;
1384 var integer chreq_total, chreq_nochan;
1385
Harald Welte89d42e82017-12-17 16:42:41 +01001386 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001387
1388 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1389 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1390
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001391 /* GSM 04.08 Table 9.9a:
1392 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1393 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001394 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 +01001395 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001396 }
1397
1398 IPA_RSL[0].clear;
1399
Harald Weltedd8cbf32018-01-28 12:07:52 +01001400 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001401 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001402
1403 /* now expect additional channel activations to fail */
1404 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1405
1406 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001407 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001408 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1409 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001410 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001411 var GsmRrMessage rr;
1412 /* match on IMM ASS REJ */
1413 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1414 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1415 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001416 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001417 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1418 chreq_nochan+1);
1419 setverdict(pass);
1420 } else {
1421 repeat;
1422 }
1423 }
1424 [] IPA_RSL[0].receive { repeat; }
1425 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001426 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001427}
1428
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001429/* Test channel deactivation due to silence from MS */
1430testcase TC_chan_deact_silence() runs on test_CT {
1431 var RslChannelNr chan_nr;
1432
1433 f_init(1);
1434
1435 /* Request for a dedicated channel */
1436 chan_nr := f_chreq_act_ack('23'O);
1437
1438 /* Wait some time until the channel is released */
1439 f_sleep(2.0);
1440
1441 /* Expect CHANnel RELease */
1442 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001443 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001444 log("Received CHANnel RELease");
1445 setverdict(pass);
1446 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001447 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001448 /* See OS#3709, OsmoBSC should not send Immediate
1449 * Assignment Reject since a dedicated channel was
1450 * already allocated, and Immediate Assignment was
1451 * already sent. */
1452 setverdict(fail, "Unexpected Immediate Assignment!");
1453 }
1454 [] IPA_RSL[0].receive {
1455 setverdict(fail, "Unexpected RSL message!");
1456 }
1457 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001458 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001459}
1460
Harald Weltecfe2c962017-12-15 12:09:32 +01001461/***********************************************************************
1462 * Assignment Testing
1463 ***********************************************************************/
1464
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001465/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1466 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001467testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001468 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001469
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001470 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1471 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001472 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001473 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001474}
1475
Harald Welte16a4adf2017-12-14 18:54:01 +01001476/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001477testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001478 var BSSAP_N_CONNECT_ind rx_c_ind;
1479 var RSL_Message rx_rsl;
1480 var DchanTuple dt;
1481
Harald Welte89d42e82017-12-17 16:42:41 +01001482 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001483
1484 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001485 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001486 /* send assignment without AoIP IEs */
1487 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1488 } else {
1489 /* Send assignmetn without CIC in IPA case */
1490 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1491 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1492 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1493 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001494 alt {
1495 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1496 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1497 }
Harald Welte235ebf12017-12-15 14:18:16 +01001498 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001499 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1500 setverdict(pass);
1501 }
1502 [] BSSAP.receive { repeat; }
1503 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001504 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001505}
1506
Harald Welteed848512018-05-24 22:27:58 +02001507/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001508function 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 +02001509 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001510 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001511 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001512 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001513 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001514 if (osmux_enabled) {
1515 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1516 } else {
1517 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1518 }
Harald Welteed848512018-05-24 22:27:58 +02001519 } else {
1520 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001521 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001522 }
1523 return ass_cmd;
1524}
1525
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001526function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001527 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1528 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001529 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001530
1531 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1532 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1533 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1534 var template BSSMAP_IE_KC128 kc128 := omit;
1535 if (ispresent(enc)) {
1536 var TestHdlrEncrParams v_enc := valueof(enc);
1537 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1538 chosenEncryptionAlgorithm := valueof(
1539 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001540 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001541 if (ispresent(v_enc.enc_kc128)) {
1542 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1543 }
1544 }
1545
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001546 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001547 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001548 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001549 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1550 encryptionInformation := encryptionInformation,
1551 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1552 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001553 } else {
1554 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001555 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1556 encryptionInformation := encryptionInformation,
1557 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1558 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001559 }
1560 return ho_req;
1561}
1562
Harald Welteed848512018-05-24 22:27:58 +02001563/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001564function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001565 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001566 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001567 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001568 if (expect_osmux) {
1569 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1570 } else {
1571 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1572 }
Harald Welteed848512018-05-24 22:27:58 +02001573 } else {
1574 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001575 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001576 }
1577 return exp_compl;
1578}
1579
Harald Welte235ebf12017-12-15 14:18:16 +01001580/* Run everything required up to sending a caller-specified assignment command and expect response */
1581function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1582runs on test_CT {
1583 var BSSAP_N_CONNECT_ind rx_c_ind;
1584 var RSL_Message rx_rsl;
1585 var DchanTuple dt;
1586
Harald Welte89d42e82017-12-17 16:42:41 +01001587 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001588
1589 dt := f_est_dchan('23'O, 23, '00000000'O);
1590 /* send assignment without AoIP IEs */
1591 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1592 alt {
1593 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1594 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1595 setverdict(pass);
1596 } else {
1597 setverdict(fail, fail_text);
1598 }
1599 }
1600 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1601 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1602 setverdict(pass);
1603 } else {
1604 setverdict(fail, fail_text);
1605 }
1606 }
1607 [] BSSAP.receive { repeat; }
1608 }
1609}
1610testcase TC_assignment_csd() runs on test_CT {
1611 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001612 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001613 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1614 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1615 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001616 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001617}
1618
1619testcase TC_assignment_ctm() runs on test_CT {
1620 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001621 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001622 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1623 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1624 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001625 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001626}
1627
Harald Welte4003d112017-12-09 22:35:39 +01001628type record DchanTuple {
1629 integer sccp_conn_id,
1630 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001631}
1632
Harald Welted6939652017-12-13 21:02:46 +01001633/* Send CHAN RQD and wait for allocation; acknowledge it */
1634private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1635runs on test_CT return RslChannelNr {
1636 var RSL_Message rx_rsl;
1637 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1638 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1639 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1640 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001641 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001642 return chan_nr;
1643}
1644
Harald Welte4003d112017-12-09 22:35:39 +01001645/* helper function to establish a dedicated channel via BTS and MSC */
1646function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1647runs on test_CT return DchanTuple {
1648 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001649 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001650
Harald Welte4003d112017-12-09 22:35:39 +01001651 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001652 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001653
1654 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1655
1656 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1657 dt.sccp_conn_id := rx_c_ind.connectionId;
1658 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1659
1660 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001661}
1662
Harald Welte641fcbe2018-06-14 10:58:35 +02001663/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1664private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1665 var RSL_Message rx_rsl;
1666 /* expect BSC to disable the channel */
1667 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1668 /* respond with CHAN REL ACK */
1669 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1670
1671 /* expect Clear Complete from BSC */
1672 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1673
1674 /* MSC disconnects as instructed. */
1675 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1676}
1677
Harald Welte4003d112017-12-09 22:35:39 +01001678/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1679testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001680 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001681 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001682
Harald Welte89d42e82017-12-17 16:42:41 +01001683 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001684
Harald Welte4003d112017-12-09 22:35:39 +01001685 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1686
1687 /* simulate RLL REL IND */
1688 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1689
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001690 /* expect Clear Request on MSC side */
1691 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1692
1693 /* Instruct BSC to clear channel */
1694 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1695 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1696
Harald Welte4003d112017-12-09 22:35:39 +01001697 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001698 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001699
1700 /* wait for SCCP emulation to do its job */
1701 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001702
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001703 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001704}
1705
1706/* Test behavior of channel release after CONN FAIL IND from BTS */
1707testcase TC_chan_rel_conn_fail() runs on test_CT {
1708 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001709 var DchanTuple dt;
1710
Harald Welte89d42e82017-12-17 16:42:41 +01001711 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001712
1713 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1714
1715 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001716 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 +01001717 /* TODO: different cause values? */
1718
Harald Welte4003d112017-12-09 22:35:39 +01001719 /* expect Clear Request from BSC */
1720 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1721
1722 /* Instruct BSC to clear channel */
1723 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1724 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1725
Harald Welte6ff76ea2018-01-28 13:08:01 +01001726 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001727 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001728
1729 /* wait for SCCP emulation to do its job */
1730 f_sleep(1.0);
1731
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001732 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001733}
1734
Harald Welte99f3ca02018-06-14 13:40:29 +02001735/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1736/* See also https://www.osmocom.org/issues/3182 */
1737testcase TC_early_conn_fail() runs on test_CT {
1738 var RSL_Message rx_rsl;
1739 var DchanTuple dt;
1740
1741 f_init(1);
1742
1743 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001744 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001745
1746 /* BTS->BSC: simulate CONN FAIL IND */
1747 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1748
1749 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1750 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1751
1752 /* BTS<-BSC: respond with CHAN REL ACK */
1753 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1754
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001755 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001756}
1757
1758/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1759/* See also https://www.osmocom.org/issues/3182 */
1760testcase TC_late_conn_fail() runs on test_CT {
1761 var RSL_Message rx_rsl;
1762 var DchanTuple dt;
1763
1764 f_init(1);
1765
1766 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1767
1768 /* BSC<-MSC: Instruct BSC to clear connection */
1769 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1770
1771 /* BTS->BSC: expect BSC to deactivate SACCH */
1772 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1773
1774 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1775 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1776
1777 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1778 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1779 /* BTS->BSC: respond with CHAN REL ACK */
1780 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1781
1782 /* BSC->MSC: expect Clear Complete from BSC */
1783 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1784
1785 /* BSC<-MSC: MSC disconnects as requested. */
1786 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1787
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001788 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001789}
1790
Oliver Smithaf03bef2021-08-24 15:34:51 +02001791private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1792 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1793 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1794
1795 f_statsd_reset();
1796
1797 /* Establish SDCCH */
1798 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1799 f_establish_fully(ass_cmd, exp_fail);
1800
1801 /* Expect stats to be 0 */
1802 var StatsDExpects expect := {
1803 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1804 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1805 };
1806 f_statsd_expect(expect);
1807
1808 /* Simulate CONN FAIL IND on SDCCH */
1809 RSL.send(ts_ASP_RSL_UD(
1810 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1811 IPAC_PROTO_RSL_TRX0));
1812
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001813 f_sleep(1.0);
1814
Oliver Smithaf03bef2021-08-24 15:34:51 +02001815 /* Expect stats to be 1 */
1816 expect := {
1817 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1818 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1819 };
1820 f_statsd_expect(expect);
1821}
1822testcase TC_stats_conn_fail() runs on test_CT {
1823 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1824 var MSC_ConnHdlr vc_conn;
1825
1826 f_init(1, true);
1827 f_sleep(1.0);
1828
1829 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1830 vc_conn.done;
1831
1832 f_shutdown_helper();
1833}
1834
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001835function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001836 boolean expect_deact_sacch := true,
1837 boolean expect_rr_chan_rel := true,
1838 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001839 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001840 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001841 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001842 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001843
1844 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001845 var boolean got_deact_sacch := false;
1846 var boolean got_rr_chan_rel := false;
1847 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001848 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001849 var RSL_IE_Body l3_ie;
1850 var PDU_ML3_NW_MS l3;
1851 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001852 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1853 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001854 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001855 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001856 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001857 repeat;
1858 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001859 [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 +01001860 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001861
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001862 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1863 setverdict(fail, "cannot find L3");
1864 mtc.stop;
1865 }
1866 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1867
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001868 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001869 var CellSelIndValue cells := dec_CellSelIndValue(
1870 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1871
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001872 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1873 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001874 setverdict(pass);
1875 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001876 log("EXPECTED CELLS: ", expect_cells);
1877 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001878 }
1879 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001880
1881 if (not istemplatekind(expect_rr_cause, "omit")) {
1882 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1883 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1884 if (match(got_cause, expect_rr_cause)) {
1885 setverdict(pass);
1886 } else {
1887 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1888 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1889 }
1890 }
Harald Welte99787102019-02-04 10:41:36 +01001891 repeat;
1892 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001893 [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 +01001894 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001895
1896 if (not istemplatekind(expect_rr_cause, "omit")) {
1897 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1898 setverdict(fail, "cannot find L3");
1899 mtc.stop;
1900 }
1901 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1902
1903 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1904 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1905 if (match(got_cause, expect_rr_cause)) {
1906 setverdict(pass);
1907 } else {
1908 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1909 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1910 }
1911 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001912 repeat;
1913 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001914 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001915 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001916 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001917 if (handle_rll_rel) {
1918 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1919 }
Harald Welte91d54a52018-01-28 15:35:07 +01001920 repeat;
1921 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001922 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001923 /* respond with CHAN REL ACK */
1924 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1925 }
1926 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001927 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001928 repeat;
1929 }
1930 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001931
1932 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
1933 " got_rll_rel_req=", got_rll_rel_req);
1934
1935 if (expect_deact_sacch != got_deact_sacch) {
1936 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
1937 }
1938 if (expect_rr_chan_rel != got_rr_chan_rel) {
1939 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
1940 }
1941 if (expect_rll_rel_req != got_rll_rel_req) {
1942 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
1943 }
Harald Welte91d54a52018-01-28 15:35:07 +01001944}
1945
Harald Welte4003d112017-12-09 22:35:39 +01001946/* Test behavior of channel release after hard Clear Command from MSC */
1947testcase TC_chan_rel_hard_clear() runs on test_CT {
1948 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001949 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01001950
Harald Welte89d42e82017-12-17 16:42:41 +01001951 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001952
1953 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1954
1955 /* Instruct BSC to clear channel */
1956 var BssmapCause cause := 0;
1957 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1958
1959 /* expect Clear Complete from BSC on A */
1960 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1961 /* release the SCCP connection */
1962 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1963 }
1964
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001965 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001966 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001967}
1968
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001969function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
1970 var BSSAP_N_DATA_ind rx_di;
1971 var DchanTuple dt;
1972
1973 f_init(1);
1974
1975 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1976 /* Send CommonID with some random PLMN (BSC doesn't take it into account
1977 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
1978 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
1979
1980 /* Instruct BSC to clear channel */
1981 var BssmapCause cause := 0;
1982 if (tx_csfb_ind) {
1983 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
1984 } else {
1985 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1986 }
1987
1988 /* expect Clear Complete from BSC on A */
1989 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1990 /* release the SCCP connection */
1991 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1992 }
1993
1994 /* 1 neighbor is added by default in osmo-bts.cfg and
1995 SystemInformationConfig_default, use that: */
1996 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
1997
1998 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
1999 f_shutdown_helper();
2000}
2001
2002/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2003 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2004 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2005 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2006 Indicator or not shouldn't matter at all. */
2007testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2008 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2009}
2010
2011/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2012 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2013 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2014 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2015testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2016 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2017}
2018
2019/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2020 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2021 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2022 CSFB Indicator should not be used anymore, and hence, there should be no
2023 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2024 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002025testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2026 var BSSAP_N_DATA_ind rx_di;
2027 var DchanTuple dt;
2028
2029 f_init(1);
2030
2031 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2032
2033 /* Instruct BSC to clear channel */
2034 var BssmapCause cause := 0;
2035 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2036
2037 /* expect Clear Complete from BSC on A */
2038 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2039 /* release the SCCP connection */
2040 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2041 }
2042
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002043 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002044 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002045}
2046
Harald Welted8c36cd2017-12-09 23:05:31 +01002047/* Test behavior of channel release after hard RLSD from MSC */
2048testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002049 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002050
Harald Welte89d42e82017-12-17 16:42:41 +01002051 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002052
2053 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2054
2055 /* release the SCCP connection */
2056 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2057
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002058 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002059 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002060}
2061
Harald Welte550daf92018-06-11 19:22:13 +02002062/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2063testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2064 var DchanTuple dt;
2065
2066 f_init(1);
2067
2068 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2069
2070 /* release the SCCP connection */
2071 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2072
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002073 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002074 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002075}
2076
Harald Welte85804d42017-12-10 14:11:58 +01002077/* Test behavior of channel release after BSSMAP RESET from MSC */
2078testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002079 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002080
Harald Welte89d42e82017-12-17 16:42:41 +01002081 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002082
2083 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2084
2085 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2086 IPA_RSL[0].clear;
2087
2088 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002089 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 +01002090 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002091 [] 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 +01002092 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2093 }
2094
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002095 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002096 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002097}
2098
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002099/* Verify T(iar) triggers and releases the channel */
2100testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2101 var DchanTuple dt;
2102
2103 /* Set T(iar) in BSC low enough that it will trigger before other side
2104 has time to keep alive with a T(ias). Keep recommended ratio of
2105 T(iar) >= T(ias)*2 */
2106 g_bsc_sccp_timer_ias := 2;
2107 g_bsc_sccp_timer_iar := 5;
2108
2109 f_init(1);
2110
2111 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2112 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002113 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002114}
2115
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002116private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2117runs on test_CT
2118{
2119 var DchanTuple dt;
2120
2121 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2122 var BssmapCause cause := 0;
2123 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2124 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2125 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2126 }
2127
2128 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 +02002129}
2130
2131/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2132testcase TC_chan_rel_rr_cause() runs on test_CT {
2133 f_init(1);
2134
2135 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2136 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2137 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2138 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2139 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2140 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002141
2142 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002143}
2144
Harald Welte5cd20ed2017-12-13 21:03:20 +01002145/* Test behavior if RSL EST IND for non-active channel */
2146testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2147 timer T := 2.0;
2148
Harald Welte89d42e82017-12-17 16:42:41 +01002149 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002150
2151 var octetstring l3 := '00010203040506'O;
2152 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2153 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2154
2155 T.start;
2156 alt {
2157 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2158 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2159 }
2160 [] BSSAP.receive {}
2161 [] IPA_RSL[0].receive {}
2162 [] T.timeout {}
2163 }
2164
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002165 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002166}
2167
2168/* Test behavior if RSL EST IND for invalid SAPI */
2169testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2170 var RslChannelNr chan_nr;
2171
Harald Welte89d42e82017-12-17 16:42:41 +01002172 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002173
2174 chan_nr := f_chreq_act_ack()
2175
2176 var octetstring l3 := '00010203040506'O;
2177 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2178
2179 timer T := 2.0;
2180 T.start;
2181 alt {
2182 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2183 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2184 }
2185 [] BSSAP.receive { repeat; }
2186 [] IPA_RSL[0].receive { repeat; }
2187 [] T.timeout {}
2188 }
2189
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002190 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002191}
2192
2193/* Test behavior if RSL EST IND for invalid SAPI */
2194testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2195 timer T := 2.0;
2196
Harald Welte89d42e82017-12-17 16:42:41 +01002197 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002198
2199 var RslChannelNr chan_nr := f_chreq_act_ack();
2200
2201 var octetstring l3 := '00010203040506'O;
2202 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2203
2204 T.start;
2205 alt {
2206 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2207 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2208 }
2209 [] BSSAP.receive { repeat; }
2210 [] IPA_RSL[0].receive { repeat; }
2211 [] T.timeout {}
2212 }
2213
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002214 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002215}
2216
2217/* Test behavior if RSL EST IND for invalid SACCH */
2218testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2219 timer T := 2.0;
2220
Harald Welte89d42e82017-12-17 16:42:41 +01002221 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002222
2223 var RslChannelNr chan_nr := f_chreq_act_ack();
2224
2225 var octetstring l3 := '00010203040506'O;
2226 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2227
2228 T.start;
2229 alt {
2230 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2231 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2232 }
2233 [] BSSAP.receive { repeat; }
2234 [] IPA_RSL[0].receive { repeat; }
2235 [] T.timeout {}
2236 }
2237
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002238 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002239}
2240
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002241/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2242private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2243 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2244 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2245
2246 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2247 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2248
2249 f_establish_fully(ass_cmd, exp_compl);
2250
2251 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2252 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2253 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2254 BSSAP.receive(PDU_BSSAP:{
2255 discriminator := '1'B,
2256 spare := '0000000'B,
2257 dlci := 'C3'O,
2258 lengthIndicator := ?,
2259 pdu := { dtap := '0904'O }
2260 });
2261
2262 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2263 for (var integer i := 0; i < 32; i := i + 1) {
2264 var octetstring l3 := '09'O & f_rnd_octstring(14);
2265 var template (value) RslLinkId link_id;
2266 var template (value) OCT1 dlci;
2267
2268 if (i mod 2 == 0) {
2269 /* SAPI0 on FACCH or SDCCH */
2270 link_id := ts_RslLinkID_DCCH(0);
2271 dlci := '80'O;
2272 } else {
2273 /* SAPI3 on SACCH */
2274 link_id := ts_RslLinkID_SACCH(3);
2275 dlci := 'C3'O;
2276 }
2277
2278 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002279 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002280 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002281 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002282 }
2283}
2284testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2285 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2286 var MSC_ConnHdlr vc_conn;
2287
2288 f_init(1, true);
2289 f_sleep(1.0);
2290
2291 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2292 vc_conn.done;
2293
2294 f_shutdown_helper();
2295}
2296
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002297private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2298 template myBSSMAP_Cause cause := ?,
2299 float T_val := 2.0)
2300runs on test_CT {
2301 var BSSAP_N_DATA_ind rx_di;
2302 timer T;
2303
2304 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2305 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2306
2307 T.start(T_val);
2308 alt {
2309 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2310 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2311 if (not match(rx_cause, tr_cause)) {
2312 setverdict(fail, "Rx unexpected Cause IE: ",
2313 rx_cause, " vs expected ", tr_cause);
2314 }
2315 setverdict(pass);
2316 }
2317 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2318 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2319 }
2320 [] T.timeout {
2321 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2322 }
2323 }
2324}
2325
2326/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2327testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2328 var octetstring rnd_data := f_rnd_octstring(16);
2329 var RSL_Message rx_rsl;
2330 var DchanTuple dt;
2331
2332 f_init(1);
2333
2334 /* MS establishes a SAPI=0 link on DCCH */
2335 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2336
2337 /* MSC sends some data on (not yet established) SAPI=3 link */
2338 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2339 /* BSC attempts to establish a SAPI=3 link on DCCH */
2340 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2341
2342 /* MS sends unexpected RELease INDication on SAPI=3 */
2343 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2344 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2345 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2346
2347 /* Clean up the connection */
2348 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2349 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2350
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002351 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002352}
2353
2354/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2355testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2356 var octetstring rnd_data := f_rnd_octstring(16);
2357 var RSL_Message rx_rsl;
2358 var DchanTuple dt;
2359
2360 f_init(1);
2361
2362 /* MS establishes a SAPI=0 link on DCCH */
2363 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2364
2365 /* MSC sends some data on (not yet established) SAPI=3 link */
2366 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2367 /* BSC attempts to establish a SAPI=3 link on DCCH */
2368 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2369
2370 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2371 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2372 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2373 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2374
2375 /* Clean up the connection */
2376 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2377 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2378
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002379 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002380}
2381
2382/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2383testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2384 var octetstring rnd_data := f_rnd_octstring(16);
2385 var RSL_Message rx_rsl;
2386 var DchanTuple dt;
2387
2388 f_init(1);
2389
2390 /* MS establishes a SAPI=0 link on DCCH */
2391 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2392
2393 /* MSC sends some data on (not yet established) SAPI=3 link */
2394 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2395 /* BSC attempts to establish a SAPI=3 link on DCCH */
2396 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2397
2398 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2399 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2400
2401 /* Clean up the connection */
2402 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2403 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2404
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002405 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002406}
2407
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002408testcase TC_si_default() runs on test_CT {
2409 f_init(0);
2410 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002411 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002412}
Harald Welte4003d112017-12-09 22:35:39 +01002413
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002414/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2415 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2416private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2417{
2418 select (earfcn_index) {
2419 case (0) {
2420 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2421 return 111;
2422 }
2423 case (1) {
2424 return 1;
2425 }
2426 case (2) {
2427 return 0;
2428 }
2429 case (3) {
2430 return 65535;
2431 }
2432 case else {
2433 return 23 * (earfcn_index - 3);
2434 }
2435 }
2436}
2437
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002438function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2439 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002440
2441 f_init(0);
2442
2443 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2444 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002445 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2446 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002447 }
2448
2449 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2450
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002451 if (not istemplatekind(expect_cells, "omit")) {
2452 /* Also check that RR Channel Release contains these EARFCNs.
2453 * (copied code from TC_chan_rel_hard_clear_csfb) */
2454 var BSSAP_N_DATA_ind rx_di;
2455 var DchanTuple dt;
2456
2457 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002458 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2459 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2460 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002461
2462 /* Instruct BSC to clear channel */
2463 var BssmapCause cause := 0;
2464 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2465
2466 /* expect Clear Complete from BSC on A */
2467 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2468 /* release the SCCP connection */
2469 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2470 }
2471
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002472 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 +02002473 }
2474
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002475 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002476 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 +02002477 }
2478}
2479
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002480private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2481{
2482 var template SI2quaterRestOctetsList si2quater := {};
2483 var integer si2quater_count := (count + 2) / 3;
2484
2485 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002486 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002487 var integer index := i / 3;
2488 var integer earfcn_index := i mod 3;
2489 if (index >= lengthof(si2quater)) {
2490 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2491 }
2492 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);
2493 }
2494
2495 return si2quater;
2496}
2497
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002498private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2499{
2500 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2501
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002502 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002503 for (var integer i := 0; i < count; i := i + 1) {
2504 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002505 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002506 }
2507
2508 return tr_CellSelIndValue_EUTRAN(cells);
2509}
2510
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002511private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2512{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002513 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002514 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002515 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2516 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002517}
2518
2519testcase TC_si2quater_2_earfcns() runs on test_CT {
2520 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002521 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002522}
2523
2524testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002525 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002526 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002527}
2528
2529testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002530 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002531 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002532}
2533
2534testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002535 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002536 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002537}
2538
2539testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002540 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002541 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002542}
2543
2544testcase TC_si2quater_12_earfcns() runs on test_CT {
2545 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002546 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002547}
2548
2549testcase TC_si2quater_23_earfcns() runs on test_CT {
2550 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002551 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002552}
2553
2554testcase TC_si2quater_32_earfcns() runs on test_CT {
2555 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002556 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002557}
2558
2559testcase TC_si2quater_33_earfcns() runs on test_CT {
2560 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002561 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002562}
2563
2564testcase TC_si2quater_42_earfcns() runs on test_CT {
2565 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002566 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002567}
2568
2569testcase TC_si2quater_48_earfcns() runs on test_CT {
2570 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002571 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002572}
2573
2574/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2575 * 48 EARFCNs. */
2576testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002577 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002578 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2579 f_init(0);
2580
2581 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002582 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2583 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002584 }
2585
2586 /* The 49th EARFCN no longer fits, expect VTY error */
2587 f_vty_enter_cfg_bts(BSCVTY, 0);
2588 var charstring vty_error;
2589 vty_error := f_vty_transceive_ret(BSCVTY,
2590 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2591 f_vty_transceive(BSCVTY, "end");
2592
2593 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2594 log("Got expected VTY error: ", vty_error);
2595 setverdict(pass);
2596 } else {
2597 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2598 }
2599
2600 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2601
2602 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002603 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 +02002604 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002605 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002606}
2607
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002608private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2609{
2610 var uint8_t count := 0;
2611 for (var integer i := 5; i < 16; i := i + 1) {
2612 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2613 count := count + 1;
2614 }
2615 }
2616 return count;
2617}
2618
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002619private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2620{
2621 var ASP_RSL_Unitdata rx_rsl_ud;
2622 var SystemInformationType1 last_si1;
2623
2624 timer T := 30.0;
2625 T.start;
2626 alt {
2627 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2628 tr_RSL_BCCH_INFO,
2629 tr_RSL_NO_SACCH_FILL,
2630 tr_RSL_SACCH_FILL))
2631 ) -> value rx_rsl_ud {
2632 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2633 if (g_system_information[rsl_idx].si1 == omit) {
2634 repeat;
2635 }
2636 last_si1 := g_system_information[rsl_idx].si1;
2637 g_system_information[rsl_idx].si1 := omit;
2638 T.stop;
2639 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002640 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002641 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2642 }
2643 return last_si1;
2644}
2645
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002646/* verify ACC rotate feature */
2647testcase TC_si_acc_rotate() runs on test_CT {
2648 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002649 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002650 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002651 var uint8_t count;
2652 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2653
2654 f_init(0, guard_timeout := 60.0);
2655
2656 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2657 "access-control-class-rotate 3",
2658 "access-control-class-rotate-quantum 1"});
2659
2660 /* Init and get first sysinfo */
2661 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2662
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002663 for (var integer i:= 0; i < 20; i := i + 1) {
2664 last_si1 := f_recv_next_si1(0);
2665 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002666 count := f_acc09_count_allowed(acc);
2667 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2668
2669 if (count != 3) {
2670 log("RSL: EXPECTED SI ACC len=3");
2671 setverdict(fail, "received SI does not match expectations");
2672 break;
2673 }
2674
2675 for (var integer j := 0; j < 10; j := j + 1) {
2676 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2677 times_allowed[j] := times_allowed[j] + 1;
2678 }
2679 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002680 }
2681
2682 for (var integer j := 0; j < 10; j := j + 1) {
2683 log("ACC", j, " allowed ", times_allowed[j], " times" );
2684 if (j != 5 and times_allowed[j] < 3) {
2685 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2686 } else if (j == 5 and times_allowed[j] > 0) {
2687 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2688 }
2689 }
2690
2691 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2692 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002693 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002694}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002695
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002696/* verify ACC startup ramp+rotate feature */
2697testcase TC_si_acc_ramp_rotate() runs on test_CT {
2698 var template SystemInformationConfig sic := SystemInformationConfig_default;
2699 var SystemInformationType1 last_si1;
2700 var AccessControlClass acc;
2701 var ASP_RSL_Unitdata rx_rsl_ud;
2702 var uint8_t count;
2703 var uint8_t prev_count;
2704 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2705
2706 f_init(0, guard_timeout := 80.0);
2707
2708 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2709 "access-control-class-rotate 0",
2710 "access-control-class-rotate-quantum 1",
2711 "access-control-class-ramping",
2712 "access-control-class-ramping-step-interval 5",
2713 "access-control-class-ramping-step-size 5"});
2714
2715 /* Init and get first sysinfo */
2716 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2717 last_si1 := g_system_information[0].si1;
2718 acc := last_si1.rach_control.acc;
2719 count := f_acc09_count_allowed(acc);
2720 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2721 while (count > 0) {
2722 last_si1 := f_recv_next_si1(0);
2723 acc := last_si1.rach_control.acc;
2724 count := f_acc09_count_allowed(acc);
2725 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2726 }
2727
2728 /* Increase adm subset size, we should see ramping start up */
2729 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2730 prev_count := 0;
2731 while (true) {
2732 last_si1 := f_recv_next_si1(0);
2733 acc := last_si1.rach_control.acc;
2734 count := f_acc09_count_allowed(acc);
2735 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2736
2737 if (prev_count > count) {
2738 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2739 break;
2740 }
2741
2742 if (count == 9) {
2743 break; /* Maximum reached (10 - 1 perm barred), done here */
2744 }
2745
2746 prev_count := count;
2747 }
2748
2749 setverdict(pass);
2750
2751 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2752 "rach access-control-class 4 allowed",
2753 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002754 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002755}
2756
Harald Welte4003d112017-12-09 22:35:39 +01002757testcase TC_ctrl_msc_connection_status() runs on test_CT {
2758 var charstring ctrl_resp;
2759
Harald Welte89d42e82017-12-17 16:42:41 +01002760 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002761
2762 /* See https://osmocom.org/issues/2729 */
2763 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002764 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002765}
2766
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002767testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2768 var charstring ctrl_resp;
2769
2770 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002771
2772 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002773 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002774}
2775
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002776/* Verify correct stats on the number of configured and connected MSCs */
2777private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2778 g_pars := f_gen_test_hdlr_pars();
2779 var StatsDExpects expect := {
2780 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2781 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2782 };
2783 f_statsd_expect(expect);
2784}
2785
2786private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2787{
2788 var MSC_ConnHdlr vc_conn;
2789
2790 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2791 f_sleep(1.0);
2792 vc_conn := f_start_handler(tc_fn);
2793 vc_conn.done;
2794
2795 /* Also verify stat exposed on CTRL interface */
2796 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2797 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2798
2799 f_shutdown_helper();
2800}
2801
2802/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2803private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2804 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2805}
2806testcase TC_stat_num_msc_connected_1() runs on test_CT {
2807 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2808}
2809
2810/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2811private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2812 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2813}
2814testcase TC_stat_num_msc_connected_2() runs on test_CT {
2815 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2816}
2817
2818/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2819private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2820 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2821}
2822testcase TC_stat_num_msc_connected_3() runs on test_CT {
2823 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2824}
2825
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002826/* Verify correct stats on the number of configured and connected MSCs */
2827private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
2828 g_pars := f_gen_test_hdlr_pars();
2829 var StatsDExpects expect := {
2830 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
2831 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2832 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
2833 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2834 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
2835 };
2836 f_statsd_expect(expect);
2837}
2838
2839private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
2840 var MSC_ConnHdlr vc_conn;
2841
2842 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
2843 f_sleep(1.0);
2844 vc_conn := f_start_handler(tc_fn);
2845 vc_conn.done;
2846
2847 /* Also verify stat exposed on CTRL interface */
2848 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
2849 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
2850 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
2851 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
2852
Neels Hofmeyra41ae302021-09-06 22:06:02 +02002853 /* Verify rf_states exposed on CTRL interface */
2854 var charstring expect_net_rf_states := "";
2855 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
2856 var charstring expect_bts_rf_states := int2str(i) & ",0,";
2857 if (i < NUM_BTS) {
2858 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
2859 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
2860 } else {
2861 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
2862 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
2863 }
2864 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
2865 expect_bts_rf_states := expect_bts_rf_states & "on,";
2866 if (i < nr_bts) {
2867 /* For BTS where RSL is connected, the RSL state will be "up" */
2868 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
2869 } else {
2870 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
2871 }
2872
2873 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
2874 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
2875 }
2876 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
2877
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002878 f_shutdown_helper();
2879}
2880
2881/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
2882private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
2883 f_tc_stat_num_bts_connected_msc_connhdlr(1);
2884}
2885testcase TC_stat_num_bts_connected_1() runs on test_CT {
2886 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
2887}
2888
2889/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
2890private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
2891 f_tc_stat_num_bts_connected_msc_connhdlr(2);
2892}
2893testcase TC_stat_num_bts_connected_2() runs on test_CT {
2894 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
2895}
2896
2897/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
2898private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
2899 f_tc_stat_num_bts_connected_msc_connhdlr(3);
2900}
2901testcase TC_stat_num_bts_connected_3() runs on test_CT {
2902 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
2903}
2904
Harald Welte4003d112017-12-09 22:35:39 +01002905testcase TC_ctrl() runs on test_CT {
2906 var charstring ctrl_resp;
2907
Harald Welte89d42e82017-12-17 16:42:41 +01002908 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002909
2910 /* all below values must match the osmo-bsc.cfg config file used */
2911
Harald Welte6a129692018-03-17 17:30:14 +01002912 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2913 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002914 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002915
2916 var integer bts_nr := 0;
2917 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2918 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2919 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2920 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2921 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2922 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2923 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2924
2925 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2926 f_sleep(2.0);
2927 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2928 setverdict(fail, "oml-uptime not incrementing as expected");
2929 }
2930 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2931
2932 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2933
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002934 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002935}
2936
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002937/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2938 "location-state" over the SCCPlite IPA conn */
2939testcase TC_ctrl_location() runs on test_CT {
2940 var MSC_ConnHdlr vc_conn;
2941 var integer bts_nr := 0;
2942
2943 f_init(1, true);
2944 f_sleep(1.0);
2945
2946 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2947 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2948 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2949
2950 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2951 f_sleep(2.0);
2952
2953 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2954 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2955 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
2956
2957 /* should match the one from config */
2958 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
2959
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002960 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002961}
2962
Harald Welte6f521d82017-12-11 19:52:02 +01002963
2964/***********************************************************************
2965 * Paging Testing
2966 ***********************************************************************/
2967
2968type record Cell_Identity {
2969 GsmMcc mcc,
2970 GsmMnc mnc,
2971 GsmLac lac,
2972 GsmCellId ci
2973};
Harald Welte24135bd2018-03-17 19:27:53 +01002974private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01002975private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01002976
Harald Welte5d1a2202017-12-13 19:51:29 +01002977type set of integer BtsIdList;
2978
2979private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
2980 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
2981 if (bts_id == bts_ids[j]) {
2982 return true;
2983 }
2984 }
2985 return false;
2986}
Harald Welte6f521d82017-12-11 19:52:02 +01002987
2988/* core paging test helper function; used by most paging test cases */
2989private function f_pageing_helper(hexstring imsi,
2990 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01002991 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01002992 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002993 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01002994{
2995 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002996 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01002997 var RSL_Message rx_rsl;
2998 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01002999 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003000
3001 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003002
3003 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003004 for (i := 0; i < NUM_BTS; i := i + 1) {
3005 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003006 }
Harald Welte6f521d82017-12-11 19:52:02 +01003007
3008 if (isvalue(rsl_chneed)) {
3009 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3010 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3011 } else {
3012 bssmap_chneed := omit;
3013 }
3014
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003015 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3016 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003017
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003018 if (not istemplatekind(tmsi, "omit")) {
3019 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003020 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003021 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003022 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003023
Harald Welte5d1a2202017-12-13 19:51:29 +01003024 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003025 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003026 /* check channel type, paging group */
3027 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3028 setverdict(fail, "Paging for wrong paging group");
3029 }
3030 if (ispresent(rsl_chneed) and
3031 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3032 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3033 }
Harald Welte6f521d82017-12-11 19:52:02 +01003034 }
Harald Welte2fccd982018-01-31 15:48:19 +01003035 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003036 /* do a quick check on all not-included BTSs if they received paging */
3037 for (i := 0; i < NUM_BTS; i := i + 1) {
3038 timer T := 0.1;
3039 if (f_bts_in_list(i, bts_ids)) {
3040 continue;
3041 }
3042 T.start;
3043 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003044 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003045 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3046 }
3047 [] IPA_RSL[i].receive { repeat; }
3048 [] T.timeout { }
3049 }
Harald Welte6f521d82017-12-11 19:52:02 +01003050 }
3051
3052 setverdict(pass);
3053}
3054
Harald Welte5d1a2202017-12-13 19:51:29 +01003055const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003056const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003057const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3058const BtsIdList c_BtsId_LAC2 := { 2 };
3059
Harald Welte6f521d82017-12-11 19:52:02 +01003060/* PAGING by IMSI + TMSI */
3061testcase TC_paging_imsi_nochan() runs on test_CT {
3062 var BSSMAP_FIELD_CellIdentificationList cid_list;
3063 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003064 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003065 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003066}
3067
3068/* PAGING by IMSI + TMSI */
3069testcase TC_paging_tmsi_nochan() runs on test_CT {
3070 var BSSMAP_FIELD_CellIdentificationList cid_list;
3071 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003072 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003073 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003074}
3075
3076/* Paging with different "channel needed' values */
3077testcase TC_paging_tmsi_any() runs on test_CT {
3078 var BSSMAP_FIELD_CellIdentificationList cid_list;
3079 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003080 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003081 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003082}
3083testcase TC_paging_tmsi_sdcch() runs on test_CT {
3084 var BSSMAP_FIELD_CellIdentificationList cid_list;
3085 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003086 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003087 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003088}
3089testcase TC_paging_tmsi_tch_f() runs on test_CT {
3090 var BSSMAP_FIELD_CellIdentificationList cid_list;
3091 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003092 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003093 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003094}
3095testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3096 var BSSMAP_FIELD_CellIdentificationList cid_list;
3097 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003098 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003099 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003100}
3101
3102/* Paging by CGI */
3103testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3104 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3105 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003106 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003107 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003108}
3109
3110/* Paging by LAC+CI */
3111testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3112 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3113 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003114 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003115 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003116}
3117
3118/* Paging by CI */
3119testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3120 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3121 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003122 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003123 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003124}
3125
3126/* Paging by LAI */
3127testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3128 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3129 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003130 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003131 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003132}
3133
3134/* Paging by LAC */
3135testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3136 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3137 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003138 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003139 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003140}
3141
3142/* Paging by "all in BSS" */
3143testcase TC_paging_imsi_nochan_all() runs on test_CT {
3144 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3145 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003146 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003147 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003148}
3149
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003150/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003151testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3152 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3153 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 +01003154 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003155 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003156}
Harald Welte6f521d82017-12-11 19:52:02 +01003157
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003158/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003159testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3160 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3161 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003162 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003163 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003164}
3165
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003166/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003167testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3168 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3169 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003170 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003171 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003172}
3173
Harald Welte6f521d82017-12-11 19:52:02 +01003174/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003175testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3176 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3177 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3178 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003179 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003180}
3181
3182/* Paging on empty list: Verify none of them page */
3183testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3184 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3185 cid_list := { cIl_LAC := { } };
3186 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003187 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003188}
3189
Stefan Sperling049a86e2018-03-20 15:51:00 +01003190/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3191testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3192 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3193 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3194 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3195 f_shutdown_helper();
3196}
3197
Harald Welte6f521d82017-12-11 19:52:02 +01003198/* Verify paging retransmission interval + count */
3199/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003200/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003201
Harald Weltee65d40e2017-12-13 00:09:06 +01003202/* Verify PCH load */
3203testcase TC_paging_imsi_load() runs on test_CT {
3204 var BSSMAP_FIELD_CellIdentificationList cid_list;
3205 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003206 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003207 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003208 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003209
3210 /* tell BSC there is no paging space anymore */
3211 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003212 f_sleep(0.2);
3213 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003214
3215 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3216 * there would be 8 retransmissions during 4 seconds */
3217 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003218 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003219 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003220 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003221 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003222 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003223 }
Harald Welte2caa1062018-03-17 18:19:05 +01003224 [] T_retrans.timeout {
3225 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3226 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3227 T_retrans.start;
3228 repeat;
3229 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003230 [] T.timeout {
3231 setverdict(pass);
3232 }
3233 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003234
3235 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003236}
3237
Harald Welte235ebf12017-12-15 14:18:16 +01003238/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003239testcase TC_paging_counter() runs on test_CT {
3240 var BSSMAP_FIELD_CellIdentificationList cid_list;
3241 timer T := 4.0;
3242 var integer i;
3243 var integer paging_attempted_bsc;
3244 var integer paging_attempted_bts[NUM_BTS];
3245 var integer paging_expired_bts[NUM_BTS];
3246 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3247
3248 f_init();
3249
3250 /* read counters before paging */
3251 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3252 for (i := 0; i < NUM_BTS; i := i+1) {
3253 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3254 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3255 }
3256
3257 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3258
3259 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3260 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3261 for (i := 0; i < NUM_BTS; i := i+1) {
3262 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3263 paging_attempted_bts[i]+1);
3264 }
3265
3266 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3267 f_sleep(12.0);
3268 for (i := 0; i < NUM_BTS; i := i+1) {
3269 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3270 paging_expired_bts[i]+1);
3271 }
Harald Welte1ff69992017-12-14 12:31:17 +01003272
Philipp Maier282ca4b2018-02-27 17:17:00 +01003273 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003274}
3275
3276
Harald Welte10985002017-12-12 09:29:15 +01003277/* Verify paging stops after A-RESET */
3278testcase TC_paging_imsi_a_reset() runs on test_CT {
3279 var BSSMAP_FIELD_CellIdentificationList cid_list;
3280 timer T := 3.0;
3281 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003282 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003283
3284 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003285 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 +01003286 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003287 [] 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 +01003288 [] BSSAP.receive { repeat; }
3289 }
3290
Daniel Willmanncbef3982018-07-30 09:22:40 +02003291 /* Wait to avoid a possible race condition if a paging message is
3292 * received right before the reset ACK. */
3293 f_sleep(0.2);
3294
Harald Welte10985002017-12-12 09:29:15 +01003295 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003296 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3297 IPA_RSL[i].clear;
3298 }
Harald Welte10985002017-12-12 09:29:15 +01003299
3300 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3301 T.start;
3302 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003303 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003304 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003305 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003306 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003307 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003308 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003309 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003310 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003311 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003312 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003313 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003314 }
Harald Welte10985002017-12-12 09:29:15 +01003315 [] T.timeout {
3316 setverdict(pass);
3317 }
3318 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003319
3320 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003321}
Harald Welteae026692017-12-09 01:03:01 +01003322
Philipp Maierf45824a2019-08-14 14:44:10 +02003323/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3324 * paging response we can not know which MSC is in charge, so we will blindly
3325 * pick the first configured MSC. This behavior is required in order to make
3326 * MT-CSFB calls working because in those cases the BSC can not know that the
3327 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3328 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003329 */
3330testcase TC_paging_resp_unsol() runs on test_CT {
3331
3332 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003333 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003334
3335 var BSSAP_N_CONNECT_ind rx_c_ind;
3336 var DchanTuple dt;
3337 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003338 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003339
3340 /* Send CHAN RQD and wait for allocation; acknowledge it */
3341 dt.rsl_chan_nr := f_chreq_act_ack();
3342
3343 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3344 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3345
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003346
Philipp Maierf45824a2019-08-14 14:44:10 +02003347 /* Expevct a CR with a matching Paging response on the A-Interface */
3348 T.start;
3349 alt {
3350 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3351 setverdict(pass);
3352 }
3353 [] BSSAP.receive {
3354 setverdict(fail, "Received unexpected message on A-Interface!");
3355 }
3356 [] T.timeout {
3357 setverdict(fail, "Received nothing on A-Interface!");
3358 }
3359 }
3360
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003361 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003362}
3363
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003364/* Test RSL link drop causes counter increment */
3365testcase TC_rsl_drop_counter() runs on test_CT {
3366 var integer rsl_fail;
3367
Harald Welte89d42e82017-12-17 16:42:41 +01003368 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003369
3370 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3371
3372 bts[0].rsl.vc_IPA.stop;
3373
3374 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3375
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003376 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003377}
3378
3379/* TODO: Test OML link drop causes counter increment */
3380
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003381/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3382function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3383 timer T := 10.0;
3384
3385 bts[0].rsl.id := "IPA-0-RSL";
3386 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3387 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3388 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003389 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003390
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003391 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003392
3393 f_init_mgcp("VirtMSC");
3394
3395 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3396 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3397 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3398 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3399
3400 /* wait for IPA OML link to connect and then disconnect */
3401 T.start;
3402 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003403 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003404 T.stop;
3405 return true;
3406 }
3407 [] IPA_RSL[0].receive { repeat }
3408 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003409 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003410 }
3411 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003412 return false;
3413}
3414
3415/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3416testcase TC_rsl_unknown_unit_id() runs on test_CT {
3417 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3418 setverdict(pass);
3419 } else {
3420 setverdict(fail, "Timeout RSL waiting for connection to close");
3421 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003422 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003423}
3424
3425
3426/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3427testcase TC_oml_unknown_unit_id() runs on test_CT {
3428 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3429 setverdict(pass);
3430 } else {
3431 setverdict(fail, "Timeout OML waiting for connection to close");
3432 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003433 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003434}
3435
3436
Harald Weltec1a2fff2017-12-17 11:06:19 +01003437/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003438 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003439 ***********************************************************************/
3440
Harald Welte6811d102019-04-14 22:23:14 +02003441import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003442import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003443import from RSL_Emulation all;
3444import from MSC_ConnectionHandler all;
3445
3446type function void_fn(charstring id) runs on MSC_ConnHdlr;
3447
Harald Welte336820c2018-05-31 20:34:52 +02003448/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003449private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3450 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003451 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003452 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003453 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003454 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003455 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3456 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3457 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003458 if (isvalue(bts[2])) {
3459 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3460 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3461 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003462 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003463 if (mp_enable_lcs_tests) {
3464 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3465 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3466 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003467 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003468 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003469 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003470}
3471
Neels Hofmeyrda436782021-07-20 22:09:06 +02003472function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003473runs on test_CT return MSC_ConnHdlr {
3474 var charstring id := testcasename();
3475 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003476 var integer bssap_idx := 0;
3477 if (isvalue(pars)) {
3478 bssap_idx := valueof(pars).mscpool.bssap_idx;
3479 }
Harald Welte336820c2018-05-31 20:34:52 +02003480 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003481 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003482 return vc_conn;
3483}
3484
3485function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3486runs on test_CT return MSC_ConnHdlr {
3487 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003488 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003489 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003490 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003491 return vc_conn;
3492}
3493
Neels Hofmeyrda436782021-07-20 22:09:06 +02003494function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3495runs on test_CT return MSC_ConnHdlr {
3496 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3497}
3498
Harald Weltea0630032018-03-20 21:09:55 +01003499/* first function inside ConnHdlr component; sets g_pars + starts function */
3500private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3501runs on MSC_ConnHdlr {
3502 if (isvalue(pars)) {
3503 g_pars := valueof(pars);
3504 }
3505 fn.apply(id);
3506}
3507
Oliver Smith26a3db72021-07-09 13:51:29 +02003508private function f_vty_encryption_a5(charstring options) runs on test_CT {
3509 f_vty_transceive(BSCVTY, "configure terminal");
3510 f_vty_transceive(BSCVTY, "network");
3511 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3512 f_vty_transceive(BSCVTY, "exit");
3513 f_vty_transceive(BSCVTY, "exit");
3514}
3515
3516private function f_vty_encryption_a5_reset() runs on test_CT {
3517 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3518 f_vty_encryption_a5("0 1 3");
3519}
3520
Harald Welte3c86ea02018-05-10 22:28:05 +02003521/* Establish signalling channel (non-assignment case) followed by cipher mode */
3522private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003523 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3524 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003525 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003526 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3527 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3528 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3529 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003530
Philipp Maier23000732018-05-18 11:25:37 +02003531 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003532}
3533testcase TC_ciph_mode_a5_0() runs on test_CT {
3534 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003535 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003536 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3537
3538 f_init(1, true);
3539 f_sleep(1.0);
3540 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3541 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003542 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003543}
3544testcase TC_ciph_mode_a5_1() runs on test_CT {
3545 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003546 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003547 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3548
3549 f_init(1, true);
3550 f_sleep(1.0);
3551 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3552 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003553 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003554}
Oliver Smith50b98122021-07-09 15:00:28 +02003555/* OS#4975: verify that A5/2 is preferred over A5/0 */
3556testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3557 var MSC_ConnHdlr vc_conn;
3558 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3559
3560 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3561 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3562
3563 f_init(1, true);
3564 f_vty_encryption_a5("0 1 2 3");
3565 f_sleep(1.0);
3566 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3567 vc_conn.done;
3568 f_vty_encryption_a5_reset();
3569 f_shutdown_helper();
3570}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003571/* OS#4975: verify that A5/1 is preferred over A5/2 */
3572testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3573 var MSC_ConnHdlr vc_conn;
3574 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3575
3576 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3577 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3578
3579 f_init(1, true);
3580 f_vty_encryption_a5("1 2");
3581 f_sleep(1.0);
3582 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3583 vc_conn.done;
3584 f_vty_encryption_a5_reset();
3585 f_shutdown_helper();
3586}
Harald Welte3c86ea02018-05-10 22:28:05 +02003587testcase TC_ciph_mode_a5_3() runs on test_CT {
3588 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003589 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003590 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3591
3592 f_init(1, true);
3593 f_sleep(1.0);
3594 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3595 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003596 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003597}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003598/* Establish a Signalling channel with A5/4 encryption. */
3599testcase TC_ciph_mode_a5_4() runs on test_CT {
3600 var MSC_ConnHdlr vc_conn;
3601 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3602 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003603
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003604 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003605 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003606 f_sleep(1.0);
3607 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3608 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003609 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003610 f_shutdown_helper();
3611}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003612/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3613private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3614 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3615 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3616 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3617 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3618
3619 f_establish_fully(ass_cmd, exp_compl);
3620}
3621testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3622 var MSC_ConnHdlr vc_conn;
3623 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3624
3625 f_init(1, true);
3626 f_sleep(1.0);
3627 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3628 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003629 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003630}
3631
Harald Welte3c86ea02018-05-10 22:28:05 +02003632
3633/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003634private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003635 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3636 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003637
Harald Welte552620d2017-12-16 23:21:36 +01003638 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3639 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003640
Harald Weltea0630032018-03-20 21:09:55 +01003641 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003642}
Harald Welte552620d2017-12-16 23:21:36 +01003643testcase TC_assignment_fr_a5_0() runs on test_CT {
3644 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003645 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003646 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003647
Harald Welte89d42e82017-12-17 16:42:41 +01003648 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003649 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003650 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003651 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003652 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003653}
Harald Welte552620d2017-12-16 23:21:36 +01003654testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003655 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003656 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003657 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003658
Harald Welte89d42e82017-12-17 16:42:41 +01003659 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003660 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003661 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3662 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003663 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003664}
3665testcase TC_assignment_fr_a5_3() runs on test_CT {
3666 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003667 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003668 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003669
Harald Welte651fcdc2018-05-10 20:23:16 +02003670 f_init(1, true);
3671 f_sleep(1.0);
3672 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003673 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003674 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003675}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003676/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3677testcase TC_assignment_fr_a5_4() runs on test_CT {
3678 var MSC_ConnHdlr vc_conn;
3679 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3680 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3681
3682 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003683 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003684 f_sleep(1.0);
3685 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3686 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003687 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003688 f_shutdown_helper();
3689}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003690
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003691/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3692testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3693 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3694 var MSC_ConnHdlr vc_conn;
3695
3696 f_init(1, true);
3697 f_sleep(1.0);
3698
3699 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3700 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3701 vc_conn.done;
3702 f_shutdown_helper();
3703}
3704
Harald Welte552620d2017-12-16 23:21:36 +01003705/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3706private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003707 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003708 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003709 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003710
3711 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003712 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3713
Harald Weltea0630032018-03-20 21:09:55 +01003714 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003715}
Harald Welte552620d2017-12-16 23:21:36 +01003716testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3717 var MSC_ConnHdlr vc_conn;
3718
Harald Welte89d42e82017-12-17 16:42:41 +01003719 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003720 f_sleep(1.0);
3721
Harald Welte8863fa12018-05-10 20:15:27 +02003722 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003723 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003724 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003725}
3726
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003727private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3728 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3729 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003730
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003731 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3732 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3733
3734 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3735
3736 var BSSMAP_FIELD_CodecType codecType;
3737 timer T := 10.0;
3738
3739 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3740 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3741
3742 f_create_chan_and_exp();
3743 /* we should now have a COMPL_L3 at the MSC */
3744
3745 var template PDU_BSSAP exp_l3_compl;
3746 exp_l3_compl := tr_BSSMAP_ComplL3()
3747 if (g_pars.aoip == false) {
3748 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3749 } else {
3750 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3751 }
3752 T.start;
3753 alt {
3754 [] BSSAP.receive(exp_l3_compl);
3755 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3756 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3757 }
3758 [] T.timeout {
3759 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3760 }
3761 }
3762
3763 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003764 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003765}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003766testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3767 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003768 var MSC_ConnHdlr vc_conn;
3769
Harald Welte89d42e82017-12-17 16:42:41 +01003770 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003771 f_sleep(1.0);
3772
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003773 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003774 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003775 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003776 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003777}
3778
3779
Harald Welte4532e0a2017-12-23 02:05:44 +01003780private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003781 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003782 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003783 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003784 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003785
3786 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003787 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003788
3789 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003790 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3791 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003792 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3793 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3794 };
3795 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003796}
3797
3798testcase TC_assignment_sign() runs on test_CT {
3799 var MSC_ConnHdlr vc_conn;
3800
3801 f_init(1, true);
3802 f_sleep(1.0);
3803
Harald Welte8863fa12018-05-10 20:15:27 +02003804 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003805 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003806 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003807}
3808
Harald Welte60aa5762018-03-21 19:33:13 +01003809/***********************************************************************
3810 * Codec (list) testing
3811 ***********************************************************************/
3812
3813/* check if the given rsl_mode is compatible with the a_elem */
3814private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3815return boolean {
3816 select (a_elem.codecType) {
3817 case (GSM_FR) {
3818 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3819 return true;
3820 }
3821 }
3822 case (GSM_HR) {
3823 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3824 return true;
3825 }
3826 }
3827 case (GSM_EFR) {
3828 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3829 return true;
3830 }
3831 }
3832 case (FR_AMR) {
3833 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3834 return true;
3835 }
3836 }
3837 case (HR_AMR) {
3838 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3839 return true;
3840 }
3841 }
3842 case else { }
3843 }
3844 return false;
3845}
3846
3847/* check if the given rsl_mode is compatible with the a_list */
3848private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3849return boolean {
3850 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3851 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3852 return true;
3853 }
3854 }
3855 return false;
3856}
3857
3858/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003859function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003860return BSSMAP_IE_ChannelType {
3861 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3862 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3863 select (a_elem.codecType) {
3864 case (GSM_FR) {
3865 ret.channelRateAndType := ChRate_TCHF;
3866 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3867 }
3868 case (GSM_HR) {
3869 ret.channelRateAndType := ChRate_TCHH;
3870 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3871 }
3872 case (GSM_EFR) {
3873 ret.channelRateAndType := ChRate_TCHF;
3874 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3875 }
3876 case (FR_AMR) {
3877 ret.channelRateAndType := ChRate_TCHF;
3878 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3879 }
3880 case (HR_AMR) {
3881 ret.channelRateAndType := ChRate_TCHH;
3882 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3883 }
3884 case else {
3885 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003886 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003887 }
3888 }
3889 return ret;
3890}
3891
Harald Weltea63b9102018-03-22 20:36:16 +01003892private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3893return template RSL_IE_Body {
3894 var template RSL_IE_Body mode_ie := {
3895 chan_mode := {
3896 len := ?,
3897 reserved := ?,
3898 dtx_d := ?,
3899 dtx_u := ?,
3900 spd_ind := RSL_SPDI_SPEECH,
3901 ch_rate_type := -,
3902 coding_alg_rate := -
3903 }
3904 }
3905
3906 select (a_elem.codecType) {
3907 case (GSM_FR) {
3908 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3909 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3910 }
3911 case (GSM_HR) {
3912 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3913 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3914 }
3915 case (GSM_EFR) {
3916 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3917 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3918 }
3919 case (FR_AMR) {
3920 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3921 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3922 }
3923 case (HR_AMR) {
3924 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3925 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3926 }
3927 }
3928 return mode_ie;
3929}
3930
Harald Welte60aa5762018-03-21 19:33:13 +01003931type record CodecListTest {
3932 BSSMAP_IE_SpeechCodecList codec_list,
3933 charstring id
3934}
3935type record of CodecListTest CodecListTests
3936
3937private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003938 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3939 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003940
3941 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003942 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003943 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3944 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3945 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003946 if (isvalue(g_pars.expect_mr_s0_s7)) {
3947 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3948 g_pars.expect_mr_s0_s7;
3949 }
Harald Welte79f3f542018-05-25 20:02:37 +02003950 }
Harald Welte60aa5762018-03-21 19:33:13 +01003951 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3952 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003953 log("expecting ASS COMPL like this: ", exp_compl);
3954
3955 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01003956
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003957 if (not g_pars.expect_channel_mode_modify) {
3958 /* Verify that the RSL-side activation actually matches our expectations */
3959 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01003960
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003961 var RSL_IE_Body mode_ie;
3962 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
3963 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02003964 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003965 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003966 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
3967 if (not match(mode_ie, t_mode_ie)) {
3968 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
3969 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003970 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003971
3972 var RSL_IE_Body mr_conf;
3973 if (g_pars.expect_mr_conf_ie != omit) {
3974 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
3975 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
3976 mtc.stop;
3977 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003978 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003979
3980 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
3981 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
3982 g_pars.expect_mr_conf_ie);
3983 }
3984 } else {
3985 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
3986 log("found RSL MR CONFIG IE: ", mr_conf);
3987 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
3988 mtc.stop;
3989 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003990 }
3991 }
Harald Welte60aa5762018-03-21 19:33:13 +01003992}
3993
Philipp Maierd0e64b02019-03-13 14:15:23 +01003994private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
3995
3996 var PDU_BSSAP ass_cmd := f_gen_ass_req();
3997 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
3998
3999 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004000 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004001 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4002 }
4003 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4004 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4005 log("expecting ASS FAIL like this: ", exp_fail);
4006
4007 f_establish_fully(ass_cmd, exp_fail);
4008}
4009
Harald Welte60aa5762018-03-21 19:33:13 +01004010testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004011 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004012 var MSC_ConnHdlr vc_conn;
4013
4014 f_init(1, true);
4015 f_sleep(1.0);
4016
4017 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004018 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004019 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004020 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004021}
4022
4023testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004024 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004025 var MSC_ConnHdlr vc_conn;
4026
4027 f_init(1, true);
4028 f_sleep(1.0);
4029
4030 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004031 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004032 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004033 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004034}
4035
4036testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004037 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004038 var MSC_ConnHdlr vc_conn;
4039
4040 f_init(1, true);
4041 f_sleep(1.0);
4042
4043 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004044 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004045 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004046 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004047}
4048
Philipp Maierd0e64b02019-03-13 14:15:23 +01004049/* Allow 5,90k only (current default config) */
4050private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004051 f_vty_cfg_msc(BSCVTY, 0, {
4052 "amr-config 12_2k forbidden",
4053 "amr-config 10_2k forbidden",
4054 "amr-config 7_95k forbidden",
4055 "amr-config 7_40k forbidden",
4056 "amr-config 6_70k forbidden",
4057 "amr-config 5_90k allowed",
4058 "amr-config 5_15k forbidden",
4059 "amr-config 4_75k forbidden"
4060 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004061}
4062
4063/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4064 * ("Config-NB-Code = 1") */
4065private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004066 f_vty_cfg_msc(BSCVTY, 0, {
4067 "amr-config 12_2k allowed",
4068 "amr-config 10_2k forbidden",
4069 "amr-config 7_95k forbidden",
4070 "amr-config 7_40k allowed",
4071 "amr-config 6_70k forbidden",
4072 "amr-config 5_90k allowed",
4073 "amr-config 5_15k forbidden",
4074 "amr-config 4_75k allowed"
4075 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004076}
4077
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004078private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4079 var charstring tch;
4080 if (fr) {
4081 tch := "tch-f";
4082 } else {
4083 tch := "tch-h";
4084 }
4085 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4086}
4087
4088/* Set the AMR start-mode for this TCH back to the default configuration. */
4089private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4090 f_vty_amr_start_mode_set(fr, "auto");
4091}
4092
Harald Welte60aa5762018-03-21 19:33:13 +01004093testcase TC_assignment_codec_amr_f() 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;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004096
4097 /* Note: This setups the codec configuration. The parameter payload in
4098 * mr_conf must be consistant with the parameter codecElements in pars
4099 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004100 var RSL_IE_Body mr_conf := {
4101 other := {
4102 len := 2,
4103 payload := '2804'O
4104 }
4105 };
Harald Welte60aa5762018-03-21 19:33:13 +01004106
Philipp Maier7695a0d2018-09-27 17:52:14 +02004107 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004108 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004109 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4110 pars.expect_mr_conf_ie := mr_conf;
4111
Harald Welte60aa5762018-03-21 19:33:13 +01004112 f_init(1, true);
4113 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004114 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004115
Harald Welte8863fa12018-05-10 20:15:27 +02004116 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004117 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004118
4119 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004120 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004121}
4122
4123testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004124 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004125 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004126
4127 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004128 var RSL_IE_Body mr_conf := {
4129 other := {
4130 len := 2,
4131 payload := '2804'O
4132 }
4133 };
Harald Welte60aa5762018-03-21 19:33:13 +01004134
Philipp Maier7695a0d2018-09-27 17:52:14 +02004135 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004136 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004137 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4138 pars.expect_mr_conf_ie := mr_conf;
4139
Harald Welte60aa5762018-03-21 19:33:13 +01004140 f_init(1, true);
4141 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004142 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004143
Harald Welte8863fa12018-05-10 20:15:27 +02004144 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004145 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004146
4147 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004148 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004149}
4150
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004151/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4152testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4153 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4154 var MSC_ConnHdlr vc_conn;
4155
4156 f_init(1, true);
4157 f_sleep(1.0);
4158
4159 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4160 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4161 * expecting a Channel Mode Modify if the channel type is compatible. */
4162 f_disable_all_sdcch();
4163 f_disable_all_tch_h();
4164
4165 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4166 pars.expect_channel_mode_modify := true;
4167 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4168 vc_conn.done;
4169
4170 f_enable_all_sdcch();
4171 f_enable_all_tch();
4172 f_shutdown_helper();
4173}
4174
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004175/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4176testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4177 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4178 var MSC_ConnHdlr vc_conn;
4179
4180 var RSL_IE_Body mr_conf := {
4181 other := {
4182 len := 2,
4183 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4184 }
4185 };
4186
4187 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4188 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4189 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4190 pars.expect_mr_conf_ie := mr_conf;
4191
4192 f_init(1, true);
4193 f_sleep(1.0);
4194
4195 /* First set nonzero start mode bits */
4196 f_vty_amr_start_mode_set(true, "4");
4197 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4198 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4199 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4200 f_vty_amr_start_mode_set(true, "auto");
4201
4202 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4203 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004204
4205 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4206 f_vty_amr_start_mode_set(true, "1");
4207 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004208 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004209}
4210
Neels Hofmeyr21863562020-11-26 00:34:33 +00004211function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4212 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004213runs on test_CT {
4214
4215 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4216 var MSC_ConnHdlr vc_conn;
4217
4218 /* See note above */
4219 var RSL_IE_Body mr_conf := {
4220 other := {
4221 len := lengthof(mrconf),
4222 payload := mrconf
4223 }
4224 };
4225
4226 if (fr) {
4227 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4228 } else {
4229 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4230 }
4231 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4232 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4233 pars.expect_mr_conf_ie := mr_conf;
4234 pars.expect_mr_s0_s7 := exp_s8_s0;
4235
4236 f_init(1, true);
4237 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004238 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004239 f_sleep(1.0);
4240
4241 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4242 vc_conn.done;
4243 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004244 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004245}
4246
4247function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4248runs on test_CT {
4249
4250 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4251 var MSC_ConnHdlr vc_conn;
4252
4253 if (fr) {
4254 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4255 } else {
4256 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4257 }
4258 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4259 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4260
4261 f_init(1, true);
4262 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004263 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004264 f_sleep(1.0);
4265
4266 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4267 vc_conn.done;
4268 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004269 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004270}
4271
4272
4273/* Set S1, we expect an AMR multirate configuration IE with all four rates
4274 * set. */
4275testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004276 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004277 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004278}
4279
4280/* Set S1, we expect an AMR multirate configuration IE with the lower three
4281 * rates set. */
4282testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004283 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004284 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004285}
4286
4287/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4288 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4289testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004290 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004291 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004292}
4293
4294/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4295 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4296testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004297 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004298 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004299}
4300
4301/* The following block of tests selects more and more rates until all four
4302 * possible rates are in the active set (full rate) */
4303testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004304 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004305 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004306}
4307
4308testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004309 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004310 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004311}
4312
4313testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004314 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004315 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004316}
4317
4318testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004319 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004320 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004321}
4322
4323/* The following block of tests selects more and more rates until all three
4324 * possible rates are in the active set (half rate) */
4325testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004326 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004327 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004328}
4329
4330testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004331 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004332 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004333}
4334
4335testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004336 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004337 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004338}
4339
4340/* The following block tests what happens when the MSC does offer rate
4341 * configurations that are not supported by the BSC. Normally such situations
4342 * should not happen because the MSC gets informed by the BSC in advance via
4343 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4344 * to offer rates that are not applicable anyway. */
4345
4346testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004347 /* Try to include 12,2k in into the active set even though the channel
4348 * is half rate only. The BSC is expected to remove the 12,0k */
4349 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004350 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004351}
4352
4353testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004354 /* See what happens when all rates are selected at once. Since then
4355 * Also S1 is selected, this setting will be prefered and we should
4356 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4357 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004358 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004359}
4360
4361testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004362 /* Same as above, but with S1 missing, the MSC is then expected to
4363 * select the currently supported rates, which are also 12.2k, 7,40k,
4364 * 5,90k, and 4,75k, into the active set. */
4365 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004366 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004367}
4368
4369testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004370 /* Try to select no rates at all */
4371 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004372 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004373}
4374
4375testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004376 /* Try to select only unsupported rates */
4377 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004378 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004379}
4380
4381testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004382 /* Try to select 12,2k for half rate */
4383 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004384 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004385}
4386
Neels Hofmeyr21863562020-11-26 00:34:33 +00004387testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4388 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4389 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004390 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004391}
4392
4393testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4394 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4395 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004396 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004397}
4398
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004399testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004400 /* "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 +00004401 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4402 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004403 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004404}
4405
4406testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004407 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4408 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004409 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004410 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004411}
4412
Philipp Maierac09bfc2019-01-08 13:41:39 +01004413private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004414 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4415 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4416 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4417 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004418}
4419
4420private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004421 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4422 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004423}
4424
4425private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004426 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4427 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4428 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4429 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4430 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4431 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004432}
4433
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004434private function f_disable_all_sdcch() runs on test_CT {
4435 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4436 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4437 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4438 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4439}
4440
4441private function f_enable_all_sdcch() runs on test_CT {
4442 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4443 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4444 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4445 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4446}
4447
Philipp Maierac09bfc2019-01-08 13:41:39 +01004448/* Allow HR only */
4449private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4450 g_pars := f_gen_test_hdlr_pars();
4451 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4452 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4453 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4454 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4455 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4456 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4457 f_establish_fully(ass_cmd, exp_compl);
4458}
4459
4460/* Allow FR only */
4461private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4462 g_pars := f_gen_test_hdlr_pars();
4463 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4464 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4465 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4466 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4467 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4468 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4469 f_establish_fully(ass_cmd, exp_compl);
4470}
4471
4472/* Allow HR only (expect assignment failure) */
4473private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4474 g_pars := f_gen_test_hdlr_pars();
4475 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4476 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4477 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4478 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4479 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4480 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4481 f_establish_fully(ass_cmd, exp_fail);
4482}
4483
4484/* Allow FR only (expect assignment failure) */
4485private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4486 g_pars := f_gen_test_hdlr_pars();
4487 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4488 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4489 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4490 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4491 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4492 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4493 f_establish_fully(ass_cmd, exp_fail);
4494}
4495
4496/* Allow FR and HR, but prefer FR */
4497private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4498 g_pars := f_gen_test_hdlr_pars();
4499 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4500 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4501 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4502 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4503 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4504 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4505 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4506 f_establish_fully(ass_cmd, exp_compl);
4507}
4508
4509/* Allow FR and HR, but prefer HR */
4510private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4511 g_pars := f_gen_test_hdlr_pars();
4512 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4513 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4514 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4515 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4516 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4517 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4518 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4519 f_establish_fully(ass_cmd, exp_compl);
4520}
4521
4522/* Allow FR and HR, but prefer FR */
4523private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4524 g_pars := f_gen_test_hdlr_pars();
4525 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4526 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4527 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4528 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4529 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4530 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4531 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4532 f_establish_fully(ass_cmd, exp_compl);
4533}
4534
4535/* Allow FR and HR, but prefer HR */
4536private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4537 g_pars := f_gen_test_hdlr_pars();
4538 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4539 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4540 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4541 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4542 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4543 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4544 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4545 f_establish_fully(ass_cmd, exp_compl);
4546}
4547
4548/* Request a HR channel while all FR channels are exhausted, this is expected
4549 * to work without conflicts */
4550testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4551 var MSC_ConnHdlr vc_conn;
4552 f_init(1, true);
4553 f_sleep(1.0);
4554 f_enable_all_tch();
4555 f_disable_all_tch_f();
4556 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4557 vc_conn.done;
4558 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004559 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004560}
4561
4562/* Request a FR channel while all FR channels are exhausted, this is expected
4563 * to fail. */
4564testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4565 var MSC_ConnHdlr vc_conn;
4566 f_init(1, true);
4567 f_sleep(1.0);
4568 f_enable_all_tch();
4569 f_disable_all_tch_f();
4570 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4571 vc_conn.done;
4572 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004573 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004574}
4575
4576/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4577 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4578testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4579 var MSC_ConnHdlr vc_conn;
4580 f_init(1, true);
4581 f_sleep(1.0);
4582 f_enable_all_tch();
4583 f_disable_all_tch_f();
4584 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4585 vc_conn.done;
4586 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004587 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004588}
4589
4590/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4591 * are exhausted, this is expected to work without conflicts. */
4592testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4593 var MSC_ConnHdlr vc_conn;
4594 f_init(1, true);
4595 f_sleep(1.0);
4596 f_enable_all_tch();
4597 f_disable_all_tch_f();
4598 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4599 vc_conn.done;
4600 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004601 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004602}
4603
4604/* Request a FR channel while all HR channels are exhausted, this is expected
4605 * to work without conflicts */
4606testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4607 var MSC_ConnHdlr vc_conn;
4608 f_init(1, true);
4609 f_sleep(1.0);
4610 f_enable_all_tch();
4611 f_disable_all_tch_h();
4612 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4613 vc_conn.done;
4614 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004615 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004616}
4617
4618/* Request a HR channel while all HR channels are exhausted, this is expected
4619 * to fail. */
4620testcase TC_assignment_codec_hr_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_h();
4626 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
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 HR (prefered) or alternatively a FR channel while all HR channels
4633 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4634testcase TC_assignment_codec_hr_exhausted_req_hr_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_h();
4640 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
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 HR channels
4647 * are exhausted, this is expected to work without conflicts. */
4648testcase TC_assignment_codec_hr_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_h();
4654 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_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/* Allow FR and HR, but prefer HR */
4661private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4662 g_pars := f_gen_test_hdlr_pars();
4663 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4664 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4665 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4666 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4667 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4668 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4669 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4670 f_establish_fully(ass_cmd, exp_compl);
4671}
4672
4673/* Allow FR and HR, but prefer FR */
4674private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4675 g_pars := f_gen_test_hdlr_pars();
4676 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4677 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4678 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4679 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4680 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4681 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4682 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4683 f_establish_fully(ass_cmd, exp_compl);
4684}
4685
4686/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4687 * HR, which is the prefered type, is selected. */
4688testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4689 var MSC_ConnHdlr vc_conn;
4690 f_init(1, true);
4691 f_sleep(1.0);
4692 f_enable_all_tch();
4693 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4694 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004695 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004696}
4697
4698/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4699 * FR, which is the prefered type, is selected. */
4700testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4701 var MSC_ConnHdlr vc_conn;
4702 f_init(1, true);
4703 f_sleep(1.0);
4704 f_enable_all_tch();
4705 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4706 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004707 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004708}
4709
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004710/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4711private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4712 g_pars := f_gen_test_hdlr_pars();
4713 g_pars.ra := '02'O; /* RA containing reason=LU */
4714
4715 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4716 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4717 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4718 var template uint3_t tsc := ?;
4719
4720 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4721 f_create_bssmap_exp(l3_enc);
4722 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4723 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4724
4725 /* we should now have a COMPL_L3 at the MSC */
4726 timer T := 10.0;
4727 T.start;
4728 alt {
4729 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4730 [] T.timeout {
4731 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4732 }
4733 }
4734}
4735testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4736 var MSC_ConnHdlr vc_conn;
4737 f_init(1, true);
4738 f_sleep(1.0);
4739 f_disable_all_sdcch();
4740 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4741 vc_conn.done;
4742 f_enable_all_sdcch();
4743 f_shutdown_helper();
4744}
4745
4746/* Request a signalling channel with all SDCCH exhausted, it is
4747 expected that no TCH will be selected for signalling and assigment will fail
4748 because it's dictated by VTY config */
4749testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4750 var RSL_Message rsl_unused, rsl_msg;
4751 var GsmRrMessage rr;
4752 f_init(1, false);
4753 f_sleep(1.0);
4754 f_vty_allow_tch_for_signalling(false, 0);
4755 f_disable_all_sdcch();
4756
4757 /* RA containing reason=LU */
4758 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4759 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4760 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4761 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4762 setverdict(fail, "Expected reject");
4763 }
4764
4765 f_vty_allow_tch_for_signalling(true, 0);
4766 f_enable_all_sdcch();
4767 f_shutdown_helper();
4768}
4769
4770/* Request a voice channel with all SDCCH exhausted, it is
4771 * expected that TCH channel will be allocated since the VTY option is only
4772 * aimed at signalling requests */
4773private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4774 g_pars := f_gen_test_hdlr_pars();
4775 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4776
4777 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4778 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4779 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4780 var template uint3_t tsc := ?;
4781
4782 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4783 f_create_bssmap_exp(l3_enc);
4784 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4785 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4786
4787 /* we should now have a COMPL_L3 at the MSC */
4788 timer T := 10.0;
4789 T.start;
4790 alt {
4791 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4792 [] T.timeout {
4793 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4794 }
4795 }
4796}
4797testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4798 var MSC_ConnHdlr vc_conn;
4799 f_init(1, true);
4800 f_sleep(1.0);
4801 f_vty_allow_tch_for_signalling(false, 0);
4802 f_disable_all_sdcch();
4803
4804 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4805 vc_conn.done;
4806
4807 f_vty_allow_tch_for_signalling(true, 0);
4808 f_enable_all_sdcch();
4809 f_shutdown_helper();
4810}
4811
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004812testcase TC_assignment_osmux() runs on test_CT {
4813 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4814 var MSC_ConnHdlr vc_conn;
4815
4816 /* See note above */
4817 var RSL_IE_Body mr_conf := {
4818 other := {
4819 len := 2,
4820 payload := '2804'O
4821 }
4822 };
4823
4824 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4825 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4826 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4827 pars.expect_mr_conf_ie := mr_conf;
4828 pars.use_osmux := true;
4829
4830 f_init(1, true, true);
4831 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004832 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004833
4834 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4835 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004836
4837 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004838 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004839}
4840
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004841/* test the procedure of the MSC requesting a Classmark Update:
4842 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4843 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004844private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004845 g_pars := f_gen_test_hdlr_pars();
4846
Harald Weltea0630032018-03-20 21:09:55 +01004847 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004848 /* we should now have a COMPL_L3 at the MSC */
4849 BSSAP.receive(tr_BSSMAP_ComplL3);
4850
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004851 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4852 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4853
Harald Welte898113b2018-01-31 18:32:21 +01004854 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4855 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4856 setverdict(pass);
4857}
4858testcase TC_classmark() runs on test_CT {
4859 var MSC_ConnHdlr vc_conn;
4860 f_init(1, true);
4861 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004862 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004863 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004864 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004865}
4866
Harald Welteeddf0e92020-06-21 19:42:15 +02004867/* Send a CommonID from the simulated MSC and verify that the information is used to
4868 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4869private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4870 g_pars := f_gen_test_hdlr_pars();
4871 f_MscConnHdlr_init_vty();
4872
4873 f_create_chan_and_exp();
4874 /* we should now have a COMPL_L3 at the MSC */
4875 BSSAP.receive(tr_BSSMAP_ComplL3);
4876
4877 /* Send CommonID */
4878 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4879
4880 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4881 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4882 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4883
4884 setverdict(pass);
4885}
4886testcase TC_common_id() runs on test_CT {
4887 var MSC_ConnHdlr vc_conn;
4888 f_init(1, true);
4889 f_sleep(1.0);
4890 vc_conn := f_start_handler(refers(f_tc_common_id));
4891 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004892 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004893}
4894
Harald Weltee3bd6582018-01-31 22:51:25 +01004895private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004896 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004897 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004898 /* we should now have a COMPL_L3 at the MSC */
4899 BSSAP.receive(tr_BSSMAP_ComplL3);
4900
Harald Weltee3bd6582018-01-31 22:51:25 +01004901 /* send the single message we want to send */
4902 f_rsl_send_l3(l3);
4903}
4904
4905private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4906 timer T := sec;
4907 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004908 T.start;
4909 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004910 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4911 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004912 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004913 }
4914 [] T.timeout {
4915 setverdict(pass);
4916 }
4917 }
4918}
4919
Harald Weltee3bd6582018-01-31 22:51:25 +01004920/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4921private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4922 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4923 f_bssap_expect_nothing();
4924}
Harald Welte898113b2018-01-31 18:32:21 +01004925testcase TC_unsol_ass_fail() runs on test_CT {
4926 var MSC_ConnHdlr vc_conn;
4927 f_init(1, true);
4928 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004929 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004930 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004931 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004932}
Harald Welte552620d2017-12-16 23:21:36 +01004933
Harald Welteea99a002018-01-31 20:46:43 +01004934
4935/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4936private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004937 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4938 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004939}
4940testcase TC_unsol_ass_compl() runs on test_CT {
4941 var MSC_ConnHdlr vc_conn;
4942 f_init(1, true);
4943 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004944 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004945 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004946 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004947}
4948
4949
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004950/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4951private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004952 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4953 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004954}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004955testcase TC_unsol_ho_fail() runs on test_CT {
4956 var MSC_ConnHdlr vc_conn;
4957 f_init(1, true);
4958 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004959 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004960 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004961 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004962}
4963
4964
Harald Weltee3bd6582018-01-31 22:51:25 +01004965/* short message from MS should be ignored */
4966private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004967 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004968 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01004969 /* we should now have a COMPL_L3 at the MSC */
4970 BSSAP.receive(tr_BSSMAP_ComplL3);
4971
4972 /* send short message */
4973 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
4974 f_bssap_expect_nothing();
4975}
4976testcase TC_err_82_short_msg() runs on test_CT {
4977 var MSC_ConnHdlr vc_conn;
4978 f_init(1, true);
4979 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004980 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01004981 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004982 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01004983}
4984
4985
Harald Weltee9e02e42018-01-31 23:36:25 +01004986/* 24.008 8.4 Unknown message must trigger RR STATUS */
4987private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
4988 f_est_single_l3(ts_RRM_UL_REL('00'O));
4989 timer T := 3.0
4990 alt {
4991 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
4992 setverdict(pass);
4993 }
4994 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01004995 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01004996 }
4997}
4998testcase TC_err_84_unknown_msg() runs on test_CT {
4999 var MSC_ConnHdlr vc_conn;
5000 f_init(1, true);
5001 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005002 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005003 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005004 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005005}
5006
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005007/***********************************************************************
5008 * Handover
5009 ***********************************************************************/
5010
Harald Welte94e0c342018-04-07 11:33:23 +02005011/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5012private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5013runs on test_CT {
5014 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5015 " timeslot "&int2str(ts_nr)&" ";
5016 f_vty_transceive(BSCVTY, cmd & suffix);
5017}
5018
Harald Welte261af4b2018-02-12 21:20:39 +01005019/* 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 +07005020private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5021 uint8_t bts_nr, uint8_t trx_nr,
5022 in RslChannelNr chan_nr)
5023{
Harald Welte261af4b2018-02-12 21:20:39 +01005024 /* FIXME: resolve those from component-global state */
5025 var integer ts_nr := chan_nr.tn;
5026 var integer ss_nr;
5027 if (ischosen(chan_nr.u.ch0)) {
5028 ss_nr := 0;
5029 } else if (ischosen(chan_nr.u.lm)) {
5030 ss_nr := chan_nr.u.lm.sub_chan;
5031 } else if (ischosen(chan_nr.u.sdcch4)) {
5032 ss_nr := chan_nr.u.sdcch4.sub_chan;
5033 } else if (ischosen(chan_nr.u.sdcch8)) {
5034 ss_nr := chan_nr.u.sdcch8.sub_chan;
5035 } else {
5036 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005037 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005038 }
5039
5040 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5041 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005042 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005043}
5044
Neels Hofmeyr91401012019-07-11 00:42:35 +02005045/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5046 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5047 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5048 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5049 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005050private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5051 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5052{
5053 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005054}
5055
5056/* intra-BSC hand-over between BTS0 and BTS1 */
5057private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005058 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5059 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005060
5061 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5062 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5063
Harald Weltea0630032018-03-20 21:09:55 +01005064 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005065 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005066
5067 var HandoverState hs := {
5068 rr_ho_cmpl_seen := false,
5069 handover_done := false,
5070 old_chan_nr := -
5071 };
5072 /* issue hand-over command on VTY */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005073 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005074 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5075 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005076
5077 /* From the MGW perspective, a handover is is characterized by
5078 * performing one MDCX operation with the MGW. So we expect to see
5079 * one more MDCX during handover. */
5080 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5081
Harald Welte261af4b2018-02-12 21:20:39 +01005082 alt {
5083 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005084 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005085
Philipp Maier4dae0652018-11-12 12:03:26 +01005086 /* Since this is an internal handover we expect the BSC to inform the
5087 * MSC about the event */
5088 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5089
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005090 /* Check the amount of MGCP transactions is still consistant with the
5091 * test expectation */
5092 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005093
5094 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5095 * g_chan_nr to the new lchan that was handed over to. It lives in bts 1, so look it up at RSL1_PROC. */
5096 f_verify_encr_info(f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr));
5097
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005098 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005099}
5100
5101testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005102 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005103 var MSC_ConnHdlr vc_conn;
5104 f_init(2, true);
5105 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005106
5107 f_ctrs_bsc_and_bts_init();
5108
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005109 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005110 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005111
5112 /* from f_establish_fully() */
5113 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5114 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5115 /* from handover */
5116 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5117 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5118 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5119 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5120 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005121 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005122}
Harald Weltee9e02e42018-01-31 23:36:25 +01005123
Oliver Smith7eabd312021-07-12 14:18:56 +02005124function 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 +02005125 var MSC_ConnHdlr vc_conn;
5126 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5127 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5128
5129 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005130 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005131 f_sleep(1.0);
5132
5133 f_ctrs_bsc_and_bts_init();
5134
5135 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5136 vc_conn.done;
5137
5138 /* from f_establish_fully() */
5139 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5140 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5141 /* from handover */
5142 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5143 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5144 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5145 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5146 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005147 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005148 f_shutdown_helper();
5149}
5150
5151testcase TC_ho_int_a5_0() runs on test_CT {
5152 f_tc_ho_int_a5('01'O);
5153}
5154
5155testcase TC_ho_int_a5_1() runs on test_CT {
5156 f_tc_ho_int_a5('02'O);
5157}
5158
5159testcase TC_ho_int_a5_3() runs on test_CT {
5160 f_tc_ho_int_a5('08'O);
5161}
5162
5163testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005164 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005165}
5166
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005167/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5168private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5169 g_pars := f_gen_test_hdlr_pars();
5170 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5171 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005172
5173 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5174 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5175
5176 f_establish_fully(ass_cmd, exp_compl);
5177 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5178
5179 var HandoverState hs := {
5180 rr_ho_cmpl_seen := false,
5181 handover_done := false,
5182 old_chan_nr := -
5183 };
5184 /* issue hand-over command on VTY */
5185 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5186 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5187 f_rslem_suspend(RSL1_PROC);
5188
5189 /* From the MGW perspective, a handover is is characterized by
5190 * performing one MDCX operation with the MGW. So we expect to see
5191 * one more MDCX during handover. */
5192 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5193
5194 var RSL_Message rsl;
5195 var PDU_ML3_NW_MS l3;
5196 var RslChannelNr new_chan_nr;
5197 var GsmArfcn arfcn;
5198 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5199 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5200 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5201 setverdict(fail, "Expected handoverCommand");
5202 mtc.stop;
5203 }
5204 }
5205 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5206 new_chan_nr, arfcn);
5207
5208 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5209
5210 /* resume processing of RSL DChan messages, which was temporarily suspended
5211 * before performing a hand-over */
5212 f_rslem_resume(RSL1_PROC);
5213 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5214
5215 f_sleep(1.0);
5216
5217 /* Handover fails because no HANDO DET appears on the new lchan,
5218 * and the old lchan reports a Radio Link Failure. */
5219 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5220
5221 var PDU_BSSAP rx_clear_request;
5222 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5223 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5224 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5225
5226 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5227
5228 var MgcpCommand mgcp;
5229 interleave {
5230 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5231 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005232 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005233 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005234 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005235 }
5236 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005237 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005238 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005239 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005240 }
5241 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5242 }
5243
5244 f_sleep(0.5);
5245 setverdict(pass);
5246}
5247testcase TC_ho_int_radio_link_failure() runs on test_CT {
5248 var MSC_ConnHdlr vc_conn;
5249 f_init(2, true);
5250 f_sleep(1.0);
5251
5252 f_ctrs_bsc_and_bts_init();
5253
5254 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5255 vc_conn.done;
5256
5257 /* from f_establish_fully() */
5258 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5259 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5260 /* from handover */
5261 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5262 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5263 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5264 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
5265 f_ctrs_bsc_and_bts_verify();
5266 f_shutdown_helper();
5267}
5268
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005269/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005270private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005271 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005272 var template MgcpResponse mgcp_resp;
5273 var MGCP_RecvFrom mrf;
5274 var template MgcpMessage msg_resp;
5275 var template MgcpMessage msg_dlcx := {
5276 command := tr_DLCX()
5277 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005278
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005279 if (g_pars.aoip) {
5280 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005281 log("Got first DLCX: ", mgcp);
5282 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005283 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005284
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005285 MGCP.receive(tr_DLCX()) -> value mgcp {
5286 log("Got second DLCX: ", mgcp);
5287 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5288 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005289 } else {
5290 /* For SCCPLite, BSC doesn't handle the MSC-side */
5291 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5292 log("Got first DLCX: ", mrf.msg.command);
5293 msg_resp := {
5294 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5295 }
5296 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5297 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005298 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005299}
5300
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005301private 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 +01005302
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005303 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005304 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5305
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005306 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005307
5308 f_sleep(0.5);
5309 /* The MSC negotiates Handover Request and Handover Request Ack with
5310 * the other BSS and comes back with a BSSMAP Handover Command
5311 * containing an RR Handover Command coming from the target BSS... */
5312
5313 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5314 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5315 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5316 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5317 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5318
5319 /* expect the Handover Command to go out on RR */
5320 var RSL_Message rsl_ho_cmd
5321 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5322 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5323 var RSL_IE_Body rsl_ho_cmd_l3;
5324 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5325 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5326 setverdict(fail);
5327 } else {
5328 log("Found L3 Info: ", rsl_ho_cmd_l3);
5329 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5330 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5331 setverdict(fail);
5332 } else {
5333 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5334 setverdict(pass);
5335 }
5336 }
5337
5338 /* When the other BSS has reported a completed handover, this side is
5339 * torn down. */
5340
5341 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5342 var BssmapCause cause := enum2int(cause_val);
5343 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5344
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005345 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005346
5347 interleave {
5348 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5349 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5350 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005351 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005352 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005353 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005354}
5355
5356private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5357 g_pars := f_gen_test_hdlr_pars();
5358 var PDU_BSSAP ass_req := f_gen_ass_req();
5359 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5360 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5361 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5362 f_establish_fully(ass_req, exp_compl);
5363
5364 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005365}
5366testcase TC_ho_out_of_this_bsc() runs on test_CT {
5367 var MSC_ConnHdlr vc_conn;
5368
5369 f_init(1, true);
5370 f_sleep(1.0);
5371
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005372 f_ctrs_bsc_and_bts_init();
5373
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005374 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5375 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005376
5377 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5378 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5379 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5380 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5381 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5382 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5383 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005384 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005385}
5386
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005387private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5388 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005389 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005390 octetstring l3 := '0123456789'O)
5391runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005392 /* The old lchan and conn should still be active. See that arbitrary L3
5393 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005394 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005395 var template PDU_BSSAP exp_data := {
5396 discriminator := '1'B,
5397 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005398 dlci := dlci,
5399 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005400 pdu := {
5401 dtap := l3
5402 }
5403 };
5404 BSSAP.receive(exp_data);
5405 setverdict(pass);
5406}
5407
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005408private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5409 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005410 template (value) OCT1 dlci := '00'O,
5411 octetstring l3 := '0123456789'O)
5412runs on MSC_ConnHdlr {
5413 BSSAP.send(PDU_BSSAP:{
5414 discriminator := '1'B,
5415 spare := '0000000'B,
5416 dlci := dlci,
5417 lengthIndicator := lengthof(l3),
5418 pdu := {
5419 dtap := l3
5420 }
5421 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005422 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005423 setverdict(pass);
5424}
5425
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005426/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5427 * simply never sends a BSSMAP Handover Command. */
5428private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005429 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005430
5431 var PDU_BSSAP ass_req := f_gen_ass_req();
5432 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5433 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5434 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5435 f_establish_fully(ass_req, exp_compl);
5436
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005437 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005438 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5439
5440 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5441
5442 /* osmo-bsc should time out 10 seconds after the handover started.
5443 * Let's give it a bit extra. */
5444 f_sleep(15.0);
5445
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005446 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005447 f_sleep(1.0);
5448}
5449testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5450 var MSC_ConnHdlr vc_conn;
5451
5452 f_init(1, true);
5453 f_sleep(1.0);
5454
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005455 f_ctrs_bsc_and_bts_init();
5456
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005457 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5458 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005459
5460 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5461 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5462 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5463 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5464 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5465 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5466 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005467 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005468}
5469
5470/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5471 * RR Handover Failure. */
5472private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005473 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005474
5475 var PDU_BSSAP ass_req := f_gen_ass_req();
5476 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5477 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5478 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5479 f_establish_fully(ass_req, exp_compl);
5480
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005481 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005482 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5483
5484 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5485
5486 f_sleep(0.5);
5487 /* The MSC negotiates Handover Request and Handover Request Ack with
5488 * the other BSS and comes back with a BSSMAP Handover Command
5489 * containing an RR Handover Command coming from the target BSS... */
5490
5491 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5492 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5493 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5494 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5495 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5496
5497 /* expect the Handover Command to go out on RR */
5498 var RSL_Message rsl_ho_cmd
5499 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5500 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5501 var RSL_IE_Body rsl_ho_cmd_l3;
5502 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5503 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5504 setverdict(fail);
5505 } else {
5506 log("Found L3 Info: ", rsl_ho_cmd_l3);
5507 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5508 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5509 setverdict(fail);
5510 } else {
5511 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5512 setverdict(pass);
5513 }
5514 }
5515
5516 f_sleep(0.2);
5517 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5518
5519 /* Should tell the MSC about the failure */
5520 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5521
5522 f_sleep(1.0);
5523
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005524 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005525 f_sleep(1.0);
5526
5527 setverdict(pass);
5528 f_sleep(1.0);
5529}
5530testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5531 var MSC_ConnHdlr vc_conn;
5532
5533 f_init(1, true);
5534 f_sleep(1.0);
5535
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005536 f_ctrs_bsc_and_bts_init();
5537
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005538 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5539 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005540
5541 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5542 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5543 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5544 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5545 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5546 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5547 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005548 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005549}
5550
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005551/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5552 * (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 +02005553 * and the lchan is released. */
5554private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005555 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005556
5557 var PDU_BSSAP ass_req := f_gen_ass_req();
5558 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5559 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5560 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5561 f_establish_fully(ass_req, exp_compl);
5562
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005563 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005564 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5565
5566 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5567
5568 f_sleep(0.5);
5569 /* The MSC negotiates Handover Request and Handover Request Ack with
5570 * the other BSS and comes back with a BSSMAP Handover Command
5571 * containing an RR Handover Command coming from the target BSS... */
5572
5573 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5574 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5575 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5576 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5577 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5578
5579 /* expect the Handover Command to go out on RR */
5580 var RSL_Message rsl_ho_cmd
5581 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5582 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5583 var RSL_IE_Body rsl_ho_cmd_l3;
5584 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5585 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5586 setverdict(fail);
5587 } else {
5588 log("Found L3 Info: ", rsl_ho_cmd_l3);
5589 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5590 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5591 setverdict(fail);
5592 } else {
5593 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5594 setverdict(pass);
5595 }
5596 }
5597
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005598 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5599 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5600 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005601
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005602 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005603 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5604 log("Got BSSMAP Clear Request");
5605 /* Instruct BSC to clear channel */
5606 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5607 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5608
5609 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005610 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005611 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5612 log("Got Deact SACCH");
5613 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005614 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005615 log("Got RR Release");
5616 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005617 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005618 log("Got RF Chan Rel");
5619 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005620 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005621 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005622 }
5623
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005624 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005625 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005626
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005627 setverdict(pass);
5628 f_sleep(1.0);
5629}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005630testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005631 var MSC_ConnHdlr vc_conn;
5632
5633 f_init(1, true);
5634 f_sleep(1.0);
5635
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005636 f_ctrs_bsc_and_bts_init();
5637
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005638 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005639 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005640
5641 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5642 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5643 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5644 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5645 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5646 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5647 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005648 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005649}
5650
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005651private 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 +01005652 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5653 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5654 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5655 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5656 * before we get started. */
5657 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5658 f_rslem_register(0, new_chan_nr);
5659 g_chan_nr := new_chan_nr;
5660 f_sleep(1.0);
5661
5662 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5663 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5664 activate(as_Media());
5665
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005666 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005667 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005668 oldToNewBSSIEs := oldToNewBSSIEs,
5669 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005670 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005671
5672 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5673
5674 var PDU_BSSAP rx_bssap;
5675 var octetstring ho_command_str;
5676
5677 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005678
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005679 /* we're sure that the channel activation is done now, verify the encryption parameters in it */
5680 f_verify_encr_info(f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr));
5681
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005682 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5683 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5684 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5685 log("L3 Info in HO Request Ack is ", ho_command);
5686
5687 var GsmArfcn arfcn;
5688 var RslChannelNr actual_new_chan_nr;
5689 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5690 actual_new_chan_nr, arfcn);
5691
5692 if (actual_new_chan_nr != new_chan_nr) {
5693 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5694 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5695 setverdict(fail);
5696 return;
5697 }
5698 log("Handover Command chan_nr is", actual_new_chan_nr);
5699
5700 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5701 * tells the MS to handover to the new lchan. Here comes the new MS on
5702 * the new lchan with a Handover RACH: */
5703
5704 /* send handover detect */
5705
5706 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5707
5708 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5709
5710 /* send handover complete over the new channel */
5711
5712 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5713 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5714 enc_PDU_ML3_MS_NW(l3_tx)));
5715
5716 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005717 setverdict(pass);
5718}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005719
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005720private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005721 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005722 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5723 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5724 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005725 }
5726 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005727 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005728 } else {
5729 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005730 }
5731 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005732 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005733 setverdict(pass);
5734}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005735function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005736 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005737
5738 f_init(1, true);
5739 f_sleep(1.0);
5740
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005741 f_ctrs_bsc_and_bts_init();
5742
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005743 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5744 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005745
5746 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5747 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005748
5749 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5750 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5751 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5752 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5753 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005754}
5755
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005756testcase TC_ho_into_this_bsc() runs on test_CT {
5757 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5758 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005759 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005760}
5761
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005762function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5763 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5764 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5765 f_tc_ho_into_this_bsc_main(pars);
5766 f_shutdown_helper();
5767}
5768
5769testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5770 f_tc_ho_into_this_bsc_a5('01'O);
5771}
5772
5773testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5774 f_tc_ho_into_this_bsc_a5('02'O);
5775}
5776
5777testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5778 f_tc_ho_into_this_bsc_a5('08'O);
5779}
5780
5781testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5782 f_tc_ho_into_this_bsc_a5('10'O);
5783}
5784
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005785testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5786 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5787 pars.host_aoip_tla := "::6";
5788 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005789 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005790}
5791
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005792/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005793 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005794 channel is later released (RR CHannel Release), should trigger inclusion of
5795 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5796 neighbors. */
5797testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5798 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5799 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005800 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005801 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005802
5803 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5804 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5805 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005806 f_shutdown_helper();
5807}
5808
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005809/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5810 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5811 list when the channel is released. */
5812testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5813 f_init_vty();
5814 f_vty_allow_srvcc_fast_return(true, 0)
5815
5816 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5817 pars.last_used_eutran_plmn := '323454'O;
5818 pars.exp_fast_return := false;
5819 f_tc_ho_into_this_bsc_main(pars);
5820 f_vty_allow_srvcc_fast_return(false, 0);
5821 f_shutdown_helper();
5822}
5823
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005824private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5825 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5826 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5827 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5828 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5829 setverdict(pass);
5830}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005831
5832private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5833 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005834 var MSC_ConnHdlr vc_conn;
5835 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5836
5837 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005838 if (disable_fast_return) {
5839 f_vty_allow_srvcc_fast_return(true, 0);
5840 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005841 f_sleep(1.0);
5842
5843 f_ctrs_bsc_and_bts_init();
5844
5845 pars.last_used_eutran_plmn := '323454'O;
5846 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5847 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5848
5849 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5850 vc_conn.done;
5851
5852 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5853 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5854 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5855 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5856 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5857 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005858
5859 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5860 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005861 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005862
5863 if (disable_fast_return) {
5864 f_vty_allow_srvcc_fast_return(false, 0);
5865 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005866 f_shutdown_helper();
5867}
5868
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005869/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5870 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5871 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5872 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5873testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5874 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5875}
5876/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5877 * independently of fast-reture allowed/forbidden in local BTS */
5878testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5879 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5880}
5881
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005882private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5883 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5884 f_rslem_register(0, new_chan_nr);
5885 g_chan_nr := new_chan_nr;
5886 f_sleep(1.0);
5887
5888 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5889 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5890 activate(as_Media());
5891
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005892 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005893 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005894 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005895
5896 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5897
5898 var PDU_BSSAP rx_bssap;
5899 var octetstring ho_command_str;
5900
5901 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5902
5903 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5904 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5905 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5906 log("L3 Info in HO Request Ack is ", ho_command);
5907
5908 var GsmArfcn arfcn;
5909 var RslChannelNr actual_new_chan_nr;
5910 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5911 actual_new_chan_nr, arfcn);
5912
5913 if (actual_new_chan_nr != new_chan_nr) {
5914 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5915 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5916 setverdict(fail);
5917 return;
5918 }
5919 log("Handover Command chan_nr is", actual_new_chan_nr);
5920
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005921 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5922 f_sleep(1.0);
5923
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005924 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5925 * tells the MS to handover to the new lchan. In this case, the MS
5926 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5927 * Handover Failure to the MSC. The procedure according to 3GPP TS
5928 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5929 * BSSMAP Clear Command: */
5930
5931 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5932 var BssmapCause cause := enum2int(cause_val);
5933 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5934
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005935 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005936 BSSAP.receive(tr_BSSMAP_ClearComplete);
5937
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005938 setverdict(pass);
5939 f_sleep(1.0);
5940
5941 setverdict(pass);
5942}
5943testcase TC_ho_in_fail_msc_clears() runs on test_CT {
5944 var MSC_ConnHdlr vc_conn;
5945 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5946
5947 f_init(1, true);
5948 f_sleep(1.0);
5949
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005950 f_ctrs_bsc_and_bts_init();
5951
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005952 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5953 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005954
5955 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
5956 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005957
5958 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5959 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5960 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5961 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5962 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005963 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005964}
5965
5966private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
5967 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5968 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5969 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5970 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5971 * before we get started. */
5972 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5973 f_rslem_register(0, new_chan_nr);
5974 g_chan_nr := new_chan_nr;
5975 f_sleep(1.0);
5976
5977 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5978 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5979 activate(as_Media());
5980
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005981 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005982 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005983 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005984
5985 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5986
5987 var PDU_BSSAP rx_bssap;
5988 var octetstring ho_command_str;
5989
5990 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5991
5992 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5993 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5994 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5995 log("L3 Info in HO Request Ack is ", ho_command);
5996
5997 var GsmArfcn arfcn;
5998 var RslChannelNr actual_new_chan_nr;
5999 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6000 actual_new_chan_nr, arfcn);
6001
6002 if (actual_new_chan_nr != new_chan_nr) {
6003 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6004 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6005 setverdict(fail);
6006 return;
6007 }
6008 log("Handover Command chan_nr is", actual_new_chan_nr);
6009
6010 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6011 * tells the MS to handover to the new lchan. Here comes the new MS on
6012 * the new lchan with a Handover RACH: */
6013
6014 /* send handover detect */
6015
6016 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6017
6018 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6019
6020 /* The MSC chooses to clear the connection now, maybe we got the
6021 * Handover RACH on the new cell but the MS still signaled Handover
6022 * Failure to the old BSS? */
6023
6024 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6025 var BssmapCause cause := enum2int(cause_val);
6026 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6027
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006028 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006029 BSSAP.receive(tr_BSSMAP_ClearComplete);
6030
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006031 f_sleep(1.0);
6032}
6033testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6034 var MSC_ConnHdlr vc_conn;
6035 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6036
6037 f_init(1, true);
6038 f_sleep(1.0);
6039
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006040 f_ctrs_bsc_and_bts_init();
6041
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006042 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6043 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006044
6045 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6046 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006047
6048 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6049 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6050 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6051 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6052 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006053 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006054}
6055
6056/* The new BSS's lchan times out before the MSC decides that handover failed. */
6057private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6058 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6059 f_rslem_register(0, new_chan_nr);
6060 g_chan_nr := new_chan_nr;
6061 f_sleep(1.0);
6062
6063 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6064 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6065 activate(as_Media());
6066
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006067 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006068 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006069 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006070
6071 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6072
6073 var PDU_BSSAP rx_bssap;
6074 var octetstring ho_command_str;
6075
6076 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6077
6078 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6079 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6080 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6081 log("L3 Info in HO Request Ack is ", ho_command);
6082
6083 var GsmArfcn arfcn;
6084 var RslChannelNr actual_new_chan_nr;
6085 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6086 actual_new_chan_nr, arfcn);
6087
6088 if (actual_new_chan_nr != new_chan_nr) {
6089 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6090 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6091 setverdict(fail);
6092 return;
6093 }
6094 log("Handover Command chan_nr is", actual_new_chan_nr);
6095
6096 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6097 * tells the MS to handover to the new lchan. But the MS never shows up
6098 * on the new lchan. */
6099
6100 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6101
6102 /* Did osmo-bsc also send a Clear Request? */
6103 timer T := 0.5;
6104 T.start;
6105 alt {
6106 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6107 [] T.timeout { }
6108 }
6109
6110 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6111 * asked for it, this is a Handover Failure after all). */
6112
6113 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6114 var BssmapCause cause := enum2int(cause_val);
6115 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6116
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006117 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006118 BSSAP.receive(tr_BSSMAP_ClearComplete);
6119
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006120 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006121}
6122testcase TC_ho_in_fail_no_detect() runs on test_CT {
6123 var MSC_ConnHdlr vc_conn;
6124 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6125
6126 f_init(1, true);
6127 f_sleep(1.0);
6128
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006129 f_ctrs_bsc_and_bts_init();
6130
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006131 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6132 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006133
6134 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6135 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006136
6137 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6138 f_ctrs_bsc_and_bts_add(0, "handover:error");
6139 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6140 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6141 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006142 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006143}
6144
6145/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6146private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6147 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6148 f_rslem_register(0, new_chan_nr);
6149 g_chan_nr := new_chan_nr;
6150 f_sleep(1.0);
6151
6152 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6153 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6154 activate(as_Media());
6155
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006156 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006157 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006158 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006159
6160 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6161
6162 var PDU_BSSAP rx_bssap;
6163 var octetstring ho_command_str;
6164
6165 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6166
6167 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6168 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6169 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6170 log("L3 Info in HO Request Ack is ", ho_command);
6171
6172 var GsmArfcn arfcn;
6173 var RslChannelNr actual_new_chan_nr;
6174 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6175 actual_new_chan_nr, arfcn);
6176
6177 if (actual_new_chan_nr != new_chan_nr) {
6178 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6179 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6180 setverdict(fail);
6181 return;
6182 }
6183 log("Handover Command chan_nr is", actual_new_chan_nr);
6184
6185 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6186 * tells the MS to handover to the new lchan. But the MS never shows up
6187 * on the new lchan. */
6188
6189 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6190
6191 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006192 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006193
6194 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006195 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6196 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6197 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006198 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006199 BSSAP.receive(tr_BSSMAP_ClearComplete);
6200
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006201 f_sleep(1.0);
6202}
6203testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6204 var MSC_ConnHdlr vc_conn;
6205 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6206
6207 f_init(1, true);
6208 f_sleep(1.0);
6209
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006210 f_ctrs_bsc_and_bts_init();
6211
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006212 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6213 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006214
6215 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6216 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006217
6218 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6219 f_ctrs_bsc_and_bts_add(0, "handover:error");
6220 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6221 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6222 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006223 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006224}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006225
Neels Hofmeyr91401012019-07-11 00:42:35 +02006226type record of charstring Commands;
6227
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006228private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006229{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006230 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006231 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006232 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006233 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006234 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006235}
6236
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006237private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6238{
6239 f_vty_enter_cfg_cs7_inst(pt, 0);
6240 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6241 f_vty_transceive(pt, cmds[i]);
6242 }
6243 f_vty_transceive(pt, "end");
6244}
6245
Neels Hofmeyr91401012019-07-11 00:42:35 +02006246private function f_probe_for_handover(charstring log_label,
6247 charstring log_descr,
6248 charstring handover_vty_cmd,
6249 boolean expect_handover,
6250 boolean is_inter_bsc_handover := false)
6251runs on MSC_ConnHdlr
6252{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006253 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6254 * lchans to be established on bts 1 or bts 2. */
6255 f_rslem_suspend(RSL1_PROC);
6256 f_rslem_suspend(RSL2_PROC);
6257
Neels Hofmeyr91401012019-07-11 00:42:35 +02006258 var RSL_Message rsl;
6259
6260 var charstring log_msg := " (expecting handover)"
6261 if (not expect_handover) {
6262 log_msg := " (expecting NO handover)";
6263 }
6264 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6265 f_vty_transceive(BSCVTY, handover_vty_cmd);
6266
Neels Hofmeyr91401012019-07-11 00:42:35 +02006267 timer T := 2.0;
6268 T.start;
6269
6270 alt {
6271 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6272 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6273 log("Rx L3 from net: ", l3);
6274 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6275 var RslChannelNr new_chan_nr;
6276 var GsmArfcn arfcn;
6277 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6278 new_chan_nr, arfcn);
6279 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6280 log(l3.msgs.rrm.handoverCommand);
6281
6282 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6283 * matter on which BTS it really is, we're not going to follow through an entire handover
6284 * anyway. */
6285 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6286 f_rslem_resume(RSL1_PROC);
6287 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6288 f_rslem_resume(RSL2_PROC);
6289
6290 if (expect_handover and not is_inter_bsc_handover) {
6291 setverdict(pass);
6292 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6293 } else {
6294 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6295 & log_label & ": " & log_descr);
6296 }
6297
6298 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6299 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6300 * Handover Failure. */
6301 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6302
6303 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6304 f_sleep(0.5);
6305 RSL1.clear;
6306 RSL2.clear;
6307 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6308 break;
6309 } else {
6310 repeat;
6311 }
6312 }
6313 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6314 if (expect_handover and is_inter_bsc_handover) {
6315 setverdict(pass);
6316 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6317 } else {
6318 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6319 & log_label & ": " & log_descr);
6320 }
6321
6322 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6323
6324 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6325 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6326 * setting a short timeout and waiting is the only way. */
6327 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6328 f_sleep(1.5);
6329 log("f_probe_for_handover(" & log_label & "): ...done");
6330
6331 break;
6332 }
6333 [] T.timeout {
6334 if (expect_handover) {
6335 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6336 & log_label & ": " & log_descr);
6337 } else {
6338 setverdict(pass);
6339 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6340 }
6341 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6342 break;
6343 }
6344 }
6345
6346 f_rslem_resume(RSL1_PROC);
6347 f_rslem_resume(RSL2_PROC);
6348 f_sleep(3.0);
6349 RSL.clear;
6350
6351 log("f_probe_for_handover(" & log_label & "): done clearing");
6352}
6353
6354/* Test the effect of various neighbor configuration scenarios:
6355 *
6356 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6357 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6358 */
6359private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6360 g_pars := f_gen_test_hdlr_pars();
6361 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6362 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006363
6364 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6365 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6366
6367 /* Establish lchan at bts 0 */
6368 f_establish_fully(ass_cmd, exp_compl);
6369
6370 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6371 f_vty_enter_cfg_network(BSCVTY);
6372 f_vty_transceive(BSCVTY, "timer T7 1");
6373 f_vty_transceive(BSCVTY, "end");
6374}
6375
6376private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6377 f_tc_ho_neighbor_config_start();
6378
6379 /*
6380 * bts 0 ARFCN 871 BSIC 10
6381 * bts 1 ARFCN 871 BSIC 11
6382 * bts 2 ARFCN 871 BSIC 12
6383 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6384 */
6385
6386 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006387 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006388 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6389 "handover any to arfcn 871 bsic 11",
6390 true);
6391
6392 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6393 "handover any to arfcn 13 bsic 39",
6394 false);
6395
6396 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6397 "handover any to arfcn 871 bsic 12",
6398 false);
6399
6400 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6401 "handover any to arfcn 871 bsic 11",
6402 true);
6403}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006404testcase TC_ho_neighbor_config_1() runs on test_CT {
6405 var MSC_ConnHdlr vc_conn;
6406 f_init(3, true, guard_timeout := 60.0);
6407 f_sleep(1.0);
6408 f_ctrs_bsc_and_bts_init();
6409 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6410 vc_conn.done;
6411
6412 /* f_tc_ho_neighbor_config_start() */
6413 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6414 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6415
6416 /* 1.a */
6417 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6418 * handover quickly by sending a Handover Failure message. */
6419 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6420 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6421 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6422 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6423
6424 /* 1.b */
6425 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6426 f_ctrs_bsc_and_bts_add(0, "handover:error");
6427
6428 /* 1.c */
6429 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6430 f_ctrs_bsc_and_bts_add(0, "handover:error");
6431
6432 /* 1.d */
6433 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6434 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6435 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6436 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6437
6438 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006439 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006440}
6441
Neels Hofmeyr91401012019-07-11 00:42:35 +02006442private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6443 f_tc_ho_neighbor_config_start();
6444
6445 /*
6446 * bts 0 ARFCN 871 BSIC 10
6447 * bts 1 ARFCN 871 BSIC 11
6448 * bts 2 ARFCN 871 BSIC 12
6449 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6450 */
6451
6452 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006453 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006454 f_sleep(0.5);
6455
6456 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6457 "handover any to arfcn 871 bsic 11",
6458 true);
6459
6460 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6461 "handover any to arfcn 871 bsic 12",
6462 false);
6463}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006464testcase TC_ho_neighbor_config_2() runs on test_CT {
6465 var MSC_ConnHdlr vc_conn;
6466 f_init(3, true, guard_timeout := 50.0);
6467 f_sleep(1.0);
6468 f_ctrs_bsc_and_bts_init();
6469 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6470 vc_conn.done;
6471
6472 /* f_tc_ho_neighbor_config_start() */
6473 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6474 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6475
6476 /* 2.a */
6477 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6478 * handover quickly by sending a Handover Failure message. */
6479 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6480 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6481 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6482 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6483
6484 /* 2.b */
6485 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6486 f_ctrs_bsc_and_bts_add(0, "handover:error");
6487
6488 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006489 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006490}
6491
Neels Hofmeyr91401012019-07-11 00:42:35 +02006492private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6493 f_tc_ho_neighbor_config_start();
6494
6495 /*
6496 * bts 0 ARFCN 871 BSIC 10
6497 * bts 1 ARFCN 871 BSIC 11
6498 * bts 2 ARFCN 871 BSIC 12
6499 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6500 */
6501
6502 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006503 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006504 f_sleep(0.5);
6505
6506 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6507 "handover any to arfcn 871 bsic 11",
6508 false);
6509 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",
6510 "handover any to arfcn 871 bsic 12",
6511 true);
6512}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006513testcase TC_ho_neighbor_config_3() runs on test_CT {
6514 var MSC_ConnHdlr vc_conn;
6515 f_init(3, true, guard_timeout := 50.0);
6516 f_sleep(1.0);
6517 f_ctrs_bsc_and_bts_init();
6518 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6519 vc_conn.done;
6520
6521 /* f_tc_ho_neighbor_config_start() */
6522 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6523 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6524
6525 /* 3.a */
6526 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6527 f_ctrs_bsc_and_bts_add(0, "handover:error");
6528
6529 /* 3.b */
6530 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6531 * handover quickly by sending a Handover Failure message. */
6532 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6533 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6534 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6535 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6536
6537 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006538 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006539}
6540
Neels Hofmeyr91401012019-07-11 00:42:35 +02006541private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6542 f_tc_ho_neighbor_config_start();
6543
6544 /*
6545 * bts 0 ARFCN 871 BSIC 10
6546 * bts 1 ARFCN 871 BSIC 11
6547 * bts 2 ARFCN 871 BSIC 12
6548 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6549 */
6550
6551 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006552 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006553 f_sleep(0.5);
6554
6555 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6556 "handover any to arfcn 871 bsic 11",
6557 false);
6558 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6559 "handover any to arfcn 871 bsic 12",
6560 false);
6561 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6562 "handover any to arfcn 123 bsic 45",
6563 true, true);
6564}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006565testcase TC_ho_neighbor_config_4() runs on test_CT {
6566 var MSC_ConnHdlr vc_conn;
6567 f_init(3, true, guard_timeout := 50.0);
6568 f_sleep(1.0);
6569 f_ctrs_bsc_and_bts_init();
6570 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6571 vc_conn.done;
6572
6573 /* f_tc_ho_neighbor_config_start() */
6574 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6575 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6576
6577 /* 4.a */
6578 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6579 f_ctrs_bsc_and_bts_add(0, "handover:error");
6580
6581 /* 4.b */
6582 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6583 f_ctrs_bsc_and_bts_add(0, "handover:error");
6584
6585 /* 4.c */
6586 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6587 * handover quickly by timing out after the Handover Required message */
6588 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6589 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6590 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6591 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6592
6593 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006594 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006595}
6596
Neels Hofmeyr91401012019-07-11 00:42:35 +02006597private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6598 f_tc_ho_neighbor_config_start();
6599
6600 /*
6601 * bts 0 ARFCN 871 BSIC 10
6602 * bts 1 ARFCN 871 BSIC 11
6603 * bts 2 ARFCN 871 BSIC 12
6604 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6605 */
6606
6607 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 +02006608 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006609 f_sleep(0.5);
6610
6611 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6612 "handover any to arfcn 871 bsic 12",
6613 true, true);
6614}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006615testcase TC_ho_neighbor_config_5() runs on test_CT {
6616 var MSC_ConnHdlr vc_conn;
6617 f_init(3, true);
6618 f_sleep(1.0);
6619 f_ctrs_bsc_and_bts_init();
6620 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6621 vc_conn.done;
6622
6623 /* f_tc_ho_neighbor_config_start() */
6624 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6625 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6626
6627 /* 5 */
6628 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6629 * handover quickly by timing out after the Handover Required message */
6630 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6631 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6632 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6633 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6634
6635 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006636 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006637}
6638
Neels Hofmeyr91401012019-07-11 00:42:35 +02006639private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6640 f_tc_ho_neighbor_config_start();
6641
6642 /*
6643 * bts 0 ARFCN 871 BSIC 10
6644 * bts 1 ARFCN 871 BSIC 11
6645 * bts 2 ARFCN 871 BSIC 12
6646 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6647 */
6648
6649 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6650 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006651 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006652 f_sleep(0.5);
6653
6654 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6655 "handover any to arfcn 871 bsic 12",
6656 false);
6657}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006658testcase TC_ho_neighbor_config_6() runs on test_CT {
6659 var MSC_ConnHdlr vc_conn;
6660 f_init(3, true);
6661 f_sleep(1.0);
6662 f_ctrs_bsc_and_bts_init();
6663 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6664 vc_conn.done;
6665
6666 /* f_tc_ho_neighbor_config_start() */
6667 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6668 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6669
6670 /* 6.a */
6671 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6672 * handover quickly by timing out after the Handover Required message */
6673 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6674 f_ctrs_bsc_and_bts_add(0, "handover:error");
6675
6676 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006677 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006678}
6679
Neels Hofmeyr91401012019-07-11 00:42:35 +02006680private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6681 f_tc_ho_neighbor_config_start();
6682
6683 /*
6684 * bts 0 ARFCN 871 BSIC 10
6685 * bts 1 ARFCN 871 BSIC 11
6686 * bts 2 ARFCN 871 BSIC 12
6687 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6688 */
6689
6690 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6691 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006692 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006693 f_sleep(0.5);
6694
6695 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6696 "handover any to arfcn 871 bsic 12",
6697 true);
6698 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6699 "handover any to arfcn 123 bsic 45",
6700 true, true);
6701}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006702testcase TC_ho_neighbor_config_7() runs on test_CT {
6703 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006704 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006705 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006706 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006707 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6708 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006709
6710 /* f_tc_ho_neighbor_config_start() */
6711 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6712 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6713
6714 /* 7.a */
6715 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6716 * handover quickly by sending a Handover Failure message. */
6717 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6718 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6719 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6720 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6721
6722 /* 7.b */
6723 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6724 * handover quickly by timing out after the Handover Required message */
6725 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6726 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6727 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6728 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6729
6730 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006731 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006732}
6733
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006734/* OS#3041: Open and close N connections in a normal fashion, and expect no
6735 * BSSMAP Reset just because of that. */
6736testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6737 var default d;
6738 var integer i;
6739 var DchanTuple dt;
6740
6741 f_init();
6742
6743 /* Wait for initial BSSMAP Reset to pass */
6744 f_sleep(4.0);
6745
6746 d := activate(no_bssmap_reset());
6747
6748 /* Setup up a number of connections and RLSD them again from the MSC
6749 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6750 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006751 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006752 /* Since we're doing a lot of runs, give each one a fresh
6753 * T_guard from the top. */
6754 T_guard.start;
6755
6756 /* Setup a BSSAP connection and clear it right away. This is
6757 * the MSC telling the BSC about a planned release, it's not an
6758 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006759 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006760
6761 /* MSC disconnects (RLSD). */
6762 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6763 }
6764
6765 /* In the buggy behavior, a timeout of 2 seconds happens between above
6766 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6767 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6768 f_sleep(4.0);
6769
6770 deactivate(d);
6771 f_shutdown_helper();
6772}
Harald Welte552620d2017-12-16 23:21:36 +01006773
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006774/* OS#3041: Open and close N connections in a normal fashion, and expect no
6775 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6776 * the MSC. */
6777testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6778 var default d;
6779 var integer i;
6780 var DchanTuple dt;
6781 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006782 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6783 var BssmapCause cause := enum2int(cause_val);
6784
6785 f_init();
6786
6787 /* Wait for initial BSSMAP Reset to pass */
6788 f_sleep(4.0);
6789
6790 d := activate(no_bssmap_reset());
6791
6792 /* Setup up a number of connections and RLSD them again from the MSC
6793 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6794 * Let's do it some more times for good measure. */
6795 for (i := 0; i < 8; i := i+1) {
6796 /* Since we're doing a lot of runs, give each one a fresh
6797 * T_guard from the top. */
6798 T_guard.start;
6799
6800 /* Setup a BSSAP connection and clear it right away. This is
6801 * the MSC telling the BSC about a planned release, it's not an
6802 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006803 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006804
6805 /* Instruct BSC to clear channel */
6806 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6807
6808 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006809 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006810 }
6811
6812 /* In the buggy behavior, a timeout of 2 seconds happens between above
6813 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6814 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6815 f_sleep(4.0);
6816
6817 deactivate(d);
6818 f_shutdown_helper();
6819}
6820
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006821/* OS#3041: Open and close N connections in a normal fashion, and expect no
6822 * BSSMAP Reset just because of that. Close connections from the MS side with a
6823 * Release Ind on RSL. */
6824testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6825 var default d;
6826 var integer i;
6827 var DchanTuple dt;
6828 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006829 var integer j;
6830
6831 f_init();
6832
6833 /* Wait for initial BSSMAP Reset to pass */
6834 f_sleep(4.0);
6835
6836 d := activate(no_bssmap_reset());
6837
6838 /* Setup up a number of connections and RLSD them again from the MSC
6839 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6840 * Let's do it some more times for good measure. */
6841 for (i := 0; i < 8; i := i+1) {
6842 /* Since we're doing a lot of runs, give each one a fresh
6843 * T_guard from the top. */
6844 T_guard.start;
6845
6846 /* Setup a BSSAP connection and clear it right away. This is
6847 * the MSC telling the BSC about a planned release, it's not an
6848 * erratic loss of a connection. */
6849 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6850
6851 /* simulate RLL REL IND */
6852 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6853
6854 /* expect Clear Request on MSC side */
6855 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6856
6857 /* Instruct BSC to clear channel */
6858 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6859 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6860
6861 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006862 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006863 }
6864
6865 /* In the buggy behavior, a timeout of 2 seconds happens between above
6866 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6867 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6868 f_sleep(4.0);
6869
6870 deactivate(d);
6871 f_shutdown_helper();
6872}
6873
Harald Welte94e0c342018-04-07 11:33:23 +02006874/***********************************************************************
6875 * IPA style dynamic PDCH
6876 ***********************************************************************/
6877
6878private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6879 template (omit) RSL_Cause nack := omit)
6880runs on test_CT {
6881 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6882 var RSL_Message rsl_unused;
6883 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6884 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6885 /* expect the BSC to issue the related RSL command */
6886 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6887 if (istemplatekind(nack, "omit")) {
6888 /* respond with a related acknowledgement */
6889 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6890 } else {
6891 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6892 }
6893}
6894
6895private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6896 template (omit) RSL_Cause nack := omit)
6897runs on test_CT {
6898 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6899 var RSL_Message rsl_unused;
6900 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6901 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6902 /* expect the BSC to issue the related RSL command */
6903 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6904 if (istemplatekind(nack, "omit")) {
6905 /* respond with a related acknowledgement */
6906 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6907 } else {
6908 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6909 }
6910}
6911
6912private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6913runs on test_CT return charstring {
6914 var charstring cmd, resp;
6915 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006916 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006917}
6918
6919private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6920 template charstring exp)
6921runs on test_CT {
6922 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
6923 if (not match(mode, exp)) {
6924 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02006925 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02006926 }
6927}
6928
6929private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
6930runs on test_CT {
6931 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
6932 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
6933 f_vty_transceive(BSCVTY, "end");
6934}
6935
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02006936
6937private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
6938 var integer i;
6939 for (i := 0; i < 8; i := i + 1) {
6940 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
6941 }
6942}
6943
Harald Welte94e0c342018-04-07 11:33:23 +02006944private const charstring TCHF_MODE := "TCH/F mode";
6945private const charstring TCHH_MODE := "TCH/H mode";
6946private const charstring PDCH_MODE := "PDCH mode";
6947private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02006948private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02006949
6950/* Test IPA PDCH activation / deactivation triggered by VTY */
6951testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
6952 var RSL_Message rsl_unused;
6953
6954 /* change Timeslot 6 before f_init() starts RSL */
6955 f_init_vty();
6956 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6957 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6958
6959 f_init(1, false);
6960 f_sleep(1.0);
6961
6962 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6963
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006964 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006965 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6966 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6967 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6968 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6969 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006970 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006971 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6972
6973 /* De-activate it via VTY */
6974 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6975 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006976 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006977 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6978
6979 /* re-activate it via VTY */
6980 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
6981 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006982 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006983 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6984
6985 /* and finally de-activate it again */
6986 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6987 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006988 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006989 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6990
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006991 /* clean up config */
6992 f_ts_set_chcomb(0, 0, 6, "PDCH");
6993
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006994 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006995}
6996
6997/* Test IPA PDCH activation NACK */
6998testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
6999 var RSL_Message rsl_unused;
7000
7001 /* change Timeslot 6 before f_init() starts RSL */
7002 f_init_vty();
7003 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7004 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7005
7006 f_init(1, false);
7007 f_sleep(1.0);
7008
7009 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7010
7011 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7012 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7013 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7014 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7015 f_sleep(1.0);
7016 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7017
7018 /* De-activate it via VTY */
7019 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7020 f_sleep(1.0);
7021 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7022
7023 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7024 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7025 f_sleep(1.0);
7026 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7027
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007028 /* clean up config */
7029 f_ts_set_chcomb(0, 0, 6, "PDCH");
7030
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007031 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007032}
7033
7034
7035/***********************************************************************
7036 * Osmocom style dynamic PDCH
7037 ***********************************************************************/
7038
7039private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7040 template (omit) RSL_Cause nack := omit)
7041runs on test_CT {
7042 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7043 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007044 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007045 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7046 /* expect the BSC to issue the related RSL command */
7047 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7048 if (istemplatekind(nack, "omit")) {
7049 /* respond with a related acknowledgement */
7050 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7051 } else {
7052 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7053 }
7054}
7055
7056private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7057 template (omit) RSL_Cause nack := omit)
7058runs on test_CT {
7059 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7060 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007061 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007062 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7063 /* expect the BSC to issue the related RSL command */
7064 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7065 if (istemplatekind(nack, "omit")) {
7066 /* respond with a related acknowledgement */
7067 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7068 } else {
7069 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7070 }
7071}
7072
7073/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7074testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7075 var RSL_Message rsl_unused;
7076
7077 /* change Timeslot 6 before f_init() starts RSL */
7078 f_init_vty();
7079 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7080 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7081
7082 f_init(1, false);
7083 f_sleep(1.0);
7084
7085 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7086
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007087 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007088 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7089 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7090 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7091
7092 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7093 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007094 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 +02007095 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7096
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007097 /* clean up config */
7098 f_ts_set_chcomb(0, 0, 6, "PDCH");
7099
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007100 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007101}
7102
7103/* Test Osmocom dyn PDCH activation NACK behavior */
7104testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7105 var RSL_Message rsl_unused;
7106
7107 /* change Timeslot 6 before f_init() starts RSL */
7108 f_init_vty();
7109 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7110 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7111
7112 f_init(1, false);
7113 f_sleep(1.0);
7114
7115 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7116
7117 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7118 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7119 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7120
7121 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7122 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7123 f_sleep(1.0);
7124 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7125
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007126 /* clean up config */
7127 f_ts_set_chcomb(0, 0, 6, "PDCH");
7128
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007129 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007130}
7131
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007132/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7133testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7134 var RSL_Message rsl_unused, rsl_msg;
7135 var DchanTuple dt;
7136 var BSSAP_N_CONNECT_ind rx_c_ind;
7137
7138 /* change Timeslot 6 before f_init() starts RSL */
7139 f_init_vty();
7140 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7141 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7142
7143 f_init(1, false);
7144 f_sleep(1.0);
7145
7146 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7147
7148 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7149 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7150 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7151 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7152
7153 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7154 f_sleep(1.0);
7155 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7156 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7157
7158 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7159 * on CCCH+SDCCH4+CBCH) */
7160 var integer i;
7161 for (i := 0; i < 3; i := i + 1) {
7162 dt := f_est_dchan('23'O, i, '00010203040506'O);
7163 }
7164
7165 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7166 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7167 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7168 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7169
7170 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7171 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7172
7173 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7174 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7175 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7176 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7177
7178 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7179 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7180 dt.sccp_conn_id := rx_c_ind.connectionId;
7181 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7182
7183 /* Instruct BSC to clear channel */
7184 var BssmapCause cause := 0;
7185 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7186 f_exp_chan_rel_and_clear(dt, 0);
7187
7188 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7189 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7190 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7191 f_sleep(1.0);
7192 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7193
7194 /* clean up config */
7195 f_ts_set_chcomb(0, 0, 6, "PDCH");
7196
7197 f_shutdown_helper();
7198}
7199
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007200/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7201 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7202 it as TCH directly instead. SYS#5309. */
7203testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7204 var RSL_Message rsl_unused, rsl_msg;
7205 var DchanTuple dt;
7206 var BSSAP_N_CONNECT_ind rx_c_ind;
7207 var integer i;
7208
7209 /* change Timeslot 6 before f_init() starts RSL */
7210 f_init_vty();
7211 for (i := 1; i < 8; i := i + 1) {
7212 if (i == 6) {
7213 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7214 } else {
7215 f_ts_set_chcomb(0, 0, i, "PDCH");
7216 }
7217 }
7218 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7219
7220 f_init(1, false);
7221 f_sleep(1.0);
7222
7223 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7224
7225 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7226 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7227 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7228 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7229
7230 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7231 f_sleep(1.0);
7232 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7233 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7234
7235 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7236 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007237 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007238 for (i := 0; i < 3; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007239 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007240 }
7241
7242 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007243 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007244 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7245 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7246
7247 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7248 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7249
7250 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7251 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7252 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7253 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7254
7255 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7256 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7257 dt.sccp_conn_id := rx_c_ind.connectionId;
7258 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7259
7260 /* Instruct BSC to clear channel */
7261 var BssmapCause cause := 0;
7262 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7263 f_exp_chan_rel_and_clear(dt, 0);
7264
7265 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7266 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7267 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7268 f_sleep(1.0);
7269 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7270
7271 /* clean up config */
7272 f_ts_reset_chcomb(0);
7273 /* TODO: clean up other channels? */
7274
7275 f_shutdown_helper();
7276}
7277
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007278/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7279testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7280 var RSL_Message rsl_unused, rsl_msg;
7281 var DchanTuple dt;
7282 var BSSAP_N_CONNECT_ind rx_c_ind;
7283 var GsmRrMessage rr;
7284
7285 /* change Timeslot 6 before f_init() starts RSL */
7286 f_init_vty();
7287 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7288 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7289
7290 f_init(1, false);
7291 f_sleep(1.0);
7292
7293 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7294
7295 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7296 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7297 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7298 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7299
7300 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7301 f_sleep(1.0);
7302 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7303 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7304
7305 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7306 * on CCCH+SDCCH4+CBCH) */
7307 var integer i;
7308 for (i := 0; i < 3; i := i + 1) {
7309 dt := f_est_dchan('23'O, i, '00010203040506'O);
7310 }
7311
7312 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7313 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7314 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7315 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7316
7317 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7318 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7319
7320 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7321 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7322 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7323 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7324 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7325 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7326 }
7327
7328 /* FIXME? Currently the TS stays in state BORKEN: */
7329
7330 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7331 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7332 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7333 * f_sleep(1.0);
7334 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7335 */
7336
7337 /* clean up config */
7338 f_ts_set_chcomb(0, 0, 6, "PDCH");
7339
7340 f_shutdown_helper();
7341}
7342
Stefan Sperling0796a822018-10-05 13:01:39 +02007343testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007344 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007345 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7346 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7347 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007348 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007349}
7350
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007351testcase TC_chopped_ipa_payload() runs on test_CT {
7352 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7353 /* TODO: mp_bsc_ctrl_port does not work yet */};
7354 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7355 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7356 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007357 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007358}
7359
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007360/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7361 the BTS does autonomous MS power control loop */
7362testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7363 var MSC_ConnHdlr vc_conn;
7364 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7365 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7366 pars.exp_ms_power_params := true;
7367
7368 f_init(1, true);
7369 f_sleep(1.0);
7370 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7371 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007372 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007373}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007374
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007375/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7376testcase TC_c0_power_red_mode() runs on test_CT {
7377 f_init(1);
7378
7379 for (var integer red := 6; red >= 0; red := red - 2) {
7380 /* Configure BCCH carrier power reduction mode via the VTY */
7381 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7382
7383 /* Expect Osmocom specific BS Power Control message on the RSL */
7384 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7385 chan_nr := t_RslChanNr_BCCH(0),
7386 bs_power := tr_RSL_IE_BS_Power(red / 2));
7387 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7388 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7389
7390 /* Additionally verify the applied value over the CTRL interface */
7391 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7392 if (cred != int2str(red)) {
7393 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7394 cred, " (expected ", red, ")");
7395 }
7396 }
7397
7398 f_shutdown_helper();
7399}
7400
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007401/***********************************************************************
7402 * MSC Pooling
7403 ***********************************************************************/
7404
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007405template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007406 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 +02007407
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007408private 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 +02007409runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007410 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007411 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007412 f_logp(BSCVTY, "Got RSL RR Release");
7413 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007414 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007415 f_logp(BSCVTY, "Got RSL Deact SACCH");
7416 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007417 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007418 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007419 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7420 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007421 break;
7422 }
7423 }
7424}
7425
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007426friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7427 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007428runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007429 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007430 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7431 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007432 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007433 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007434 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007435 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007436 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007437 }
7438 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007439 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007440 /* Also drop the SCCP connection */
7441 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7442 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007443 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007444 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007445 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7446 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007447 }
7448 }
7449}
7450
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007451private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7452 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007453runs on MSC_ConnHdlr {
7454 timer T := 10.0;
7455 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7456
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007457 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007458 f_create_bssmap_exp(l3_enc);
7459
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007460 /* RSL_Emulation.f_chan_est() on rsl_pt:
7461 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007462 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7463 */
7464 var RSL_Message rx_rsl;
7465 var GsmRrMessage rr;
7466
7467 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007468 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007469 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007470 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007471 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7472 */
7473 timer Tt := 10.0;
7474
7475 /* request a channel to be established */
7476 Tt.start;
7477 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007478 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007479 Tt.stop;
7480 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007481 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007482 setverdict(fail, "Unexpected RSL message on DCHAN");
7483 mtc.stop;
7484 }
7485 [] Tt.timeout {
7486 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7487 mtc.stop;
7488 }
7489 }
7490 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7491 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007492 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007493
7494
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007495 if (expect_bssmap_l3) {
7496 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7497 var template PDU_BSSAP exp_l3_compl;
7498 exp_l3_compl := tr_BSSMAP_ComplL3()
7499 if (g_pars.aoip == false) {
7500 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7501 } else {
7502 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7503 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007504
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007505 var PDU_BSSAP bssap;
7506 T.start;
7507 alt {
7508 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7509 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7510 log("rx exp_l3_compl = ", bssap);
7511 }
7512 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7513 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7514 }
7515 [] T.timeout {
7516 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7517 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007518 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007519
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007520 /* start ciphering, if requested */
7521 if (ispresent(g_pars.encr)) {
7522 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007523 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007524 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007525 }
7526
7527 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007528 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007529 }
7530 setverdict(pass);
7531 f_sleep(1.0);
7532}
7533
7534private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7535 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7536 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007537 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007538 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007539 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007540 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007541 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007542 }
7543}
7544
7545/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7546private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7547 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007548 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7549 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7550 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7551 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 +02007552}
7553testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7554
7555 f_init(1, true);
7556 f_sleep(1.0);
7557 var MSC_ConnHdlr vc_conn;
7558 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007559
7560 f_ctrs_msc_init();
7561
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007562 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7563 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007564
7565 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007566 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007567}
7568
7569/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7570/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7571 * just as well using only RSL. */
7572testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7573
7574 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7575 f_sleep(1.0);
7576
7577 /* Control which MSC gets chosen next by the round-robin, otherwise
7578 * would be randomly affected by which other tests ran before this. */
7579 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7580
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007581 f_ctrs_msc_init();
7582
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007583 var MSC_ConnHdlr vc_conn1;
7584 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7585 pars1.mscpool.rsl_idx := 0;
7586 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7587 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7588 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007589 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007590
7591 var MSC_ConnHdlr vc_conn2;
7592 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7593 pars2.mscpool.rsl_idx := 1;
7594 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7595 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7596 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007597 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007598
7599 /* Test round-robin wrap to the first MSC */
7600 var MSC_ConnHdlr vc_conn3;
7601 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7602 pars3.mscpool.rsl_idx := 2;
7603 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7604 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7605 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007606 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007607 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007608}
7609
7610/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7611 * (configured in osmo-bsc.cfg). */
7612/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7613 * just as well using only RSL. */
7614testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7615
7616 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7617 f_sleep(1.0);
7618
7619 /* Control which MSC gets chosen next by the round-robin, otherwise
7620 * would be randomly affected by which other tests ran before this. */
7621 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7622
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007623 f_ctrs_msc_init();
7624
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007625 var MSC_ConnHdlr vc_conn1;
7626 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7627 pars1.mscpool.rsl_idx := 0;
7628 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7629 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7630 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007631 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007632
7633 var MSC_ConnHdlr vc_conn2;
7634 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7635 pars2.mscpool.rsl_idx := 1;
7636 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7637 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7638 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007639 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007640
7641 /* Test round-robin wrap to the first MSC */
7642 var MSC_ConnHdlr vc_conn3;
7643 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7644 pars3.mscpool.rsl_idx := 2;
7645 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7646 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7647 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007648 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007649 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007650}
7651
7652/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7653 * (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
7654 * NULL-NRI setting is stronger than that. */
7655/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7656 * just as well using only RSL. */
7657testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7658
7659 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7660 f_sleep(1.0);
7661
7662 /* Control which MSC gets chosen next by the round-robin, otherwise
7663 * would be randomly affected by which other tests ran before this. */
7664 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7665
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007666 f_ctrs_msc_init();
7667
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007668 var MSC_ConnHdlr vc_conn1;
7669 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7670 pars1.mscpool.rsl_idx := 0;
7671 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7672 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7673 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007674 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007675
7676 var MSC_ConnHdlr vc_conn2;
7677 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7678 pars2.mscpool.rsl_idx := 1;
7679 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7680 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7681 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007682 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007683
7684 /* Test round-robin wrap to the first MSC */
7685 var MSC_ConnHdlr vc_conn3;
7686 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7687 pars3.mscpool.rsl_idx := 2;
7688 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7689 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7690 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007691 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007692 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007693}
7694
7695/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7696 * assigned to any MSC (configured in osmo-bsc.cfg). */
7697/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7698 * just as well using only RSL. */
7699testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7700
7701 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7702 f_sleep(1.0);
7703
7704 /* Control which MSC gets chosen next by the round-robin, otherwise
7705 * would be randomly affected by which other tests ran before this. */
7706 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7707
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007708 f_ctrs_msc_init();
7709
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007710 var MSC_ConnHdlr vc_conn1;
7711 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7712 pars1.mscpool.rsl_idx := 0;
7713 /* An NRI that is not assigned to any MSC */
7714 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7715 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7716 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007717 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007718
7719 var MSC_ConnHdlr vc_conn2;
7720 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7721 pars2.mscpool.rsl_idx := 1;
7722 /* An NRI that is not assigned to any MSC */
7723 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7724 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7725 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007726 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007727
7728 /* Test round-robin wrap to the first MSC */
7729 var MSC_ConnHdlr vc_conn3;
7730 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7731 pars3.mscpool.rsl_idx := 2;
7732 /* An NRI that is not assigned to any MSC */
7733 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7734 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7735 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007736 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007737 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007738}
7739
7740/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7741 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7742/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7743 * just as well using only RSL. */
7744testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7745
7746 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7747 f_sleep(1.0);
7748
7749 /* Control which MSC gets chosen next by the round-robin, otherwise
7750 * would be randomly affected by which other tests ran before this. */
7751 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7752
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007753 f_ctrs_msc_init();
7754
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007755 var MSC_ConnHdlr vc_conn1;
7756 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7757 pars1.mscpool.rsl_idx := 0;
7758 /* An NRI that is assigned to an unconnected MSC */
7759 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7760 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7761 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007762 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7763 f_ctrs_msc_add(0, "mscpool:subscr:new");
7764 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007765
7766 var MSC_ConnHdlr vc_conn2;
7767 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7768 pars2.mscpool.rsl_idx := 1;
7769 /* An NRI that is assigned to an unconnected MSC */
7770 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7771 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7772 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007773 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7774 f_ctrs_msc_add(1, "mscpool:subscr:new");
7775 f_ctrs_msc_verify();
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 /* An NRI that is assigned to an unconnected MSC */
7782 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7783 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7784 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007785 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7786 f_ctrs_msc_add(0, "mscpool:subscr:new");
7787 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007788 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007789}
7790
7791/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7792 * osmo-bsc.cfg). */
7793/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7794 * just as well using only RSL. */
7795testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7796
7797 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7798 f_sleep(1.0);
7799
7800 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7801 * this is not using round-robin. */
7802 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7803
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007804 f_ctrs_msc_init();
7805
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007806 var MSC_ConnHdlr vc_conn1;
7807 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7808 pars1.mscpool.rsl_idx := 0;
7809 /* An NRI of the second MSC's range (256-511) */
7810 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7811 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7812 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007813 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007814
7815 var MSC_ConnHdlr vc_conn2;
7816 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7817 pars2.mscpool.rsl_idx := 1;
7818 /* An NRI of the second MSC's range (256-511) */
7819 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7820 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7821 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007822 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007823
7824 var MSC_ConnHdlr vc_conn3;
7825 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7826 pars3.mscpool.rsl_idx := 2;
7827 /* An NRI of the second MSC's range (256-511) */
7828 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7829 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7830 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007831 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007832 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007833}
7834
7835/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7836 * while a round-robin remains unaffected by that. */
7837/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7838 * just as well using only RSL. */
7839testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7840
7841 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7842 f_sleep(1.0);
7843
7844 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7845 * this is not using round-robin. */
7846 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7847
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007848 f_ctrs_msc_init();
7849
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007850 var MSC_ConnHdlr vc_conn1;
7851 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7852 pars1.mscpool.rsl_idx := 0;
7853 /* An NRI of the third MSC's range (512-767) */
7854 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7855 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7856 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007857 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007858
7859 var MSC_ConnHdlr vc_conn2;
7860 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7861 pars2.mscpool.rsl_idx := 1;
7862 /* An NRI of the third MSC's range (512-767) */
7863 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7864 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7865 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007866 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007867
7868 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7869 var MSC_ConnHdlr vc_conn3;
7870 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7871 pars3.mscpool.rsl_idx := 2;
7872 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7873 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7874 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007875 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007876 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007877}
7878
7879/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
7880/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7881 * just as well using only RSL. */
7882testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
7883
7884 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7885 f_sleep(1.0);
7886
7887 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
7888 * instead, and hits msc 0. */
7889 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7890
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007891 f_ctrs_msc_init();
7892
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007893 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
7894 var MSC_ConnHdlr vc_conn1;
7895 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7896 pars1.mscpool.rsl_idx := 0;
7897 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
7898 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7899 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007900 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007901
7902 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
7903 var MSC_ConnHdlr vc_conn2;
7904 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7905 pars2.mscpool.rsl_idx := 1;
7906 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
7907 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7908 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007909 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007910 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007911}
7912
7913/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
7914 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7915private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
7916 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7917 //cid_list := { cIl_allInBSS := ''O };
7918 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7919 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7920 var BSSAP_N_UNITDATA_req paging;
7921 var hexstring imsi := '001010000000123'H;
7922
7923 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7924
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007925 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007926 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
7927 BSSAP.send(paging);
7928
7929 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7930 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7931 * channel number is picked here. */
7932 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7933 f_rslem_register(0, new_chan_nr);
7934 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
7935 f_rslem_unregister(0, new_chan_nr);
7936
7937 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
7938 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007939 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007940 f_sleep(1.0);
7941}
7942testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
7943 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7944 f_sleep(1.0);
7945
7946 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7947 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7948 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7949
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007950 f_ctrs_msc_init();
7951
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007952 var MSC_ConnHdlr vc_conn1;
7953 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7954 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007955 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7956 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007957 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
7958 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007959 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007960 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007961}
7962
7963/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
7964 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7965private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
7966 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7967 //cid_list := { cIl_allInBSS := ''O };
7968 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7969 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7970 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01007971 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007972 var BSSAP_N_UNITDATA_req paging;
7973
7974 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7975
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007976 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007977 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
7978 BSSAP.send(paging);
7979
7980 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7981 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7982 * channel number is picked here. */
7983 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7984 f_rslem_register(0, new_chan_nr);
7985 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
7986 f_rslem_unregister(0, new_chan_nr);
7987
7988 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
7989 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
7990 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007991 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 +02007992 f_sleep(1.0);
7993}
7994testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
7995 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7996 f_sleep(1.0);
7997
7998 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7999 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8000 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8001
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008002 f_ctrs_msc_init();
8003
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008004 var MSC_ConnHdlr vc_conn1;
8005 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8006 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008007 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8008 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008009 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8010 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008011 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008012 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008013}
8014
8015/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8016/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8017 * just as well using only RSL. */
8018testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8019
8020 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8021 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008022 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8023 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008024
8025 /* Control which MSC gets chosen next by the round-robin, otherwise
8026 * would be randomly affected by which other tests ran before this. */
8027 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8028
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008029 f_ctrs_msc_init();
8030
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008031 var MSC_ConnHdlr vc_conn1;
8032 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8033 pars1.mscpool.rsl_idx := 0;
8034 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8035 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8036 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008037 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008038
8039 var MSC_ConnHdlr vc_conn2;
8040 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8041 pars2.mscpool.rsl_idx := 1;
8042 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8043 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8044 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008045 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008046
8047 var MSC_ConnHdlr vc_conn3;
8048 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8049 pars3.mscpool.rsl_idx := 2;
8050 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
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(0, "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/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8058 * TMSI NRI. */
8059testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8060
8061 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8062 f_sleep(1.0);
8063
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008064 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8065 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8066
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008067 /* Control which MSC gets chosen next by the round-robin, otherwise
8068 * would be randomly affected by which other tests ran before this. */
8069 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8070
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008071 f_ctrs_msc_init();
8072
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008073 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8074 var MSC_ConnHdlr vc_conn1;
8075 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8076 pars1.mscpool.rsl_idx := 0;
8077 /* An NRI of the second MSC's range (256-511) */
8078 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8079 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8080 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008081 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008082
8083 var MSC_ConnHdlr vc_conn2;
8084 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8085 pars2.mscpool.rsl_idx := 1;
8086 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8087 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8088 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008089 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008090
8091 var MSC_ConnHdlr vc_conn3;
8092 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8093 pars3.mscpool.rsl_idx := 2;
8094 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8095 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8096 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008097 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008098 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008099}
8100
Philipp Maier783681c2020-07-16 16:47:06 +02008101/* Allow/Deny emergency calls globally via VTY */
8102private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8103 f_vty_enter_cfg_msc(BSCVTY, 0);
8104 if (allow) {
8105 f_vty_transceive(BSCVTY, "allow-emergency allow");
8106 } else {
8107 f_vty_transceive(BSCVTY, "allow-emergency deny");
8108 }
8109 f_vty_transceive(BSCVTY, "exit");
8110 f_vty_transceive(BSCVTY, "exit");
8111}
8112
8113/* Allow/Deny emergency calls per BTS via VTY */
8114private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8115 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8116 if (allow) {
8117 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8118 } else {
8119 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8120 }
8121 f_vty_transceive(BSCVTY, "exit");
8122 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008123 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008124}
8125
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008126/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8127private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8128 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8129 if (allow) {
8130 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8131 } else {
8132 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8133 }
8134 f_vty_transceive(BSCVTY, "exit");
8135 f_vty_transceive(BSCVTY, "exit");
8136 f_vty_transceive(BSCVTY, "exit");
8137}
8138
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008139/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8140private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8141 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8142 if (allow) {
8143 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8144 } else {
8145 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8146 }
8147 f_vty_transceive(BSCVTY, "exit");
8148 f_vty_transceive(BSCVTY, "exit");
8149 f_vty_transceive(BSCVTY, "exit");
8150}
8151
Philipp Maier783681c2020-07-16 16:47:06 +02008152/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8153private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8154 var PDU_ML3_MS_NW emerg_setup;
8155 var octetstring emerg_setup_enc;
8156 var RSL_Message emerg_setup_data_ind;
8157
8158 f_establish_fully(omit, omit);
8159
8160 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8161 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8162 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8163
8164 RSL.send(emerg_setup_data_ind);
8165}
8166
8167/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8168 * CALLS are permitted by the BSC config. */
8169private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8170 var PDU_BSSAP emerg_setup_data_ind_bssap;
8171 var PDU_ML3_MS_NW emerg_setup;
8172 timer T := 3.0;
8173
8174 f_assignment_emerg_setup()
8175
8176 T.start;
8177 alt {
8178 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8179 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8180 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8181 setverdict(fail, "no emergency setup");
8182 }
8183 }
8184 [] BSSAP.receive {
8185 setverdict(fail, "unexpected BSSAP message!");
8186 }
8187 [] T.timeout {
8188 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8189 }
8190 }
8191
8192 setverdict(pass);
8193}
8194
8195/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8196 * forbidden by the BSC config. */
8197private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8198 var PDU_BSSAP emerg_setup_data_ind_bssap;
8199 timer T := 3.0;
8200
8201 f_assignment_emerg_setup()
8202
8203 T.start;
8204 alt {
8205 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8206 setverdict(pass);
8207 }
8208 [] RSL.receive {
8209 setverdict(fail, "unexpected RSL message!");
8210 }
8211 [] T.timeout {
8212 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8213 }
8214 }
8215}
8216
8217/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8218testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8219 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8220 var MSC_ConnHdlr vc_conn;
8221
8222 f_init(1, true);
8223 f_sleep(1.0);
8224
8225 f_vty_allow_emerg_msc(true);
8226 f_vty_allow_emerg_bts(true, 0);
8227 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8228 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008229 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008230}
8231
8232/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8233testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8234 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8235 var MSC_ConnHdlr vc_conn;
8236
8237 f_init(1, true);
8238 f_sleep(1.0);
8239
8240 f_vty_allow_emerg_msc(false);
8241 f_vty_allow_emerg_bts(true, 0);
8242 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8243 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008244 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008245}
8246
8247/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8248testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8249 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8250 var MSC_ConnHdlr vc_conn;
8251
8252 /* Note: This simulates a spec violation by the MS, correct MS
8253 * implementations would not try to establish an emergency call because
8254 * the system information tells in advance that emergency calls are
8255 * not forbidden */
8256
8257 f_init(1, true);
8258 f_sleep(1.0);
8259
8260 f_vty_allow_emerg_msc(true);
8261 f_vty_allow_emerg_bts(false, 0);
8262 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8263 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008264 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008265}
8266
Philipp Maier82812002020-08-13 18:48:27 +02008267/* Test what happens when an emergency call arrives while all TCH channels are
8268 * busy, the BSC is expected to terminate one call in favor of the incoming
8269 * emergency call */
8270testcase TC_emerg_premption() runs on test_CT {
8271 var ASP_RSL_Unitdata rsl_ud;
8272 var integer i;
8273 var integer chreq_total, chreq_nochan;
8274 var RSL_Message rx_rsl;
8275 var RslChannelNr chan_nr;
8276
8277 f_init(1);
8278 f_sleep(1.0);
8279
8280 f_vty_allow_emerg_msc(true);
8281 f_vty_allow_emerg_bts(true, 0);
8282
8283 /* Fill up all channels on the BTS */
8284 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8285 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8286 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8287 chan_nr := f_chreq_act_ack('33'O, i);
8288 }
8289 IPA_RSL[0].clear;
8290 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8291 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8292
8293 /* Send Channel request for emegergency call */
8294 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8295
8296 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8297 chan_nr := valueof(t_RslChanNr_Bm(1));
8298 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8299
8300 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8301 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8302 chan_nr := rx_rsl.ies[0].body.chan_nr;
8303 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8304 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008305
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008306 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008307}
8308
8309/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008310private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008311private type record FHParamsTs {
8312 boolean enabled,
8313 uint6_t hsn,
8314 uint6_t maio,
8315 ArfcnList ma
8316};
8317
8318/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008319private type record FHParamsTrx {
8320 GsmArfcn arfcn,
8321 FHParamsTs ts[8]
8322};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008323
8324/* Randomly generate the hopping parameters for the given timeslot numbers */
8325private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8326runs on test_CT return FHParamsTrx {
8327 var FHParamsTrx fhp;
8328
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008329 /* Generate a random ARFCN, including ARFCN 0 */
8330 fhp.arfcn := f_rnd_int(3);
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008331
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008332 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8333 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008334 fhp.ts[tn].enabled := false;
8335 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008336 continue;
8337 }
8338
8339 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008340 fhp.ts[tn].hsn := f_rnd_int(64);
8341 fhp.ts[tn].maio := f_rnd_int(64);
8342 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008343
8344 /* Random Mobile Allocation (hopping channels) */
8345 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8346 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8347 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008348 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008349 }
8350
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008351 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008352 }
8353
8354 log("f_TC_fh_params_gen(): ", fhp);
8355 return fhp;
8356}
8357
8358/* Make sure that the given Channel Description IE matches the hopping configuration */
8359private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8360{
8361 var template (present) ChannelDescription tr_cd;
8362 var template (present) MaioHsn tr_maio_hsn;
8363 var uint3_t tn := cd.chan_nr.tn;
8364
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008365 if (fhp.ts[tn].enabled) {
8366 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008367 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8368 } else {
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008369 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008370 }
8371
8372 if (not match(cd, tr_cd)) {
8373 setverdict(fail, "Channel Description IE does not match: ",
8374 cd, " vs expected ", tr_cd);
8375 }
8376}
8377
8378/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8379private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8380 in MobileAllocationLV ma)
8381{
8382 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8383
8384 if (not match(ma, tr_ma)) {
8385 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8386 tn, "): ", ma, " vs expected: ", tr_ma);
8387 } else {
8388 setverdict(pass);
8389 }
8390}
8391
8392private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8393 in MobileAllocationLV ma)
8394return template MobileAllocationLV {
8395 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008396 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008397 return { len := 0, ma := ''B };
8398 }
8399
8400 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8401 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8402 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008403
8404 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008405 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8406 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8407 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008408 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008409 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008410 }
8411 }
8412
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008413 /* Take ARFCN of the TRX itself into account */
8414 full_mask[fhp.arfcn] := '1'B;
8415
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008416 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008417 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8418 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008419 }
8420
8421 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008422 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008423 if (full_mask[i] != '1'B)
8424 { continue; }
8425
8426 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8427 if (slot_mask[i] == '1'B) {
8428 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008429 } else {
8430 ma_mask := ma_mask & '0'B;
8431 }
8432 }
8433
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008434 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8435 if (full_mask[0] == '1'B) {
8436 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8437 if (slot_mask[0] == '1'B) {
8438 ma_mask := ma_mask & '1'B;
8439 } else {
8440 ma_mask := ma_mask & '0'B;
8441 }
8442 }
8443
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008444 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008445 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008446 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8447
8448 return { len := ma_mask_len, ma := ma_mask };
8449}
8450
8451/* Configure the hopping parameters in accordance with the given record */
8452private function f_TC_fh_params_set(in FHParamsTrx fhp,
8453 uint8_t bts_nr := 0,
8454 uint8_t trx_nr := 0)
8455runs on test_CT {
8456 /* Enter the configuration node for the given BTS/TRX numbers */
8457 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8458
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008459 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn));
8460
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008461 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008462 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8463
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008464 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008465 f_vty_transceive(BSCVTY, "hopping enabled 0");
8466 f_vty_transceive(BSCVTY, "exit"); /* go back */
8467 continue;
8468 }
8469
8470 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008471 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8472 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008473
8474 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008475 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8476 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008477 }
8478
8479 f_vty_transceive(BSCVTY, "hopping enabled 1");
8480 f_vty_transceive(BSCVTY, "exit"); /* go back */
8481 }
8482
8483 f_vty_transceive(BSCVTY, "end");
8484}
8485
8486/* Disable frequency hopping on all timeslots */
8487private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8488 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008489 uint8_t trx_nr := 0,
8490 GsmArfcn arfcn := 871)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008491runs on test_CT {
8492 /* Enter the configuration node for the given BTS/TRX numbers */
8493 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8494
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008495 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn));
8496
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008497 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008498 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8499
8500 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008501 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8502 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008503 }
8504
8505 f_vty_transceive(BSCVTY, "hopping enabled 0");
8506 f_vty_transceive(BSCVTY, "exit"); /* go back */
8507 }
8508
8509 f_vty_transceive(BSCVTY, "end");
8510 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8511}
8512
8513/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8514 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8515testcase TC_fh_params_chan_activ() runs on test_CT {
8516 var FHParamsTrx fhp := f_TC_fh_params_gen();
8517 var RSL_Message rsl_msg;
8518 var RSL_IE_Body ie;
8519
8520 f_init_vty();
8521
8522 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8523 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8524
8525 f_init(1);
8526
8527 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8528 for (var integer i := 0; i < 9; i := i + 1) {
8529 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8530 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8531
8532 /* Make sure that Channel Identification IE is present */
8533 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8534 setverdict(fail, "RSL Channel Identification IE is absent");
8535 continue;
8536 }
8537
8538 /* Make sure that hopping parameters (HSN/MAIO) match */
8539 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8540
8541 /* "Mobile Allocation shall be included but empty" - let's check this */
8542 if (ie.chan_ident.ma.v.len != 0) {
8543 setverdict(fail, "Mobile Allocation IE is not empty: ",
8544 ie.chan_ident.ma, ", despite it shall be");
8545 continue;
8546 }
8547 }
8548
8549 /* Disable frequency hopping */
8550 f_TC_fh_params_unset(fhp);
8551
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008552 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008553}
8554
8555/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8556testcase TC_fh_params_imm_ass() runs on test_CT {
8557 var FHParamsTrx fhp := f_TC_fh_params_gen();
8558 var RSL_Message rsl_msg;
8559 var RSL_IE_Body ie;
8560
8561 f_init_vty();
8562
8563 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8564 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8565
8566 f_init(1);
8567
8568 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8569 for (var integer i := 0; i < 9; i := i + 1) {
8570 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8571 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8572
8573 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8574 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8575
8576 /* Make sure that Full Immediate Assign Info IE is present */
8577 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8578 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8579 continue;
8580 }
8581
8582 /* Decode the actual Immediate Assignment message */
8583 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8584 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8585 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8586 continue;
8587 }
8588
8589 /* Make sure that hopping parameters (HSN/MAIO) match */
8590 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8591
8592 /* Make sure that the Mobile Allocation IE matches */
8593 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8594 rr_msg.payload.imm_ass.mobile_allocation);
8595 }
8596
8597 /* Disable frequency hopping */
8598 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008599
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008600 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008601}
8602
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008603/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8604testcase TC_fh_params_assignment_cmd() runs on test_CT {
8605 var FHParamsTrx fhp := f_TC_fh_params_gen();
8606 var RSL_Message rsl_msg;
8607 var RSL_IE_Body ie;
8608
8609 f_init_vty();
8610
8611 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8612 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8613
8614 f_init(1);
8615
8616 /* HACK: work around "Couldn't find Expect for CRCX" */
8617 vc_MGCP.stop;
8618
8619 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8620 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8621
8622 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8623 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8624 for (var integer i := 0; i < 3; i := i + 1) {
8625 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8626 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8627
8628 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8629 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8630 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8631
8632 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8633 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8634 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8635
8636 /* Make sure that L3 Information IE is present */
8637 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8638 setverdict(fail, "RSL L3 Information IE is absent");
8639 continue;
8640 }
8641
8642 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8643 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8644 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8645 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8646 continue;
8647 }
8648
8649 /* Make sure that hopping parameters (HSN/MAIO) match */
8650 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8651 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8652
8653 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8654 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008655 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008656 continue;
8657 }
8658
8659 /* Make sure that the Mobile Allocation IE matches (if present) */
8660 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8661 if (chan_desc.h and ma_present) {
8662 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8663 l3_msg.payload.ass_cmd.mobile_allocation.v);
8664 } else if (chan_desc.h and not ma_present) {
8665 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8666 continue;
8667 } else if (not chan_desc.h and ma_present) {
8668 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8669 continue;
8670 }
8671 }
8672
8673 /* Give the IUT some time to release all channels */
8674 f_sleep(3.0);
8675
8676 /* Disable frequency hopping */
8677 f_TC_fh_params_unset(fhp);
8678
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008679 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008680}
8681
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008682/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8683private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8684runs on test_CT {
8685 var RSL_Message rsl_msg;
8686 var RSL_IE_Body ie;
8687 var DchanTuple dt;
8688
8689 /* Establish a dedicated channel, so we can trigger handover */
8690 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8691
8692 /* Trigger handover from BTS0 to BTS1 */
8693 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8694 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8695
8696 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8697 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8698
8699 /* ACKnowledge channel activation and expect (RR) Handover Command */
8700 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8701 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8702
8703 /* Make sure that L3 Information IE is present */
8704 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8705 setverdict(fail, "RSL L3 Information IE is absent");
8706 return;
8707 }
8708
8709 /* Decode the L3 message and make sure it is (RR) Handover Command */
8710 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8711 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8712 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8713 return;
8714 }
8715
8716 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8717 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8718 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8719 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8720 return;
8721 }
8722
8723 /* Make sure that hopping parameters (HSN/MAIO) match */
8724 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8725
8726 /* Make sure that Cell Channel Description IE is present */
8727 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8728 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8729 return;
8730 }
8731
8732 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8733 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8734 if (ma_present) {
8735 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8736 l3_msg.payload.ho_cmd.mobile_allocation.v);
8737 } else {
8738 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8739 return;
8740 }
8741}
8742testcase TC_fh_params_handover_cmd() runs on test_CT {
8743 var FHParamsTrx fhp := f_TC_fh_params_gen();
8744
8745 f_init_vty();
8746
8747 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8748 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8749
8750 f_vty_transceive(BSCVTY, "timeslot 0");
8751 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8752 f_vty_transceive(BSCVTY, "exit"); /* go back */
8753
8754 f_vty_transceive(BSCVTY, "timeslot 1");
8755 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8756 f_vty_transceive(BSCVTY, "end"); /* we're done */
8757
8758 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8759 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8760
8761 f_init(2);
8762
8763 f_TC_fh_params_handover_cmd(fhp);
8764
8765 /* Disable frequency hopping on BTS1 */
8766 f_TC_fh_params_unset(fhp, 1);
8767
8768 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8769 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8770
8771 f_vty_transceive(BSCVTY, "timeslot 0");
8772 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8773 f_vty_transceive(BSCVTY, "exit"); /* go back */
8774
8775 f_vty_transceive(BSCVTY, "timeslot 1");
8776 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8777 f_vty_transceive(BSCVTY, "end"); /* we're done */
8778
8779 f_shutdown_helper();
8780}
8781
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008782/* Verify the hopping parameters in System Information Type 4 */
8783testcase TC_fh_params_si4_cbch() runs on test_CT {
8784 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8785 var ASP_RSL_Unitdata rx_rsl_ud;
8786 timer T := 5.0;
8787
8788 f_init_vty();
8789
8790 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
8791 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8792
8793 f_vty_transceive(BSCVTY, "timeslot 0");
8794 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8795 f_vty_transceive(BSCVTY, "exit"); /* go back */
8796
8797 f_vty_transceive(BSCVTY, "timeslot 1");
8798 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
8799 f_vty_transceive(BSCVTY, "end"); /* we're done */
8800
8801 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8802 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8803
8804 f_init(1);
8805
8806 T.start;
8807 alt {
8808 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
8809 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
8810 var SystemInformation si := dec_SystemInformation(ie.other.payload);
8811
8812 /* Make sure that what we decoded is System Information Type 4 */
8813 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
8814 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
8815 repeat;
8816 }
8817
8818 /* Make sure that CBCH Channel Description IE is present */
8819 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
8820 setverdict(fail, "CBCH Channel Description IE is absent");
8821 break;
8822 }
8823
8824 /* Finally, check the hopping parameters (HSN, MAIO) */
8825 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
8826 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8827
8828 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
8829 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
8830 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
8831 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8832 break;
8833 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
8834 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8835 si.payload.si4.cbch_mobile_alloc.v);
8836 }
8837 }
8838 [] IPA_RSL[0].receive { repeat; }
8839 [] T.timeout {
8840 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
8841 }
8842 }
8843
8844 /* Disable frequency hopping */
8845 f_TC_fh_params_unset(fhp);
8846
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008847 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008848 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8849
8850 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008851 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008852 f_vty_transceive(BSCVTY, "exit"); /* go back */
8853
8854 f_vty_transceive(BSCVTY, "timeslot 1");
8855 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8856 f_vty_transceive(BSCVTY, "end"); /* we're done */
8857
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008858 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008859}
8860
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008861template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
8862 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
8863
8864private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
8865 template (present) BSSLAP_PDU expect_bsslap)
8866{
8867 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
8868 if (not match(bsslap, expect_bsslap)) {
8869 log("EXPECTING BSSLAP: ", expect_bsslap);
8870 log("GOT BSSLAP: ", bsslap);
8871 setverdict(fail, "BSSLAP is not as expected");
8872 mtc.stop;
8873 }
8874 setverdict(pass);
8875}
8876
8877/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
8878const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
8879
8880private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
8881 var PDU_BSSAP_LE rx_bsslap;
8882 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
8883 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
8884}
8885
8886/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8887 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
8888private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
8889 f_sleep(1.0);
8890
8891 f_establish_fully(omit, omit);
8892 f_bssap_le_register_imsi(g_pars.imsi, omit);
8893
8894 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8895 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8896
8897 var PDU_BSSAP_LE plr;
8898 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8899
8900 if (not do_ta_request) {
8901 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
8902 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
8903 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
8904 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
8905 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
8906 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
8907 mtc.stop;
8908 }
8909 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
8910 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
8911 if (not match(bsslap, expect_ta_layer3)) {
8912 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
8913 log("GOT BSSLAP: ", bsslap);
8914 setverdict(fail, "BSSLAP is not as expected");
8915 mtc.stop;
8916 }
8917 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
8918 * has no need to request the TA from the BSC and directly responds. */
8919 } else {
8920 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8921 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8922 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8923 }
8924
8925 /* SMLC got the TA from the BSC, now responds with geo information data. */
8926 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8927 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8928 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8929
8930 /* The LCS was using an active A-interface conn. It should still remain active after this. */
8931 f_mo_l3_transceive();
8932
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008933 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008934
8935 f_sleep(2.0);
8936 setverdict(pass);
8937}
8938
8939/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8940 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
8941private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
8942 f_lcs_loc_req_for_active_ms(false);
8943}
8944testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
8945 var MSC_ConnHdlr vc_conn;
8946 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8947
8948 f_init(1, true);
8949 f_sleep(1.0);
8950 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
8951 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008952 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008953}
8954
8955/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8956 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
8957private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
8958 f_lcs_loc_req_for_active_ms(true);
8959}
8960testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
8961 var MSC_ConnHdlr vc_conn;
8962 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8963
8964 f_init(1, true);
8965 f_sleep(1.0);
8966 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
8967 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008968 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008969}
8970
8971/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
8972 * conn without an active lchan. */
8973private function f_clear_A_conn() runs on MSC_ConnHdlr
8974{
8975 var BssmapCause cause := 0;
8976 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
8977 BSSAP.receive(tr_BSSMAP_ClearComplete);
8978 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8979
8980 timer no_more_bssap := 5.0;
8981 no_more_bssap.start;
8982 alt {
8983 [] no_more_bssap.timeout { break; }
8984 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
8985 setverdict(fail, "Expected no more BSSAP after Clear Complete");
8986 mtc.stop;
8987 }
8988 }
8989 setverdict(pass);
8990}
8991
8992/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
8993 * for LCS, for cases where there is only an A conn without an active lchan. */
8994private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
8995{
8996 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
8997
8998 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
8999 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9000 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9001 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9002 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9003 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9004
9005 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9006 f_clear_A_conn();
9007 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9008 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9009}
9010
9011/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9012 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9013 */
9014private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9015 f_sleep(1.0);
9016
9017 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9018 f_bssap_le_register_imsi(g_pars.imsi, omit);
9019
9020 /* Register to receive the Paging Command */
9021 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9022 g_chan_nr := new_chan_nr;
9023 f_rslem_register(0, g_chan_nr);
9024
9025 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9026 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9027 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9028 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9029
9030 var PDU_BSSAP_LE plr;
9031 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9032
9033 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9034 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9035
9036 /* OsmoBSC needs to Page */
9037 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9038 f_logp(BSCVTY, "got Paging Command");
9039
9040 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9041 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009042 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);
9043 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009044
9045 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9046
9047 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9048
9049 /* SMLC got the TA from the BSC, now responds with geo information data. */
9050 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9051 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9052
9053 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9054
9055 /* The lchan is gone, the A-interface conn was created for the LCS only.
9056 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9057 f_verify_active_A_conn_and_clear();
9058
9059 f_sleep(2.0);
9060 setverdict(pass);
9061}
9062testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9063 var MSC_ConnHdlr vc_conn;
9064 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9065
9066 f_init(1, true);
9067 f_sleep(1.0);
9068
9069 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9070 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9071
9072 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9073 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009074 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009075}
9076
9077/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9078 */
9079private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9080 f_sleep(1.0);
9081
9082 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9083 f_bssap_le_register_imsi(g_pars.imsi, omit);
9084
9085 /* provoke an abort by omitting both IMSI and IMEI */
9086 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9087 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9088 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9089 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9090
9091 /* BSC tells MSC about failure */
9092 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9093 locationEstimate := omit, positioningData := omit,
9094 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9095
9096 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9097 f_verify_active_A_conn_and_clear();
9098
9099 f_sleep(2.0);
9100 setverdict(pass);
9101}
9102testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9103 var MSC_ConnHdlr vc_conn;
9104 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9105
9106 f_init(1, true);
9107 f_sleep(1.0);
9108
9109 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9110 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9111
9112 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9113 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009114 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009115}
9116
9117/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9118 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9119private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9120 f_sleep(1.0);
9121
9122 f_establish_fully(omit, omit);
9123 f_bssap_le_register_imsi(g_pars.imsi, omit);
9124
9125 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9126 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9127
9128 var PDU_BSSAP_LE plr;
9129 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9130
9131 if (do_ta) {
9132 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9133 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9134 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9135 }
9136
9137 /* SMLC fails to respond, BSC runs into timeout */
9138 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9139 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9140
9141 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9142 locationEstimate := omit, positioningData := omit,
9143 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9144
9145 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9146 f_verify_active_A_conn_and_clear();
9147
9148 f_sleep(2.0);
9149 setverdict(pass);
9150}
9151
9152/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9153 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9154private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9155 f_lcs_loc_req_for_active_ms_le_timeout(false);
9156}
9157
9158testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9159 var MSC_ConnHdlr vc_conn;
9160 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9161
9162 f_init(1, true);
9163 f_sleep(1.0);
9164 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9165 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009166 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009167}
9168
9169/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9170 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9171private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9172 f_lcs_loc_req_for_active_ms_le_timeout(true);
9173}
9174
9175testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9176 var MSC_ConnHdlr vc_conn;
9177 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9178
9179 f_init(1, true);
9180 f_sleep(1.0);
9181 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9182 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009183 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009184}
9185
9186/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9187private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9188 f_sleep(1.0);
9189
9190 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9191 f_bssap_le_register_imsi(g_pars.imsi, omit);
9192
9193 /* Register to receive the Paging Command */
9194 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9195 g_chan_nr := new_chan_nr;
9196 f_rslem_register(0, g_chan_nr);
9197
9198 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9199 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9200 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9201 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9202
9203 var PDU_BSSAP_LE plr;
9204 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9205
9206 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9207 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9208
9209 /* OsmoBSC needs to Page */
9210 var PDU_BSSAP_LE rx_bsslap;
9211 alt {
9212 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9213 f_logp(BSCVTY, "got Paging Command");
9214 repeat;
9215 }
9216 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9217 /* MS does not respond to Paging, TA Req runs into timeout. */
9218 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9219 }
9220 }
9221
9222 /* SMLC responds with failure */
9223 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9224 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9225
9226 /* BSC tells MSC about failure */
9227 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9228 locationEstimate := omit, positioningData := omit,
9229 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9230
9231 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9232 f_verify_active_A_conn_and_clear();
9233
9234 f_sleep(2.0);
9235 setverdict(pass);
9236}
9237testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9238 var MSC_ConnHdlr vc_conn;
9239 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9240
9241 f_init(1, true);
9242 f_sleep(1.0);
9243
9244 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9245 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9246
9247 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9248 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009249 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009250}
9251
9252/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9253 * over. */
9254private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9255 f_sleep(1.0);
9256
9257 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9258 f_bssap_le_register_imsi(g_pars.imsi, omit);
9259
9260 /* Register to receive the Paging Command */
9261 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9262 g_chan_nr := new_chan_nr;
9263 f_rslem_register(0, g_chan_nr);
9264
9265 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9266 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9267 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9268 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9269
9270 var PDU_BSSAP_LE plr;
9271 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9272
9273 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9274 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009275 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 +02009276 do_clear := false, expect_bssmap_l3 := true);
9277
9278 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9279 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9280
9281 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9282 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9283
9284 /* SMLC got the TA from the BSC, now responds with geo information data. */
9285 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9286 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9287 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9288
9289 /* The lchan should still exist, it was from a CM Service Request. */
9290 f_mo_l3_transceive();
9291
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009292 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009293
9294 f_sleep(2.0);
9295 setverdict(pass);
9296}
9297testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9298 var MSC_ConnHdlr vc_conn;
9299 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9300
9301 f_init(1, true);
9302 f_sleep(1.0);
9303
9304 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9305 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9306
9307 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9308 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009309 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009310}
9311
9312/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9313 * the new lchan after handover. */
9314private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9315 f_sleep(1.0);
9316
9317 f_establish_fully(omit, omit);
9318 f_bssap_le_register_imsi(g_pars.imsi, omit);
9319
9320 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9321 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9322
9323 var PDU_BSSAP_LE plr;
9324 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9325
9326 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9327 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9328
9329 var HandoverState hs := {
9330 rr_ho_cmpl_seen := false,
9331 handover_done := false,
9332 old_chan_nr := -
9333 };
9334 /* issue hand-over command on VTY */
9335 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9336 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9337 f_rslem_suspend(RSL1_PROC);
9338
9339 /* From the MGW perspective, a handover is is characterized by
9340 * performing one MDCX operation with the MGW. So we expect to see
9341 * one more MDCX during handover. */
9342 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9343
9344 alt {
9345 [] as_handover(hs);
9346 }
9347
9348 var PDU_BSSAP_LE rx_bsslap;
9349
9350 interleave {
9351 /* Expect the BSC to inform the MSC about the handover */
9352 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9353
9354 /* Expect the BSC to inform the SMLC about the handover */
9355 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9356 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9357 }
9358 }
9359
9360 /* SMLC now responds with geo information data. */
9361 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9362 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9363 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9364
9365 /* lchan still active */
9366 f_mo_l3_transceive(RSL1);
9367
9368 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009369 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009370
9371 f_sleep(2.0);
9372 setverdict(pass);
9373}
9374testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9375 var MSC_ConnHdlr vc_conn;
9376 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9377
9378 f_init(2, true);
9379 f_sleep(1.0);
9380 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9381 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009382 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009383}
9384
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009385/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9386private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9387 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9388
9389 /* Also disable attach for the single connected MSC */
9390 f_vty_msc_allow_attach(BSCVTY, { false });
9391
9392 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) ));
9393 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9394
9395 /* No MSC is found, expecting a proper release on RSL */
9396 interleave {
9397 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9398 f_logp(BSCVTY, "Got RSL RR Release");
9399 }
9400 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9401 f_logp(BSCVTY, "Got RSL Deact SACCH");
9402 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009403 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009404 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9405 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009406 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009407 }
9408 }
9409 setverdict(pass);
9410}
9411testcase TC_no_msc() runs on test_CT {
9412
9413 f_init(1, true);
9414 f_sleep(1.0);
9415 var MSC_ConnHdlr vc_conn;
9416 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9417
9418 f_ctrs_bsc_init(counternames_bsc_mscpool);
9419
9420 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9421 vc_conn.done;
9422
9423 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9424 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009425 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009426}
9427
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009428/* Dyn PDCH todo:
9429 * activate OSMO as TCH/F
9430 * activate OSMO as TCH/H
9431 * does the BSC-located PCU socket get the updated INFO?
9432 * what if no PCU is connected at the time?
9433 * is the info correct on delayed PCU (re)connect?
9434 */
Harald Welte94e0c342018-04-07 11:33:23 +02009435
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009436private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9437 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9438 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9439
9440 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9441 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9442 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9443 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9444 g_pars.ass_codec_list.codecElements[0];
9445 if (isvalue(g_pars.expect_mr_s0_s7)) {
9446 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9447 g_pars.expect_mr_s0_s7;
9448 }
9449 }
9450 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9451 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9452 log("expecting ASS COMPL like this: ", exp_compl);
9453
9454 f_establish_fully(ass_cmd, exp_compl);
9455
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009456 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 +00009457
9458 var RSL_Message rsl;
9459
9460 timer T := 5.0;
9461 T.start;
9462 alt {
9463 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9464 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9465 log("Rx L3 from net: ", l3);
9466 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9467 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9468 mtc.stop;
9469 }
9470 }
9471 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9472 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9473 mtc.stop;
9474 }
9475 [] T.timeout {
9476 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9477 setverdict(pass);
9478 }
9479 }
9480 T.stop;
9481}
9482
9483/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9484 * osmo-bsc. */
9485testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9486 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9487 var MSC_ConnHdlr vc_conn;
9488
9489 f_init(1, true);
9490 f_sleep(1.0);
9491
9492 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9493 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9494 vc_conn.done;
9495 f_shutdown_helper();
9496}
9497
9498/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9499 */
9500testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9501 f_init_vty();
9502
9503 f_init(1, false);
9504 f_sleep(1.0);
9505
9506 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9507
9508 var ASP_RSL_Unitdata rx_rsl_ud;
9509 timer T := 5.0;
9510
9511 T.start;
9512 alt {
9513 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9514 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9515 T.stop;
9516 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9517 mtc.stop;
9518 }
9519 repeat;
9520 }
9521 [] T.timeout {
9522 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9523 setverdict(pass);
9524 }
9525 }
9526}
9527
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009528private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9529 /* First fully set up a speech lchan */
9530 f_TC_assignment_codec(id);
9531
9532 /* Trigger re-assignment to another lchan */
9533 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9534
9535 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9536 * one MDCX on MGCP. */
9537 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9538
9539 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9540 * as the old lchan used. */
9541 g_media.bts.ipa_crcx_seen := false;
9542 g_media.bts.ipa_mdcx_seen := false;
9543
9544 /* Send different BTS side RTP port number for the new lchan */
9545 g_media.bts.bts.port_nr := 4223;
9546
9547 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9548
9549 /* Trigger re-assignment. */
9550 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9551
9552 timer T := 5.0;
9553 T.start;
9554 alt {
9555 [] as_assignment(assignment_st);
9556 [] as_Media();
9557 [] T.timeout {
9558 break;
9559 }
9560 }
9561
9562 if (not assignment_st.assignment_done) {
9563 setverdict(fail, "Assignment did not complete");
9564 mtc.stop;
9565 }
9566
9567 f_check_mgcp_expectations()
9568 setverdict(pass);
9569
9570 f_sleep(2.0);
9571 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9572
9573 /* Instruct BSC to clear channel */
9574 var BssmapCause cause := 0;
9575 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9576 interleave {
9577 [] MGCP.receive(tr_DLCX) {}
9578 [] MGCP.receive(tr_DLCX) {}
9579 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9580 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009581 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009582 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009583 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009584 }
9585 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9586 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9587 }
9588 }
9589
9590 f_sleep(0.5);
9591}
9592
9593testcase TC_reassignment_fr() runs on test_CT {
9594 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9595 var MSC_ConnHdlr vc_conn;
9596
9597 f_init(1, true);
9598 f_sleep(1.0);
9599
9600 f_ctrs_bsc_and_bts_init();
9601
9602 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9603 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9604 vc_conn.done;
9605
9606 /* from f_establish_fully() */
9607 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9608 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9609 /* from re-assignment */
9610 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9611 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9612 f_ctrs_bsc_and_bts_verify();
9613 f_shutdown_helper();
9614}
9615
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009616const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9617const charstring REEST_CLEAR := "REEST_CLEAR";
9618const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9619
9620/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9621 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9622 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9623 * the MSC as the CM Re-Establishment is handled.
9624 *
9625 * MS bts0 bts1 bsc msc test-component
9626 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9627 * | | _1 wait a bit, to settle down
9628 * |<-x x--| | _1 "lose connection"
9629 * | | REEST_LOST_CONNECTION
9630 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9631 * | | REEST_CLEAR
9632 * | |<-0---| _1 Clear Command on first A-conn
9633 * | |--0-->| _1 Clear Complete
9634 * | |<----------------->| | _1 Release first channel
9635 * | | REEST_CLEAR_DONE
9636 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9637 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9638 *
9639 */
9640private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9641 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9642 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9643
9644 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9645 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9646
9647 f_establish_fully(ass_cmd, exp_compl);
9648
9649 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9650 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9651 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9652 f_sleep(2.0);
9653 COORD.send(REEST_LOST_CONNECTION);
9654
9655 alt {
9656 [] COORD.receive(REEST_CLEAR);
9657 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9658 setverdict(fail, "Unexpected channel release");
9659 mtc.stop;
9660 }
9661 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9662 setverdict(fail, "Unexpected channel release");
9663 mtc.stop;
9664 }
9665 }
9666 f_perform_clear()
9667 f_expect_dlcx_conns();
9668 COORD.send(REEST_CLEAR_DONE);
9669}
9670
9671private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9672 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9673
9674 /* The MS lost the connection on the first channel, now establishes another one */
9675 COORD.receive(REEST_LOST_CONNECTION);
9676
9677 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9678 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9679 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9680
9681 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009682 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 +02009683 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9684
9685 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9686 COORD.send(REEST_CLEAR);
9687 COORD.receive(REEST_CLEAR_DONE);
9688
9689 f_sleep(2.0);
9690
9691 /* Answer the CM Re-Establishment with an Assignment Command. */
9692 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9693 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9694 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9695 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9696
9697 var AssignmentState st := valueof(ts_AssignmentStateInit);
9698 st.voice_call := true;
9699 st.is_assignment := true;
9700
9701 var ExpectCriteria mgcpcrit := {
9702 connid := omit,
9703 endpoint := omit,
9704 transid := omit
9705 };
9706 f_create_mgcp_expect(mgcpcrit);
9707
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009708 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009709
9710 BSSAP.send(ass_cmd);
9711
9712 var PDU_BSSAP bssap;
9713
9714 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009715 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9716 [] as_Media_ipacc(RSL1, RSL2);
9717 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009718 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9719 break;
9720 }
9721 }
9722
9723 f_sleep(3.0);
9724
9725 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009726 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009727 f_expect_dlcx_conns();
9728}
9729
9730testcase TC_cm_reestablishment() runs on test_CT {
9731 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9732 var MSC_ConnHdlr vc_conn1;
9733
9734 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9735 var MSC_ConnHdlr vc_conn2;
9736 pars2.imsi := pars1.imsi;
9737 pars2.media_nr := 2;
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009738 /* f_tc_cm_reestablishment_2 uses 'bts 1'.
9739 * BTS 1 has BSIC 11 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 3 */
9740 pars2.expect_tsc := 3;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009741
9742 f_init(2, true, guard_timeout := 40.0);
9743 f_sleep(1.0);
9744
9745 vc_conn1 := f_start_handler_create(pars1);
9746 vc_conn2 := f_start_handler_create(pars2);
9747 connect(vc_conn1:COORD, vc_conn2:COORD);
9748 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9749 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9750 vc_conn1.done;
9751 vc_conn2.done;
9752
9753 f_shutdown_helper();
9754}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009755
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009756function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9757 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9758runs on test_CT return template (omit) RSL_Message {
9759 var ASP_RSL_Unitdata rx_rsl_ud;
9760 timer T := t_secs;
9761
9762 T.start;
9763 alt {
9764 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9765 T.stop;
9766 }
9767 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9768 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9769 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9770 T.stop;
9771 return omit;
9772 }
9773 [] T.timeout {
9774 return omit;
9775 }
9776 }
9777 return rx_rsl_ud.rsl;
9778}
9779
9780private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9781 f_vty_enter_cfg_bts(pt, bts_nr);
9782 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9783 f_vty_transceive(pt, "exit");
9784 f_vty_transceive(pt, "exit");
9785 f_vty_transceive(pt, "exit");
9786}
9787
9788private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009789 template RslChannelNr chan_nr := ?,
9790 template (present) uint12_t arfcn := ?,
9791 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009792{
9793 var RSL_IE_Body full_imm_ass_info;
9794 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
9795 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9796 mtc.stop;
9797 }
9798
9799 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
9800 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
9801 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009802 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009803 page_mode := ?);
9804 if (not match(rr_imm_ass, expect_imm_ass)) {
9805 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
9806 setverdict(fail, "Failed to match Immediate Assignment");
9807 mtc.stop;
9808 }
9809}
9810
9811testcase TC_imm_ass_post_chan_ack() runs on test_CT {
9812 var RSL_Message chan_act;
9813 var RSL_Message imm_ass;
9814
9815 f_init(1, false);
9816 f_sleep(1.0);
9817
9818 /* (should be the default anyway, just to make things clear) */
9819 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
9820
9821 /* RA containing reason=LU */
9822 var GsmFrameNumber fn := 2342;
9823 var uint8_t ra := 2;
9824 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9825
9826 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9827
9828 /* First send the Chan Act ACK */
9829 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009830 var RSL_IE_Body chan_ident_ie;
9831 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9832 setverdict(fail, "RSL Channel Identification IE is absent");
9833 mtc.stop;
9834 }
9835
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009836 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
9837
9838 /* Then expect the Immediate Assignment, after we ACKed the chan act */
9839 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9840
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009841 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9842 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009843
9844 /* Check that the lchan is working */
9845 var octetstring l3 := '00010203040506'O;
9846 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9847
9848 var BSSAP_N_CONNECT_ind rx_c_ind;
9849 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9850 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9851
9852 f_sleep(1.0);
9853 f_shutdown_helper();
9854}
9855
9856testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
9857 var RSL_Message chan_act;
9858 var RSL_Message imm_ass;
9859
9860 f_init(1, false);
9861 f_sleep(1.0);
9862
9863 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9864
9865 /* RA containing reason=LU */
9866 var GsmFrameNumber fn := 2342;
9867 var uint8_t ra := 2;
9868 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9869
9870 /* (set bts 0 cfg back to default) */
9871 f_vty_set_imm_ass(BSCVTY);
9872
9873 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9874 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009875 var RSL_IE_Body chan_ident_ie;
9876 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9877 setverdict(fail, "RSL Channel Identification IE is absent");
9878 mtc.stop;
9879 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009880
9881 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9882 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009883 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9884 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009885
9886 /* Only now send the Chan Act ACK */
9887 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9888
9889 /* Check that the lchan is working */
9890 var octetstring l3 := '00010203040506'O;
9891 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9892
9893 var BSSAP_N_CONNECT_ind rx_c_ind;
9894 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9895 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9896
9897 f_sleep(1.0);
9898 f_shutdown_helper();
9899}
9900
Neels Hofmeyr23158742021-09-07 19:08:07 +02009901testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
9902 var RSL_Message chan_act;
9903 var RSL_Message imm_ass;
9904
9905 f_init(1, false);
9906 f_sleep(1.0);
9907
9908 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
9909
9910 /* RA containing reason=LU */
9911 var GsmFrameNumber fn := 2342;
9912 var uint8_t ra := 2;
9913 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9914
9915 /* (set bts 0 cfg back to default) */
9916 f_vty_set_imm_ass(BSCVTY);
9917
9918 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9919 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
9920 var RSL_IE_Body chan_ident_ie;
9921 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9922 setverdict(fail, "RSL Channel Identification IE is absent");
9923 mtc.stop;
9924 }
9925
9926 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9927 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9928 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9929 chan_ident_ie.chan_ident.ch_desc.v.tsc);
9930
9931 /* Only now send the Chan Act ACK */
9932 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9933
9934 /* Check that the lchan is working */
9935 var octetstring l3 := '00010203040506'O;
9936 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9937
9938 var BSSAP_N_CONNECT_ind rx_c_ind;
9939 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9940 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9941
9942 f_sleep(1.0);
9943 f_shutdown_helper();
9944}
9945
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009946testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
9947 /* change Timeslot 6 before f_init() starts RSL */
9948 f_init_vty();
9949 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
9950 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9951
9952 f_init(1, false);
9953 f_sleep(1.0);
9954
9955 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
9956 /* The BSC will activate the dynamic PDCH by default, so confirm that */
9957 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
9958 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
9959
9960 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
9961 f_ts_set_chcomb(0, 0, 6, "PDCH");
9962
9963 /* block all static timeslots so that the dyn TS will be used */
9964 f_disable_all_tch_f();
9965 f_disable_all_tch_h();
9966 f_disable_all_sdcch();
9967
9968 var RSL_Message chan_act;
9969 var RSL_Message imm_ass;
9970
9971 f_init(1, false);
9972 f_sleep(1.0);
9973
9974 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9975
9976 /* RA containing reason=LU */
9977 var GsmFrameNumber fn := 2342;
9978 var uint8_t ra := 2;
9979 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9980
9981 /* (set bts 0 cfg back to default) */
9982 f_vty_set_imm_ass(BSCVTY);
9983
9984 /* Expect the dyn TS to deactivate PDCH first */
9985 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
9986 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
9987
9988 /* Now activation as SDCCH8 */
9989 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
9990
9991 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009992 var RSL_IE_Body chan_ident_ie;
9993 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9994 setverdict(fail, "RSL Channel Identification IE is absent");
9995 mtc.stop;
9996 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009997
9998 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9999 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010000 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10001 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010002
10003 /* Only now send the Chan Act ACK */
10004 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10005
10006 /* Check that the lchan is working */
10007 var octetstring l3 := '00010203040506'O;
10008 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10009
10010 var BSSAP_N_CONNECT_ind rx_c_ind;
10011 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10012 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10013
10014 f_sleep(1.0);
10015 f_shutdown_helper();
10016}
10017
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010018testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10019 /* change Timeslot 6 before f_init() starts RSL */
10020 f_init_vty();
10021 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10022 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10023
10024 f_init(1, false);
10025 f_sleep(1.0);
10026
10027 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10028 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10029 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10030 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10031
10032 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10033 f_ts_set_chcomb(0, 0, 6, "PDCH");
10034
10035 /* block all static timeslots so that the dyn TS will be used */
10036 f_disable_all_tch_f();
10037 f_disable_all_tch_h();
10038 f_disable_all_sdcch();
10039
10040 var RSL_Message chan_act;
10041 var RSL_Message imm_ass;
10042
10043 f_init(1, false);
10044 f_sleep(1.0);
10045
10046 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10047
10048 /* RA containing reason=LU */
10049 var GsmFrameNumber fn := 2342;
10050 var uint8_t ra := 2;
10051 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10052
10053 /* (set bts 0 cfg back to default) */
10054 f_vty_set_imm_ass(BSCVTY);
10055
10056 /* Expect the dyn TS to deactivate PDCH first */
10057 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10058
10059 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10060 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10061
10062 /* continue the Osmo style PDCH Deact (usual chan rel) */
10063 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10064
10065 /* Now activation as SDCCH8 */
10066 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10067
10068 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010069 var RSL_IE_Body chan_ident_ie;
10070 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10071 setverdict(fail, "RSL Channel Identification IE is absent");
10072 mtc.stop;
10073 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010074 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10075
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010076 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10077 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010078
10079 /* Check that the lchan is working */
10080 var octetstring l3 := '00010203040506'O;
10081 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10082
10083 var BSSAP_N_CONNECT_ind rx_c_ind;
10084 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10085 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10086
10087 f_sleep(1.0);
10088 f_shutdown_helper();
10089}
10090
Harald Welte28d943e2017-11-25 15:00:50 +010010091control {
Harald Welte898113b2018-01-31 18:32:21 +010010092 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010093 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010094 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +020010095 execute( TC_stat_num_msc_connected_1() );
10096 execute( TC_stat_num_msc_connected_2() );
10097 execute( TC_stat_num_msc_connected_3() );
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020010098 execute( TC_stat_num_bts_connected_1() );
10099 execute( TC_stat_num_bts_connected_2() );
10100 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010101 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010102 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010103 execute( TC_ctrl_location() );
10104 }
Harald Welte898113b2018-01-31 18:32:21 +010010105
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010106 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010107 execute( TC_si2quater_2_earfcns() );
10108 execute( TC_si2quater_3_earfcns() );
10109 execute( TC_si2quater_4_earfcns() );
10110 execute( TC_si2quater_5_earfcns() );
10111 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010112 execute( TC_si2quater_12_earfcns() );
10113 execute( TC_si2quater_23_earfcns() );
10114 execute( TC_si2quater_32_earfcns() );
10115 execute( TC_si2quater_33_earfcns() );
10116 execute( TC_si2quater_42_earfcns() );
10117 execute( TC_si2quater_48_earfcns() );
10118 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010119 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010120 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010121
Harald Welte898113b2018-01-31 18:32:21 +010010122 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010123 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010124 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010125 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010126 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010127 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010128 execute( TC_chan_act_ack_est_ind_noreply() );
10129 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010130 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010131 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010132 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010133 execute( TC_chan_rel_rll_rel_ind() );
10134 execute( TC_chan_rel_conn_fail() );
10135 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010136 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10137 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010138 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010139 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010140 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010141 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010142 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010143 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010144
Harald Weltecfe2c962017-12-15 12:09:32 +010010145 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010146
10147 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010148 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010149 execute( TC_assignment_csd() );
10150 execute( TC_assignment_ctm() );
10151 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010152 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10153 execute( TC_assignment_aoip_tla_v6() );
10154 }
Harald Welte235ebf12017-12-15 14:18:16 +010010155 execute( TC_assignment_fr_a5_0() );
10156 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010157 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010158 execute( TC_assignment_fr_a5_1_codec_missing() );
10159 }
Harald Welte235ebf12017-12-15 14:18:16 +010010160 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010161 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010162 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010163 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010164 execute( TC_ciph_mode_a5_0() );
10165 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010166 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010167 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010168 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010169 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010170
Harald Welte60aa5762018-03-21 19:33:13 +010010171 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010172 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010173 execute( TC_assignment_codec_hr() );
10174 execute( TC_assignment_codec_efr() );
10175 execute( TC_assignment_codec_amr_f() );
10176 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010177
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010178 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010179 execute( TC_assignment_codec_amr_f_S1() );
10180 execute( TC_assignment_codec_amr_h_S1() );
10181 execute( TC_assignment_codec_amr_f_S124() );
10182 execute( TC_assignment_codec_amr_h_S124() );
10183 execute( TC_assignment_codec_amr_f_S0() );
10184 execute( TC_assignment_codec_amr_f_S02() );
10185 execute( TC_assignment_codec_amr_f_S024() );
10186 execute( TC_assignment_codec_amr_f_S0247() );
10187 execute( TC_assignment_codec_amr_h_S0() );
10188 execute( TC_assignment_codec_amr_h_S02() );
10189 execute( TC_assignment_codec_amr_h_S024() );
10190 execute( TC_assignment_codec_amr_h_S0247() );
10191 execute( TC_assignment_codec_amr_f_S01234567() );
10192 execute( TC_assignment_codec_amr_f_S0234567() );
10193 execute( TC_assignment_codec_amr_f_zero() );
10194 execute( TC_assignment_codec_amr_f_unsupp() );
10195 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010196 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10197 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010198 execute( TC_assignment_codec_amr_f_start_mode_4() );
10199 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010200 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010201 }
Harald Welte60aa5762018-03-21 19:33:13 +010010202
Philipp Maierac09bfc2019-01-08 13:41:39 +010010203 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10204 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10205 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10206 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10207 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10208 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10209 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10210 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10211 execute( TC_assignment_codec_req_hr_fr() );
10212 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010213 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10214 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10215 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010216
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010217 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010218
Harald Welte898113b2018-01-31 18:32:21 +010010219 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010220 execute( TC_rll_est_ind_inact_lchan() );
10221 execute( TC_rll_est_ind_inval_sapi1() );
10222 execute( TC_rll_est_ind_inval_sapi3() );
10223 execute( TC_rll_est_ind_inval_sacch() );
10224
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010225 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10226 execute( TC_tch_dlci_link_id_sapi() );
10227
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010228 /* SAPI N Reject triggered by RLL establishment failures */
10229 execute( TC_rll_rel_ind_sapi_n_reject() );
10230 execute( TC_rll_err_ind_sapi_n_reject() );
10231 execute( TC_rll_timeout_sapi_n_reject() );
10232
Harald Welte898113b2018-01-31 18:32:21 +010010233 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010234 execute( TC_paging_imsi_nochan() );
10235 execute( TC_paging_tmsi_nochan() );
10236 execute( TC_paging_tmsi_any() );
10237 execute( TC_paging_tmsi_sdcch() );
10238 execute( TC_paging_tmsi_tch_f() );
10239 execute( TC_paging_tmsi_tch_hf() );
10240 execute( TC_paging_imsi_nochan_cgi() );
10241 execute( TC_paging_imsi_nochan_lac_ci() );
10242 execute( TC_paging_imsi_nochan_ci() );
10243 execute( TC_paging_imsi_nochan_lai() );
10244 execute( TC_paging_imsi_nochan_lac() );
10245 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010246 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10247 execute( TC_paging_imsi_nochan_rnc() );
10248 execute( TC_paging_imsi_nochan_lac_rnc() );
10249 execute( TC_paging_imsi_nochan_lacs() );
10250 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010251 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010252 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010253 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010254 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010255 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010256
10257 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010258 execute( TC_rsl_unknown_unit_id() );
10259
10260 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010261
10262 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010263 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010264 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010265 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010266 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010267 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010268 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010269
Harald Welte261af4b2018-02-12 21:20:39 +010010270 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010271 execute( TC_ho_int_a5_0() );
10272 execute( TC_ho_int_a5_1() );
10273 execute( TC_ho_int_a5_3() );
10274 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010275 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010276
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010277 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010278 execute( TC_ho_out_fail_no_msc_response() );
10279 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010280 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010281
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010282 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010283 execute( TC_ho_into_this_bsc_a5_0() );
10284 execute( TC_ho_into_this_bsc_a5_1() );
10285 execute( TC_ho_into_this_bsc_a5_3() );
10286 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010287 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10288 execute( TC_ho_into_this_bsc_tla_v6() );
10289 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010290 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010291 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010292 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10293 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010294 execute( TC_ho_in_fail_msc_clears() );
10295 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10296 execute( TC_ho_in_fail_no_detect() );
10297 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010298
Neels Hofmeyr91401012019-07-11 00:42:35 +020010299 execute( TC_ho_neighbor_config_1() );
10300 execute( TC_ho_neighbor_config_2() );
10301 execute( TC_ho_neighbor_config_3() );
10302 execute( TC_ho_neighbor_config_4() );
10303 execute( TC_ho_neighbor_config_5() );
10304 execute( TC_ho_neighbor_config_6() );
10305 execute( TC_ho_neighbor_config_7() );
10306
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010307 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010308 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010309 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010310
10311 execute( TC_dyn_pdch_ipa_act_deact() );
10312 execute( TC_dyn_pdch_ipa_act_nack() );
10313 execute( TC_dyn_pdch_osmo_act_deact() );
10314 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010315 if (mp_enable_dyn_sdcch8_test) {
10316 execute( TC_dyn_ts_sdcch8_act_deact() );
10317 execute (TC_dyn_ts_sdcch8_tch_call_act_deact() );
10318 execute( TC_dyn_ts_sdcch8_act_nack() );
10319 }
Harald Welte99f3ca02018-06-14 13:40:29 +020010320
Stefan Sperling0796a822018-10-05 13:01:39 +020010321 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010322 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010323
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010324 /* Power control related */
10325 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010326 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010327
10328 /* MSC pooling */
10329 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10330 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10331 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10332 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10333 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10334 execute( TC_mscpool_L3Compl_on_1_msc() );
10335 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10336 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10337 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10338 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10339 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10340 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10341 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10342 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10343 execute( TC_mscpool_paging_and_response_imsi() );
10344 execute( TC_mscpool_paging_and_response_tmsi() );
10345 execute( TC_mscpool_no_allow_attach_round_robin() );
10346 execute( TC_mscpool_no_allow_attach_valid_nri() );
10347 }
10348
Harald Welte99f3ca02018-06-14 13:40:29 +020010349 execute( TC_early_conn_fail() );
10350 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010351 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010352
Philipp Maier783681c2020-07-16 16:47:06 +020010353 /* Emergency call handling (deny / allow) */
10354 execute( TC_assignment_emerg_setup_allow() );
10355 execute( TC_assignment_emerg_setup_deny_msc() );
10356 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010357 execute( TC_emerg_premption() );
10358
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010359 /* Frequency hopping parameters handling */
10360 execute( TC_fh_params_chan_activ() );
10361 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010362 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010363 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010364 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010365
10366 if (mp_enable_lcs_tests) {
10367 execute( TC_lcs_loc_req_for_active_ms() );
10368 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10369 execute( TC_lcs_loc_req_for_idle_ms() );
10370 execute( TC_lcs_loc_req_no_subscriber() );
10371 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10372 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10373 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10374 execute( TC_cm_service_during_lcs_loc_req() );
10375 execute( TC_ho_during_lcs_loc_req() );
10376 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010377
10378 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010379
10380 execute( TC_refuse_chan_act_to_vamos() );
10381 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010382
10383 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010384
10385 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010386
10387 execute( TC_imm_ass_post_chan_ack() );
10388 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010389 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010390 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010391 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Harald Welte28d943e2017-11-25 15:00:50 +010010392}
10393
10394}