blob: d8e2ab1f1a65494175408f3288dbe3fde8aae540 [file] [log] [blame]
Harald Welte28d943e2017-11-25 15:00:50 +01001module BSC_Tests {
2
Harald Welte21b46bd2017-12-17 19:46:32 +01003/* Integration Tests for OsmoBSC
Harald Weltea0630032018-03-20 21:09:55 +01004 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
Harald Welte21b46bd2017-12-17 19:46:32 +01005 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
Harald Welte34b5a952019-05-27 11:54:11 +020010 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
Harald Welte21b46bd2017-12-17 19:46:32 +010012 * This test suite tests OsmoBSC while emulating both multiple BTS + MS as
13 * well as the MSC. See README for more details.
14 *
15 * There are test cases that run in so-called 'handler mode' and test cases
16 * that run directly on top of the BSSAP and RSL CodecPorts. The "handler mode"
17 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
18 * and/or RSL channels and are hence suitable for higher-level test cases, while
19 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
20 * level testing.
21 */
22
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020023friend module BSC_Tests_VAMOS;
24
Neels Hofmeyr4f118412020-06-04 15:25:10 +020025import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010026import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010027import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010028import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010029import from IPL4asp_Types all;
30
Harald Welte6f521d82017-12-11 19:52:02 +010031import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020032import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020033import from BSSAP_LE_Adapter all;
34import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020035import from BSSAP_LE_Types all;
36import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010037import from BSSAP_CodecPort all;
38import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010039import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010040import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010041import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020042import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010043import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010044import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010045import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010046import from MGCP_Templates all;
47import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020048import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010049
Harald Welte96c94412017-12-09 03:12:45 +010050import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010051import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010052import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010053
Daniel Willmannebdecc02020-08-12 15:30:17 +020054import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
Harald Weltebc03c762018-02-12 18:09:38 +010059import from Osmocom_VTY_Functions all;
60import from TELNETasp_PortType all;
61
Harald Welte6f521d82017-12-11 19:52:02 +010062import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010063import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010064import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010065import from L3_Templates all;
66import from GSM_RR_Types all;
67
Stefan Sperlingc307e682018-06-14 15:15:46 +020068import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010069import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020070import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010071
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010072import from SCCPasp_Types all;
73
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020074import from GSM_SystemInformation all;
75import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020076import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020077
Neels Hofmeyrbf720202021-10-02 12:58:24 +020078type record of integer integer_list;
79
Harald Welte5d1a2202017-12-13 19:51:29 +010080const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020081const integer NUM_BTS_CFG := 4; /* we have 4 BTS in the osmo-bsc.cfg (for inter-BSC HO tests) but use only 3 */
Neels Hofmeyrf246a922020-05-13 02:27:10 +020082const integer NUM_MSC := 3;
Harald Welteae026692017-12-09 01:03:01 +010083const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010084
Harald Welte799c97b2017-12-14 17:50:30 +010085/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020086const integer NUM_TCHH_PER_BTS := 2;
87const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020088const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010089
Neels Hofmeyrbf720202021-10-02 12:58:24 +020090/* Default Training Sequence Code expected for bts[i]:
91 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
92 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
93 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
94 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
95 */
96const integer_list BTS_TSC := {
97 2,
98 3,
99 4,
100 4
101}
Harald Welte4003d112017-12-09 22:35:39 +0100102
Harald Welte21b46bd2017-12-17 19:46:32 +0100103/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100104type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100105 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100106 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100107}
108
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200109/* Default list of counters for an 'msc' entity. */
110const CounterNameVals counternames_msc_mscpool := {
111 { "mscpool:subscr:new", 0 },
112 { "mscpool:subscr:known", 0 },
113 { "mscpool:subscr:reattach", 0 },
114 { "mscpool:subscr:attach_lost", 0 },
115 { "mscpool:subscr:paged", 0 }
116};
117
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000118/* List of global mscpool counters, not related to a specific 'msc' entity. */
119const CounterNameVals counternames_bsc_mscpool := {
120 { "mscpool:subscr:no_msc", 0 }
121};
122
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000123/* Default list of counters for 'bsc' and 'bts' entities. */
124const CounterNameVals counternames_bsc_bts_handover := {
125 { "assignment:attempted", 0 },
126 { "assignment:completed", 0 },
127 { "assignment:stopped", 0 },
128 { "assignment:no_channel", 0 },
129 { "assignment:timeout", 0 },
130 { "assignment:failed", 0 },
131 { "assignment:error", 0 },
132
133 { "handover:attempted", 0 },
134 { "handover:completed", 0 },
135 { "handover:stopped", 0 },
136 { "handover:no_channel", 0 },
137 { "handover:timeout", 0 },
138 { "handover:failed", 0 },
139 { "handover:error", 0 },
140
141 { "intra_cell_ho:attempted", 0 },
142 { "intra_cell_ho:completed", 0 },
143 { "intra_cell_ho:stopped", 0 },
144 { "intra_cell_ho:no_channel", 0 },
145 { "intra_cell_ho:timeout", 0 },
146 { "intra_cell_ho:failed", 0 },
147 { "intra_cell_ho:error", 0 },
148
149 { "intra_bsc_ho:attempted", 0 },
150 { "intra_bsc_ho:completed", 0 },
151 { "intra_bsc_ho:stopped", 0 },
152 { "intra_bsc_ho:no_channel", 0 },
153 { "intra_bsc_ho:timeout", 0 },
154 { "intra_bsc_ho:failed", 0 },
155 { "intra_bsc_ho:error", 0 },
156
157 { "interbsc_ho_out:attempted", 0 },
158 { "interbsc_ho_out:completed", 0 },
159 { "interbsc_ho_out:stopped", 0 },
160 { "interbsc_ho_out:timeout", 0 },
161 { "interbsc_ho_out:failed", 0 },
162 { "interbsc_ho_out:error", 0 },
163
164 { "interbsc_ho_in:attempted", 0 },
165 { "interbsc_ho_in:completed", 0 },
166 { "interbsc_ho_in:stopped", 0 },
167 { "interbsc_ho_in:no_channel", 0 },
168 { "interbsc_ho_in:timeout", 0 },
169 { "interbsc_ho_in:failed", 0 },
170 { "interbsc_ho_in:error", 0 }
171};
172
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100173const CounterNameVals counternames_bts_handover := {
174 { "incoming_intra_bsc_ho:attempted", 0 },
175 { "incoming_intra_bsc_ho:completed", 0 },
176 { "incoming_intra_bsc_ho:stopped", 0 },
177 { "incoming_intra_bsc_ho:no_channel", 0 },
178 { "incoming_intra_bsc_ho:timeout", 0 },
179 { "incoming_intra_bsc_ho:failed", 0 },
180 { "incoming_intra_bsc_ho:error", 0 }
181};
182
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200183/* Set of all System Information received during one RSL port's startup.
184 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
185 * broadcast that SI type. That will be reflected as 'omit' here.
186 */
187type record SystemInformationConfig {
188 SystemInformationType1 si1 optional,
189 SystemInformationType2 si2 optional,
190 SystemInformationType2bis si2bis optional,
191 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200192 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200193 SystemInformationType3 si3 optional,
194 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100195 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200196 SystemInformationType5 si5 optional,
197 SystemInformationType5bis si5bis optional,
198 SystemInformationType5ter si5ter optional,
199 SystemInformationType6 si6 optional
200};
201
202const SystemInformationConfig SystemInformationConfig_omit := {
203 si1 := omit,
204 si2 := omit,
205 si2bis := omit,
206 si2ter := omit,
207 si2quater := omit,
208 si3 := omit,
209 si4 := omit,
210 si13 := omit,
211 si5 := omit,
212 si5bis := omit,
213 si5ter := omit,
214 si6 := omit
215};
216
217/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
218template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
219 template uint3_t meas_bw := 3)
220:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
221 meas_bw_presence := '1'B,
222 meas_bw := meas_bw);
223
224/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200225template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200226 template uint3_t prio := 3,
227 template (present) uint5_t thresh_high := 20,
228 template uint5_t thresh_low := 10,
229 template uint5_t qrxlevmin := 22)
230:= tr_EUTRAN_NeighbourCells(
231 cell_desc_list := cell_desc_list,
232 prio_presence := '1'B,
233 prio := prio,
234 thresh_high := thresh_high,
235 thresh_low_presence := '1'B,
236 thresh_low := thresh_low,
237 qrxlevmin_presence := '1'B,
238 qrxlevmin := qrxlevmin);
239
240template SystemInformationConfig SystemInformationConfig_default := {
241 si1 := {
242 cell_chan_desc := '8FB38000000000000000000000000000'O,
243 rach_control := {
244 max_retrans := RACH_MAX_RETRANS_7,
245 tx_integer := '1001'B,
246 cell_barr_access := false,
247 re_not_allowed := true,
248 acc := '0000010000000000'B
249 },
250 rest_octets := ?
251 },
252 si2 := {
253 bcch_freq_list := '00000000000000000000000000000000'O,
254 ncc_permitted := '11111111'B,
255 rach_control := {
256 max_retrans := RACH_MAX_RETRANS_7,
257 tx_integer := '1001'B,
258 cell_barr_access := false,
259 re_not_allowed := true,
260 acc := '0000010000000000'B
261 }
262 },
263 si2bis := omit,
264 si2ter := {
265 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
266 rest_octets := ?
267 },
268 si2quater := {
269 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
270 },
271 si3 := {
272 cell_id := 0,
273 lai := {
274 mcc_mnc := '001F01'H,
275 lac := 1
276 },
277 ctrl_chan_desc := {
278 msc_r99 := true,
279 att := true,
280 bs_ag_blks_res := 1,
281 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
282 si22ind := false,
283 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
284 spare := '00'B,
285 bs_pa_mfrms := 3,
286 t3212 := 30
287 },
288 cell_options := {
289 dn_ind := false,
290 pwrc := false,
291 dtx := MS_SHALL_USE_UL_DTX,
292 radio_link_tout_div4 := 7
293 },
294 cell_sel_par := {
295 cell_resel_hyst_2dB := 2,
296 ms_txpwr_max_cch := 7,
297 acs := '0'B,
298 neci := true,
299 rxlev_access_min := 0
300 },
301 rach_control := {
302 max_retrans := RACH_MAX_RETRANS_7,
303 tx_integer := '1001'B,
304 cell_barr_access := false,
305 re_not_allowed := true,
306 acc := '0000010000000000'B
307 },
308 rest_octets := {
309 sel_params := {
310 presence := '0'B,
311 params := omit
312 },
313 pwr_offset := {
314 presence := '0'B,
315 offset := omit
316 },
317 si_2ter_ind := '1'B,
318 early_cm_ind := '0'B,
319 sched_where := {
320 presence := '0'B,
321 where := omit
322 },
323 gprs_ind := {
324 presence := '1'B,
325 ind := {
326 ra_colour := 0,
327 si13_pos := '0'B
328 }
329 },
330 umts_early_cm_ind := '1'B,
331 si2_quater_ind := {
332 presence := '1'B,
333 ind := '0'B
334 },
335 iu_mode_ind := omit,
336 si21_ind := {
337 presence := '0'B,
338 pos := omit
339 }
340 }
341 },
342 si4 := {
343 lai := {
344 mcc_mnc := '001F01'H,
345 lac := 1
346 },
347 cell_sel_par := {
348 cell_resel_hyst_2dB := 2,
349 ms_txpwr_max_cch := 7,
350 acs := '0'B,
351 neci := true,
352 rxlev_access_min := 0
353 },
354 rach_control := {
355 max_retrans := RACH_MAX_RETRANS_7,
356 tx_integer := '1001'B,
357 cell_barr_access := false,
358 re_not_allowed := true,
359 acc := '0000010000000000'B
360 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200361 cbch_chan_desc := {
362 iei := '64'O,
363 v := {
364 chan_nr := {
365 u := {
366 sdcch4 := {
367 tag := '001'B,
368 sub_chan := 2
369 }
370 },
371 tn := 0
372 },
373 tsc := 2,
374 h := false,
375 arfcn := 871,
376 maio_hsn := omit
377 }
378 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200379 cbch_mobile_alloc := omit,
380 rest_octets := {
381 sel_params := {
382 presence := '0'B,
383 params := omit
384 },
385 pwr_offset := {
386 presence := '0'B,
387 offset := omit
388 },
389 gprs_ind := {
390 presence := '1'B,
391 ind := {
392 ra_colour := 0,
393 si13_pos := '0'B
394 }
395 },
396 s_presence := '0'B,
397 s := omit
398 }
399 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100400 si13 := {
401 rest_octets := {
402 presence := '1'B,
403 bcch_change_mark := ?,
404 si_change_field := '0000'B,
405 presence2 := '0'B,
406 si13_change_mark := omit,
407 gprs_ma := omit,
408 zero := '0'B, /* PBCCH not present in cell */
409 rac := 0,
410 spgc_ccch_sup := '0'B,
411 priority_access_thr := '110'B,
412 network_control_order := '00'B,
413 gprs_cell_opts := {
414 nmo := '01'B,
415 t3168 := '011'B,
416 t3192 := '010'B,
417 drx_timer_max := '011'B,
418 access_burst_type := '0'B,
419 control_ack_type := '1'B,
420 bs_cv_max := 15,
421 pan_presence := '1'B,
422 pan_dec := 1,
423 pan_inc := 1,
424 pan_max := '111'B,
425 ext_info_presence := ?,
426 ext_info_length := *,
427 ext_info := *
428 },
429 gprs_pwr_ctrl_params := {
430 alpha := 0,
431 t_avg_w := '10000'B,
432 t_avg_t := '10000'B,
433 pc_meas_chan := '0'B,
434 n_avg_i := '1000'B
435 }
436 }
437 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200438 si5 := {
439 bcch_freq_list := '10000000000000000000000000000000'O
440 },
441 si5bis := omit,
442 si5ter := {
443 extd_bcch_freq_list := '9E050020000000000000000000000000'O
444 },
445 si6 := {
446 cell_id := 0,
447 lai := {
448 mcc_mnc := '001F01'H,
449 lac := 1
450 },
451 cell_options := {
452 dtx_ext := '1'B,
453 pwrc := false,
454 dtx := '01'B,
455 radio_link_timeout := '0111'B
456 },
457 ncc_permitted := '11111111'B,
458 rest_octets := ?
459 }
460 };
461
462
463/* List of all the System Information received on all RSL ports */
464type record of SystemInformationConfig SystemInformationConfig_list;
465
466function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
467{
468 var RSL_IE_Body sysinfo_type_ie;
469 var RSL_IE_SysinfoType si_type;
470 var octetstring data;
471
472 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
473 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
474 mtc.stop;
475 }
476 si_type := sysinfo_type_ie.sysinfo_type;
477
478 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
479 var RSL_IE_Body bcch_ie;
480 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
481 data := bcch_ie.other.payload;
482 }
483 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
484 var RSL_IE_Body l3_ie;
485 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
486 data := l3_ie.l3_info.payload;
487 }
488 } else {
489 setverdict(fail, "Don't understand this System Information message");
490 mtc.stop;
491 }
492
493 var boolean handled := false;
494
495 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
496 handled := true;
497
498 if (si_type == RSL_SYSTEM_INFO_1) {
499 if (not isbound(data)) {
500 si.si1 := omit;
501 } else {
502 si.si1 := dec_SystemInformation(data).payload.si1;
503 }
504 } else if (si_type == RSL_SYSTEM_INFO_2) {
505 if (not isbound(data)) {
506 si.si2 := omit;
507 } else {
508 si.si2 := dec_SystemInformation(data).payload.si2;
509 }
510 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
511 if (not isbound(data)) {
512 si.si2bis := omit;
513 } else {
514 si.si2bis := dec_SystemInformation(data).payload.si2bis;
515 }
516 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
517 if (not isbound(data)) {
518 si.si2ter := omit;
519 } else {
520 si.si2ter := dec_SystemInformation(data).payload.si2ter;
521 }
522 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
523 if (not isbound(data)) {
524 si.si2quater := {};
525 } else {
526 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
527 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
528 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
529 }
530 } else if (si_type == RSL_SYSTEM_INFO_3) {
531 if (not isbound(data)) {
532 si.si3 := omit;
533 } else {
534 si.si3 := dec_SystemInformation(data).payload.si3;
535 }
536 } else if (si_type == RSL_SYSTEM_INFO_4) {
537 if (not isbound(data)) {
538 si.si4 := omit;
539 } else {
540 si.si4 := dec_SystemInformation(data).payload.si4;
541 }
542 } else if (si_type == RSL_SYSTEM_INFO_13) {
543 if (not isbound(data)) {
544 si.si13 := omit;
545 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100546 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200547 }
548 } else {
549 handled := false;
550 }
551 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
552 handled := true;
553
554 if (si_type == RSL_SYSTEM_INFO_5) {
555 if (not isbound(data)) {
556 si.si5 := omit;
557 } else {
558 si.si5 := dec_SystemInformation(data).payload.si5;
559 }
560 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
561 if (not isbound(data)) {
562 si.si5bis := omit;
563 } else {
564 si.si5bis := dec_SystemInformation(data).payload.si5bis;
565 }
566 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
567 if (not isbound(data)) {
568 si.si5ter := omit;
569 } else {
570 si.si5ter := dec_SystemInformation(data).payload.si5ter;
571 }
572 } else if (si_type == RSL_SYSTEM_INFO_6) {
573 if (not isbound(data)) {
574 si.si6 := omit;
575 } else {
576 si.si6 := dec_SystemInformation(data).payload.si6;
577 }
578 } else {
579 handled := false;
580 }
581 }
582
583 if (not handled) {
584 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
585 }
586}
587
Harald Weltea4ca4462018-02-09 00:17:14 +0100588type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100589 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100590 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100591 /* RSL common Channel Port (for RSL_Emulation) */
592 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100593 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100594 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100595 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200596 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
597 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100598
Daniel Willmann191e0d92018-01-17 12:44:35 +0100599 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100600 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100601
Daniel Willmannebdecc02020-08-12 15:30:17 +0200602 /* StatsD */
603 var StatsD_Checker_CT vc_STATSD;
604
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200605 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200606 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100607 /* for old legacy-tests only */
608 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200609 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100610
Harald Welte21b46bd2017-12-17 19:46:32 +0100611 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100612 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100613
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200614 /* Osmux is enabled through VTY */
615 var boolean g_osmux_enabled := false;
616
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100617 /*Configure T(tias) over VTY, seconds */
618 var integer g_bsc_sccp_timer_ias := 7 * 60;
619 /*Configure T(tiar) over VTY, seconds */
620 var integer g_bsc_sccp_timer_iar := 15 * 60;
621
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200622 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100623 timer T_guard := 30.0;
624
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200625 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000626 var CounterNameValsList g_ctr_bsc;
627 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200628
629 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
630 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100631}
632
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200633type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100634modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100635 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100636 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100637 /* port number to which to establish the IPA OML connections */
638 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100639 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100640 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100641 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100642 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200643 /* port number to which to listen for STATSD metrics */
644 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100645 /* IP address at which the test binds */
646 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100647
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200648 RAN_Configurations mp_bssap_cfg := {
649 {
650 transport := BSSAP_TRANSPORT_AoIP,
651 sccp_service_type := "mtp3_itu",
652 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
653 own_pc := 185, /* 0.23.1 first MSC emulation */
654 own_ssn := 254,
655 peer_pc := 187, /* 0.23.3 osmo-bsc */
656 peer_ssn := 254,
657 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200658 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200659 },
660 {
661 transport := BSSAP_TRANSPORT_AoIP,
662 sccp_service_type := "mtp3_itu",
663 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
664 own_pc := 2, /* 0.0.2 second MSC emulation */
665 own_ssn := 254,
666 peer_pc := 187, /* 0.23.3 osmo-bsc */
667 peer_ssn := 254,
668 sio := '83'O,
669 rctx := 2
670 },
671 {
672 transport := BSSAP_TRANSPORT_AoIP,
673 sccp_service_type := "mtp3_itu",
674 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
675 own_pc := 3, /* 0.0.3 third MSC emulation */
676 own_ssn := 254,
677 peer_pc := 187, /* 0.23.3 osmo-bsc */
678 peer_ssn := 254,
679 sio := '83'O,
680 rctx := 3
681 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100682 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200683
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200684 /* Must match per BTS config in osmo-bsc.cfg */
685 phys_chan_configs phys_chan_config := {
686 "CCCH+SDCCH4+CBCH",
687 "TCH/F",
688 "TCH/F",
689 "TCH/F",
690 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600691 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200692 "PDCH",
693 "PDCH"
694 };
695
Harald Welte47cd0e32020-08-21 12:39:11 +0200696 BSSAP_LE_Configuration mp_bssap_le_cfg := {
697 sccp_service_type := "mtp3_itu",
698 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200699 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200700 own_ssn := 252, /* SMLC side SSN */
701 peer_pc := 187, /* 0.23.3 osmo-bsc */
702 peer_ssn := 250, /* BSC side SSN */
703 sio := '83'O,
704 rctx := 6
705 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200706 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200707
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100708 /* Value set in osmo-bsc.cfg "ms max power" */
709 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100710}
711
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200712friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200713
714 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200715 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200716 pars.aoip := true;
717 } else {
718 pars.aoip := false;
719 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100720 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200721 pars.mscpool.bssap_idx := bssap_idx;
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200722 pars.expect_tsc := BTS_TSC[0];
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200723
Philipp Maier48604732018-10-09 15:00:37 +0200724 return pars;
725}
726
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200727/* Convenience functions for rate counters using g_ctr_msc. */
728
729private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
730 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
731 log("initial msc rate counters: ", g_ctr_msc);
732}
733
734private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200735 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200736}
737
738/* f_ctrs_msc_init();
739 * f_do_thing(on_msc := 0);
740 * f_do_thing(on_msc := 0);
741 * f_do_other(on_msc := 1);
742 * f_ctrs_msc_add(0, "thing", 2);
743 * f_ctrs_msc_add(1, "other");
744 * f_ctrs_msc_verify();
745 */
746private function f_ctrs_msc_verify() runs on test_CT {
747 log("verifying msc rate counters: ", g_ctr_msc);
748 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
749}
750
751/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
752 * f_ctrs_msc_init();
753 * f_do_thing(on_msc := 0);
754 * f_do_thing(on_msc := 0);
755 * f_do_thing(on_msc := 0);
756 * f_ctrs_msc_expect(0, "thing", 3);
757 */
758private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
759 f_ctrs_msc_add(msc_nr, countername, val);
760 f_ctrs_msc_verify();
761}
762
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000763/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
764
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100765private function f_ctrs_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000766 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100767}
768
769function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
770 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000771 log("initial bts rate counters: ", g_ctr_bts);
772 f_ctrs_bsc_init(counternames);
773}
774
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100775private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
776 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
777 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, bts_names);
778 log("initial bts rate counters: ", g_ctr_bts);
779 f_ctrs_bsc_init(counternames_bsc_bts_handover);
780}
781
782private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000783 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100784}
785
786private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
787 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000788 f_ctrs_bsc_add(countername, val);
789}
790
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100791function f_ctrs_bts_verify() runs on test_CT {
792 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
793}
794
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000795/* f_ctrs_bsc_and_bts_init();
796 * f_do_thing(on_bts := 0);
797 * f_do_thing(on_bts := 0);
798 * f_do_other(on_bts := 1);
799 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
800 * f_ctrs_bsc_and_bts_add(1, "other");
801 * f_ctrs_bsc_and_bts_verify();
802 */
803private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100804 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000805 f_ctrs_bsc_verify();
806}
807
808/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
809 * f_ctrs_bsc_and_bts_init();
810 * f_do_thing(on_bts := 0);
811 * f_do_thing(on_bts := 0);
812 * f_do_thing(on_bts := 0);
813 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
814 */
815private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
816 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
817 f_ctrs_bsc_and_bts_verify();
818}
819
820
821/* Convenience functions for rate counters using g_ctr_bsc. */
822
823private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
824 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
825 log("initial bsc rate counters: ", g_ctr_bsc);
826}
827
828private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
829 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
830}
831
832/* f_ctrs_bsc_init();
833 * f_do_thing();
834 * f_do_thing();
835 * f_do_other();
836 * f_ctrs_bsc_add("thing", 2);
837 * f_ctrs_bsc_add("other");
838 * f_ctrs_bsc_verify();
839 */
840private function f_ctrs_bsc_verify() runs on test_CT {
841 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
842}
843
844/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
845 * f_ctrs_bsc_init();
846 * f_do_thing();
847 * f_ctrs_bsc_expect("thing", 1);
848 */
849private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
850 f_ctrs_bsc_add(countername, val);
851 f_ctrs_bsc_verify();
852}
853
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200854
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200855friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200856 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100857 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200858 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100859}
860
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200861private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100862 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200863 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100864 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200865 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
866 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100867 T.start;
868 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200869 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
870 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200871 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100872 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200873 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200874 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100875 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200876 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200877 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100878 repeat;
879 }
880 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200881 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200882 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200883 /* If we received a RESET after ours was sent, it
884 may be a race condition where the other peer beacame
885 available after we sent it, but we are in a desired
886 state anyway, so go forward. */
887 if (not reset_received) {
888 setverdict(fail);
889 }
890 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100891 }
Harald Welte28d943e2017-11-25 15:00:50 +0100892}
893
Harald Welteae026692017-12-09 01:03:01 +0100894type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100895 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100896 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100897 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100898 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100899 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100900 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100901 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100902 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100903}
904
Harald Welte21b46bd2017-12-17 19:46:32 +0100905/*! Start the IPA/RSL related bits for one IPA_Client.
906 * \param clnt IPA_Client for which to establish
907 * \param bsc_host IP address / hostname of the BSC
908 * \param bsc_port TCP port number of the BSC
909 * \param i number identifying this BTS
910 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100911function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
912 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100913runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100914 timer T := 10.0;
915
Harald Welte96c94412017-12-09 03:12:45 +0100916 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100917 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
918 clnt.ccm_pars := c_IPA_default_ccm_pars;
919 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
920 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100921 if (handler_mode) {
922 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100923 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100924 }
Harald Welteae026692017-12-09 01:03:01 +0100925
926 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100927 if (handler_mode) {
928 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
929 } else {
930 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
931 }
Harald Welteae026692017-12-09 01:03:01 +0100932
Harald Welte5d1a2202017-12-13 19:51:29 +0100933 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100934 if (handler_mode) {
935 clnt.vc_RSL.start(RSL_Emulation.main());
936 return;
937 }
Harald Welteae026692017-12-09 01:03:01 +0100938
939 /* wait for IPA RSL link to connect and send ID ACK */
940 T.start;
941 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700942 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100943 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700944 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100945 }
Harald Welte60e823a2017-12-10 14:10:59 +0100946 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100947 [] IPA_RSL[i].receive { repeat }
948 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100949 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200950 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100951 }
952 }
953}
954
Harald Welte12055472018-03-17 20:10:08 +0100955function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
956 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
957 return;
958 }
959 clnt.vc_IPA.stop;
960 if (isbound(clnt.vc_RSL)) {
961 clnt.vc_RSL.stop;
962 }
963}
964
Harald Welte21b46bd2017-12-17 19:46:32 +0100965/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100966function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
967 timer T := secs_max;
968 T.start;
969 while (true) {
970 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
971 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100972 /* the 'degraded' state exists from OML connection time, and we have to wait
973 * until all MO's are initialized */
974 T.start(1.0);
975 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100976 return;
977 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100978 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100979 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100980 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200981 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100982 }
983 }
984}
985
Harald Welte21b46bd2017-12-17 19:46:32 +0100986/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100987altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100988 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100989 [] T_guard.timeout {
990 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200991 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100992 }
Harald Welte60e823a2017-12-10 14:10:59 +0100993 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200994 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100995 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200996 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100997 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100998 }
Harald Welte28d943e2017-11-25 15:00:50 +0100999}
1000
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001001altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001002 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001003 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001004 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001005 }
1006}
1007
Daniel Willmann191e0d92018-01-17 12:44:35 +01001008function f_init_mgcp(charstring id) runs on test_CT {
1009 id := id & "-MGCP";
1010
1011 var MGCPOps ops := {
1012 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1013 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1014 };
1015 var MGCP_conn_parameters mgcp_pars := {
1016 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001017 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001018 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001019 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001020 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1021 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001022 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001023 };
1024
1025 vc_MGCP := MGCP_Emulation_CT.create(id);
1026 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1027}
1028
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001029/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1030 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1031 * OsmuxCID IE.
1032 */
1033private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1034 f_vty_enter_cfg_msc(BSCVTY, 0);
1035 if (allow) {
1036 f_vty_transceive(BSCVTY, "osmux on");
1037 } else {
1038 f_vty_transceive(BSCVTY, "osmux off");
1039 }
1040 f_vty_transceive(BSCVTY, "exit");
1041 f_vty_transceive(BSCVTY, "exit");
1042 g_osmux_enabled := allow;
1043}
1044
Max2253c0b2018-11-06 19:28:05 +01001045function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001046 if (BSCVTY.checkstate("Mapped")) {
1047 /* skip initialization if already executed once */
1048 return;
1049 }
Harald Weltebc03c762018-02-12 18:09:38 +01001050 map(self:BSCVTY, system:BSCVTY);
1051 f_vty_set_prompts(BSCVTY);
1052 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001053 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1054 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001055}
1056
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001057friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001058{
1059 // log on TTCN3 log output
1060 log(log_msg);
1061 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001062 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001063}
1064
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001065private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1066{
1067 if (rsl_idx >= lengthof(g_system_information)) {
1068 g_system_information[rsl_idx] := SystemInformationConfig_omit
1069 }
1070 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1071}
1072
1073altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1074 var ASP_RSL_Unitdata rx_rsl_ud;
1075
1076 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1077 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1078 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1079 repeat;
1080 }
1081 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1082 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1083 repeat;
1084 }
1085 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1086 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1087 repeat;
1088 }
1089 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1090 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1091 repeat;
1092 }
1093
1094 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1095 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1096 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1097 repeat;
1098 }
1099 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1100 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1101 repeat;
1102 }
1103 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1104 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1105 repeat;
1106 }
1107 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1108 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1109 repeat;
1110 }
1111}
1112
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001113/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1114private type record of boolean my_BooleanList;
1115
1116private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1117{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001118 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1119
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001120 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001121 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1122 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1123 * stepping into that config node. */
1124 log("msc ", msc_nr, " is not configured, skipping");
1125 continue;
1126 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001127 f_vty_enter_cfg_msc(pt, msc_nr);
1128 if (allow_attach_list[msc_nr]) {
1129 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1130 f_vty_transceive(pt, "allow-attach", strict := false);
1131 } else {
1132 f_vty_transceive(pt, "no allow-attach", strict := false);
1133 }
1134 f_vty_transceive(pt, "exit");
1135 f_vty_transceive(pt, "exit");
1136 }
1137}
1138
Harald Welte21b46bd2017-12-17 19:46:32 +01001139/* global initialization function
1140 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001141 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1142 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1143 */
1144function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001145 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001146 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001147
Harald Welteae026692017-12-09 01:03:01 +01001148 if (g_initialized) {
1149 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001150 }
Harald Welteae026692017-12-09 01:03:01 +01001151 g_initialized := true;
1152
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001153 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001154 activate(as_Tguard());
1155
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001156 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001157 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001158
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001159 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001160 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1161
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001162 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1163 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1164 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1165 }
1166
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001167 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001168 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001169 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1170 * MSC-side BSSAP emulation */
1171 if (handler_mode) {
1172 var RanOps ranops := MSC_RanOps;
1173 ranops.use_osmux := g_osmux_enabled;
1174 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1175 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1176 f_ran_adapter_start(g_bssap[bssap_idx]);
1177 } else {
1178 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1179 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1180 f_ran_adapter_start(g_bssap[bssap_idx]);
1181 f_legacy_bssap_reset();
1182 }
Harald Welte67089ee2018-01-17 22:19:03 +01001183 }
Harald Welted5833a82018-05-27 16:52:56 +02001184
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001185 if (mp_enable_lcs_tests) {
1186 if (handler_mode) {
1187 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1188 } else {
1189 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1190 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1191 }
1192 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001193 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001194
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001195 /* start the test with exactly all enabled MSCs allowed to attach */
1196 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1197
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001198 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001199
Daniel Willmann191e0d92018-01-17 12:44:35 +01001200 f_init_mgcp("VirtMSC");
1201
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001202 for (var integer i := 0; i < nr_bts; i := i+1) {
1203 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001204 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001205}
Harald Welte696ddb62017-12-08 14:01:43 +01001206
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001207function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1208runs on test_CT {
1209 /* wait until osmo-bts-omldummy has respawned */
1210 f_wait_oml(bts_idx, "degraded", 5.0);
1211
1212 /* start RSL connection */
1213 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1214 /* wait until BSC tells us "connected" */
1215 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001216}
1217
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001218function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1219 template SystemInformationConfig expect_si)
1220runs on test_CT {
1221 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1222
1223 f_init_bts(bts_idx, handler_mode);
1224
1225 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1226 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1227 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1228 */
1229 f_sleep(5.0);
1230 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1231
1232 deactivate(sysinfo);
1233
1234 if (match(g_system_information[bts_idx], expect_si)) {
1235 setverdict(pass);
1236 } else {
1237 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1238 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1239 setverdict(fail, "received SI does not match expectations");
1240 return;
1241 }
1242}
1243
Maxd4e56962018-10-31 19:08:25 +01001244/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001245function f_exp_ipa_rx(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001246runs on test_CT return RSL_Message {
1247 var ASP_RSL_Unitdata rx_rsl_ud;
1248 timer T := t_secs;
1249
1250 T.start;
1251 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001252 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001253 T.stop;
1254 }
1255 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001256 [] T.timeout {
1257 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001258 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001259 }
Harald Welteae026692017-12-09 01:03:01 +01001260 }
1261 return rx_rsl_ud.rsl;
1262}
1263
Harald Welte21b46bd2017-12-17 19:46:32 +01001264/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001265function f_ipa_tx(integer bts_nr, template (value) RSL_Message t_tx, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001266runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001267 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001268}
1269
1270
Harald Welte4003d112017-12-09 22:35:39 +01001271/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001272testcase TC_chan_act_noreply() runs on test_CT {
1273 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001274 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001275
Harald Welte89d42e82017-12-17 16:42:41 +01001276 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001277
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001278 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001279 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001280 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001281}
1282
Harald Welte4003d112017-12-09 22:35:39 +01001283/* verify if the "chreq:total" counter increments as expected */
1284testcase TC_chan_act_counter() runs on test_CT {
1285 var BSSAP_N_UNITDATA_ind ud_ind;
1286 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001287 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001288
Harald Welte89d42e82017-12-17 16:42:41 +01001289 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001290
1291 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001292 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001293 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001294 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1295
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001296 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001297}
1298
Harald Welteae026692017-12-09 01:03:01 +01001299/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001300private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001301 var RSL_Message rx_rsl;
1302
Harald Welteae026692017-12-09 01:03:01 +01001303 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001304 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001305
1306 /* expect BSC to disable the channel again if there's no RLL EST IND */
1307 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1308
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001309 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001310}
1311
Philipp Maier9c60a622020-07-09 15:08:46 +02001312/* Normal variant */
1313testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001314 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001315 f_TC_chan_act_ack_noest();
1316}
1317
1318/* Emergency call variant */
1319testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1320 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001321 f_init(1);
1322 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001323 f_TC_chan_act_ack_noest(ra := 'A5'O);
1324}
1325
Philipp Maier606f07d2020-08-12 17:21:58 +02001326/* Emergency call variant, but emergency calls are not allowed */
1327testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1328 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1329
1330 var RSL_Message rx_rsl;
1331 var GsmRrMessage rr;
1332
1333 f_init(1);
1334 f_vty_allow_emerg_bts(false, 0);
1335
1336 IPA_RSL[0].clear;
1337 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1338
1339 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1340 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1341 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1342 setverdict(pass);
1343 } else {
1344 setverdict(fail, "immediate assignment not rejected");
1345 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001346
1347 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001348}
1349
Harald Welteae026692017-12-09 01:03:01 +01001350/* Test behavior if MSC never answers to CR */
1351testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001352 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1353 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001354 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001355 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001356
Harald Welte89d42e82017-12-17 16:42:41 +01001357 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001358
1359 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001360 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001361
1362 var octetstring l3 := '00010203040506'O
1363 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1364
1365 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1366
1367 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001368 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001369 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001370 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001371}
1372
1373/* Test behavior if MSC answers with CREF to CR */
1374testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1375 var BSSAP_N_CONNECT_ind rx_c_ind;
1376 var RSL_Message rx_rsl;
1377
Harald Welte89d42e82017-12-17 16:42:41 +01001378 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001379
1380 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001381 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001382
1383 var octetstring l3 := '00010203040506'O
1384 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1385
1386 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1387 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1388
1389 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001390 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001391 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001392}
1393
Harald Welte618ef642017-12-14 14:58:20 +01001394/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1395testcase TC_chan_act_nack() runs on test_CT {
1396 var RSL_Message rx_rsl;
1397 var integer chact_nack;
1398
Harald Welte89d42e82017-12-17 16:42:41 +01001399 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001400
1401 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1402
1403 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1404 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1405 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1406
1407 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1408
1409 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1410 f_sleep(0.5);
1411
1412 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1413
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001414 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001415}
1416
Harald Welte799c97b2017-12-14 17:50:30 +01001417/* Test for channel exhaustion due to RACH overload */
1418testcase TC_chan_exhaustion() runs on test_CT {
1419 var ASP_RSL_Unitdata rsl_ud;
1420 var integer i;
1421 var integer chreq_total, chreq_nochan;
1422
Harald Welte89d42e82017-12-17 16:42:41 +01001423 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001424
1425 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1426 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1427
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001428 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001429 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1430 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001431 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001432 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001433 }
1434
1435 IPA_RSL[0].clear;
1436
Harald Weltedd8cbf32018-01-28 12:07:52 +01001437 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001438 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001439
1440 /* now expect additional channel activations to fail */
1441 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1442
1443 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001444 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001445 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1446 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001447 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001448 var GsmRrMessage rr;
1449 /* match on IMM ASS REJ */
1450 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1451 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1452 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001453 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001454 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1455 chreq_nochan+1);
1456 setverdict(pass);
1457 } else {
1458 repeat;
1459 }
1460 }
1461 [] IPA_RSL[0].receive { repeat; }
1462 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001463 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001464}
1465
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001466/* Test channel deactivation due to silence from MS */
1467testcase TC_chan_deact_silence() runs on test_CT {
1468 var RslChannelNr chan_nr;
1469
1470 f_init(1);
1471
1472 /* Request for a dedicated channel */
1473 chan_nr := f_chreq_act_ack('23'O);
1474
1475 /* Wait some time until the channel is released */
1476 f_sleep(2.0);
1477
1478 /* Expect CHANnel RELease */
1479 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001480 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001481 log("Received CHANnel RELease");
1482 setverdict(pass);
1483 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001484 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001485 /* See OS#3709, OsmoBSC should not send Immediate
1486 * Assignment Reject since a dedicated channel was
1487 * already allocated, and Immediate Assignment was
1488 * already sent. */
1489 setverdict(fail, "Unexpected Immediate Assignment!");
1490 }
1491 [] IPA_RSL[0].receive {
1492 setverdict(fail, "Unexpected RSL message!");
1493 }
1494 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001495 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001496}
1497
Harald Weltecfe2c962017-12-15 12:09:32 +01001498/***********************************************************************
1499 * Assignment Testing
1500 ***********************************************************************/
1501
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001502/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1503 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001504testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001505 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001506
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001507 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1508 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001509 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001510 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001511}
1512
Harald Welte16a4adf2017-12-14 18:54:01 +01001513/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001514testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001515 var BSSAP_N_CONNECT_ind rx_c_ind;
1516 var RSL_Message rx_rsl;
1517 var DchanTuple dt;
1518
Harald Welte89d42e82017-12-17 16:42:41 +01001519 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001520
1521 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001522 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001523 /* send assignment without AoIP IEs */
1524 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1525 } else {
1526 /* Send assignmetn without CIC in IPA case */
1527 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1528 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1529 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1530 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001531 alt {
1532 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1533 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1534 }
Harald Welte235ebf12017-12-15 14:18:16 +01001535 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001536 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1537 setverdict(pass);
1538 }
1539 [] BSSAP.receive { repeat; }
1540 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001541 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001542}
1543
Harald Welteed848512018-05-24 22:27:58 +02001544/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001545function f_gen_ass_req(boolean osmux_enabled := false, integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4") return PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001546 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001547 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001548 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001549 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001550 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001551 if (osmux_enabled) {
1552 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1553 } else {
1554 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1555 }
Harald Welteed848512018-05-24 22:27:58 +02001556 } else {
1557 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001558 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001559 }
1560 return ass_cmd;
1561}
1562
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001563function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001564 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1565 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001566 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001567
1568 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1569 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1570 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1571 var template BSSMAP_IE_KC128 kc128 := omit;
1572 if (ispresent(enc)) {
1573 var TestHdlrEncrParams v_enc := valueof(enc);
1574 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1575 chosenEncryptionAlgorithm := valueof(
1576 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001577 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001578 if (ispresent(v_enc.enc_kc128)) {
1579 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1580 }
1581 }
1582
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001583 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001584 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001585 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001586 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1587 encryptionInformation := encryptionInformation,
1588 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1589 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001590 } else {
1591 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001592 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1593 encryptionInformation := encryptionInformation,
1594 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1595 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001596 }
1597 return ho_req;
1598}
1599
Harald Welteed848512018-05-24 22:27:58 +02001600/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001601function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001602 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001603 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001604 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001605 if (expect_osmux) {
1606 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1607 } else {
1608 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1609 }
Harald Welteed848512018-05-24 22:27:58 +02001610 } else {
1611 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001612 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001613 }
1614 return exp_compl;
1615}
1616
Harald Welte235ebf12017-12-15 14:18:16 +01001617/* Run everything required up to sending a caller-specified assignment command and expect response */
1618function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1619runs on test_CT {
1620 var BSSAP_N_CONNECT_ind rx_c_ind;
1621 var RSL_Message rx_rsl;
1622 var DchanTuple dt;
1623
Harald Welte89d42e82017-12-17 16:42:41 +01001624 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001625
1626 dt := f_est_dchan('23'O, 23, '00000000'O);
1627 /* send assignment without AoIP IEs */
1628 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1629 alt {
1630 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1631 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1632 setverdict(pass);
1633 } else {
1634 setverdict(fail, fail_text);
1635 }
1636 }
1637 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1638 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1639 setverdict(pass);
1640 } else {
1641 setverdict(fail, fail_text);
1642 }
1643 }
1644 [] BSSAP.receive { repeat; }
1645 }
1646}
1647testcase TC_assignment_csd() runs on test_CT {
1648 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001649 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001650 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1651 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1652 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001653 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001654}
1655
1656testcase TC_assignment_ctm() runs on test_CT {
1657 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001658 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001659 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1660 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1661 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001662 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001663}
1664
Harald Welte4003d112017-12-09 22:35:39 +01001665type record DchanTuple {
1666 integer sccp_conn_id,
1667 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001668}
1669
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001670type record of DchanTuple DchanTuples;
1671
Harald Welted6939652017-12-13 21:02:46 +01001672/* Send CHAN RQD and wait for allocation; acknowledge it */
1673private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1674runs on test_CT return RslChannelNr {
1675 var RSL_Message rx_rsl;
1676 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1677 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1678 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1679 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001680 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001681 return chan_nr;
1682}
1683
Harald Welte4003d112017-12-09 22:35:39 +01001684/* helper function to establish a dedicated channel via BTS and MSC */
1685function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1686runs on test_CT return DchanTuple {
1687 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001688 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001689
Harald Welte4003d112017-12-09 22:35:39 +01001690 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001691 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001692
1693 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1694
1695 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1696 dt.sccp_conn_id := rx_c_ind.connectionId;
1697 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1698
1699 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001700}
1701
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001702/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1703function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1704runs on test_CT return DchanTuple {
1705 var BSSAP_N_CONNECT_ind rx_c_ind;
1706 var DchanTuple dt;
1707
1708 /* Send CHAN RQD */
1709 var RSL_Message rx_rsl;
1710 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1711
1712 /* The dyn TS first deactivates PDCH */
1713 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1714 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1715 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1716
1717 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1718 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1719
1720 /* Now activates the signalling channel */
1721 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1722 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1723
1724 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1725
1726 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1727 dt.sccp_conn_id := rx_c_ind.connectionId;
1728 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1729
1730 return dt;
1731}
1732
Harald Welte641fcbe2018-06-14 10:58:35 +02001733/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1734private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1735 var RSL_Message rx_rsl;
1736 /* expect BSC to disable the channel */
1737 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1738 /* respond with CHAN REL ACK */
1739 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1740
1741 /* expect Clear Complete from BSC */
1742 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1743
1744 /* MSC disconnects as instructed. */
1745 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1746}
1747
Harald Welte4003d112017-12-09 22:35:39 +01001748/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1749testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001750 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001751 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001752
Harald Welte89d42e82017-12-17 16:42:41 +01001753 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001754
Harald Welte4003d112017-12-09 22:35:39 +01001755 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1756
1757 /* simulate RLL REL IND */
1758 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1759
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001760 /* expect Clear Request on MSC side */
1761 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1762
1763 /* Instruct BSC to clear channel */
1764 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1765 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1766
Harald Welte4003d112017-12-09 22:35:39 +01001767 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001768 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001769
1770 /* wait for SCCP emulation to do its job */
1771 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001772
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001773 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001774}
1775
1776/* Test behavior of channel release after CONN FAIL IND from BTS */
1777testcase TC_chan_rel_conn_fail() runs on test_CT {
1778 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001779 var DchanTuple dt;
1780
Harald Welte89d42e82017-12-17 16:42:41 +01001781 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001782
1783 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1784
1785 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001786 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001787 /* TODO: different cause values? */
1788
Harald Welte4003d112017-12-09 22:35:39 +01001789 /* expect Clear Request from BSC */
1790 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1791
1792 /* Instruct BSC to clear channel */
1793 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1794 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1795
Harald Welte6ff76ea2018-01-28 13:08:01 +01001796 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001797 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001798
1799 /* wait for SCCP emulation to do its job */
1800 f_sleep(1.0);
1801
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001802 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001803}
1804
Harald Welte99f3ca02018-06-14 13:40:29 +02001805/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1806/* See also https://www.osmocom.org/issues/3182 */
1807testcase TC_early_conn_fail() runs on test_CT {
1808 var RSL_Message rx_rsl;
1809 var DchanTuple dt;
1810
1811 f_init(1);
1812
1813 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001814 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001815
1816 /* BTS->BSC: simulate CONN FAIL IND */
1817 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1818
1819 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1820 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1821
1822 /* BTS<-BSC: respond with CHAN REL ACK */
1823 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1824
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001825 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001826}
1827
1828/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1829/* See also https://www.osmocom.org/issues/3182 */
1830testcase TC_late_conn_fail() runs on test_CT {
1831 var RSL_Message rx_rsl;
1832 var DchanTuple dt;
1833
1834 f_init(1);
1835
1836 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1837
1838 /* BSC<-MSC: Instruct BSC to clear connection */
1839 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1840
1841 /* BTS->BSC: expect BSC to deactivate SACCH */
1842 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1843
1844 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1845 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1846
1847 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1848 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1849 /* BTS->BSC: respond with CHAN REL ACK */
1850 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1851
1852 /* BSC->MSC: expect Clear Complete from BSC */
1853 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1854
1855 /* BSC<-MSC: MSC disconnects as requested. */
1856 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1857
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001858 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001859}
1860
Oliver Smithaf03bef2021-08-24 15:34:51 +02001861private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1862 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1863 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1864
1865 f_statsd_reset();
1866
1867 /* Establish SDCCH */
1868 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1869 f_establish_fully(ass_cmd, exp_fail);
1870
1871 /* Expect stats to be 0 */
1872 var StatsDExpects expect := {
1873 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1874 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1875 };
1876 f_statsd_expect(expect);
1877
1878 /* Simulate CONN FAIL IND on SDCCH */
1879 RSL.send(ts_ASP_RSL_UD(
1880 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1881 IPAC_PROTO_RSL_TRX0));
1882
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001883 f_sleep(1.0);
1884
Oliver Smithaf03bef2021-08-24 15:34:51 +02001885 /* Expect stats to be 1 */
1886 expect := {
1887 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1888 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1889 };
1890 f_statsd_expect(expect);
1891}
1892testcase TC_stats_conn_fail() runs on test_CT {
1893 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1894 var MSC_ConnHdlr vc_conn;
1895
1896 f_init(1, true);
1897 f_sleep(1.0);
1898
1899 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1900 vc_conn.done;
1901
1902 f_shutdown_helper();
1903}
1904
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001905function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001906 boolean expect_deact_sacch := true,
1907 boolean expect_rr_chan_rel := true,
1908 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001909 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001910 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001911 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001912 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001913
1914 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001915 var boolean got_deact_sacch := false;
1916 var boolean got_rr_chan_rel := false;
1917 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001918 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001919 var RSL_IE_Body l3_ie;
1920 var PDU_ML3_NW_MS l3;
1921 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001922 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1923 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001924 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001925 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001926 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001927 repeat;
1928 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001929 [not istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE_CellSelectInd))) -> value ud {
Harald Welte99787102019-02-04 10:41:36 +01001930 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001931
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001932 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1933 setverdict(fail, "cannot find L3");
1934 mtc.stop;
1935 }
1936 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1937
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001938 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001939 var CellSelIndValue cells := dec_CellSelIndValue(
1940 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1941
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001942 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1943 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001944 setverdict(pass);
1945 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001946 log("EXPECTED CELLS: ", expect_cells);
1947 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001948 }
1949 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001950
1951 if (not istemplatekind(expect_rr_cause, "omit")) {
1952 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1953 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1954 if (match(got_cause, expect_rr_cause)) {
1955 setverdict(pass);
1956 } else {
1957 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1958 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1959 }
1960 }
Harald Welte99787102019-02-04 10:41:36 +01001961 repeat;
1962 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001963 [istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) -> value ud {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001964 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001965
1966 if (not istemplatekind(expect_rr_cause, "omit")) {
1967 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1968 setverdict(fail, "cannot find L3");
1969 mtc.stop;
1970 }
1971 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1972
1973 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1974 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1975 if (match(got_cause, expect_rr_cause)) {
1976 setverdict(pass);
1977 } else {
1978 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1979 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1980 }
1981 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001982 repeat;
1983 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001984 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001985 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001986 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001987 if (handle_rll_rel) {
1988 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1989 }
Harald Welte91d54a52018-01-28 15:35:07 +01001990 repeat;
1991 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001992 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001993 /* respond with CHAN REL ACK */
1994 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1995 }
1996 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001997 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001998 repeat;
1999 }
2000 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002001
2002 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2003 " got_rll_rel_req=", got_rll_rel_req);
2004
2005 if (expect_deact_sacch != got_deact_sacch) {
2006 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2007 }
2008 if (expect_rr_chan_rel != got_rr_chan_rel) {
2009 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2010 }
2011 if (expect_rll_rel_req != got_rll_rel_req) {
2012 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2013 }
Harald Welte91d54a52018-01-28 15:35:07 +01002014}
2015
Harald Welte4003d112017-12-09 22:35:39 +01002016/* Test behavior of channel release after hard Clear Command from MSC */
2017testcase TC_chan_rel_hard_clear() runs on test_CT {
2018 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002019 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002020
Harald Welte89d42e82017-12-17 16:42:41 +01002021 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002022
2023 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2024
2025 /* Instruct BSC to clear channel */
2026 var BssmapCause cause := 0;
2027 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2028
2029 /* expect Clear Complete from BSC on A */
2030 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2031 /* release the SCCP connection */
2032 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2033 }
2034
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002035 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002036 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002037}
2038
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002039function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2040 var BSSAP_N_DATA_ind rx_di;
2041 var DchanTuple dt;
2042
2043 f_init(1);
2044
2045 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2046 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2047 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2048 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2049
2050 /* Instruct BSC to clear channel */
2051 var BssmapCause cause := 0;
2052 if (tx_csfb_ind) {
2053 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2054 } else {
2055 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2056 }
2057
2058 /* expect Clear Complete from BSC on A */
2059 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2060 /* release the SCCP connection */
2061 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2062 }
2063
2064 /* 1 neighbor is added by default in osmo-bts.cfg and
2065 SystemInformationConfig_default, use that: */
2066 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2067
2068 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2069 f_shutdown_helper();
2070}
2071
2072/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2073 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2074 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2075 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2076 Indicator or not shouldn't matter at all. */
2077testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2078 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2079}
2080
2081/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2082 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2083 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2084 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2085testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2086 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2087}
2088
2089/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2090 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2091 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2092 CSFB Indicator should not be used anymore, and hence, there should be no
2093 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2094 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002095testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2096 var BSSAP_N_DATA_ind rx_di;
2097 var DchanTuple dt;
2098
2099 f_init(1);
2100
2101 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2102
2103 /* Instruct BSC to clear channel */
2104 var BssmapCause cause := 0;
2105 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2106
2107 /* expect Clear Complete from BSC on A */
2108 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2109 /* release the SCCP connection */
2110 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2111 }
2112
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002113 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002114 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002115}
2116
Harald Welted8c36cd2017-12-09 23:05:31 +01002117/* Test behavior of channel release after hard RLSD from MSC */
2118testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002119 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002120
Harald Welte89d42e82017-12-17 16:42:41 +01002121 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002122
2123 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2124
2125 /* release the SCCP connection */
2126 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2127
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002128 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002129 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002130}
2131
Harald Welte550daf92018-06-11 19:22:13 +02002132/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2133testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2134 var DchanTuple dt;
2135
2136 f_init(1);
2137
2138 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2139
2140 /* release the SCCP connection */
2141 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2142
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002143 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002144 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002145}
2146
Harald Welte85804d42017-12-10 14:11:58 +01002147/* Test behavior of channel release after BSSMAP RESET from MSC */
2148testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002149 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002150
Harald Welte89d42e82017-12-17 16:42:41 +01002151 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002152
2153 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2154
2155 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2156 IPA_RSL[0].clear;
2157
2158 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002159 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Welte85804d42017-12-10 14:11:58 +01002160 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002161 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
Harald Welte85804d42017-12-10 14:11:58 +01002162 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2163 }
2164
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002165 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002166 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002167}
2168
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002169/* Verify T(iar) triggers and releases the channel */
2170testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2171 var DchanTuple dt;
2172
2173 /* Set T(iar) in BSC low enough that it will trigger before other side
2174 has time to keep alive with a T(ias). Keep recommended ratio of
2175 T(iar) >= T(ias)*2 */
2176 g_bsc_sccp_timer_ias := 2;
2177 g_bsc_sccp_timer_iar := 5;
2178
2179 f_init(1);
2180
2181 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2182 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002183 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002184}
2185
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002186private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2187runs on test_CT
2188{
2189 var DchanTuple dt;
2190
2191 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2192 var BssmapCause cause := 0;
2193 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2194 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2195 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2196 }
2197
2198 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_rr_cause := expect_rr_cause);
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002199}
2200
2201/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2202testcase TC_chan_rel_rr_cause() runs on test_CT {
2203 f_init(1);
2204
2205 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2206 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2207 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2208 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2209 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2210 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002211
2212 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002213}
2214
Harald Welte5cd20ed2017-12-13 21:03:20 +01002215/* Test behavior if RSL EST IND for non-active channel */
2216testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2217 timer T := 2.0;
2218
Harald Welte89d42e82017-12-17 16:42:41 +01002219 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002220
2221 var octetstring l3 := '00010203040506'O;
2222 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2223 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2224
2225 T.start;
2226 alt {
2227 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2228 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2229 }
2230 [] BSSAP.receive {}
2231 [] IPA_RSL[0].receive {}
2232 [] T.timeout {}
2233 }
2234
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002235 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002236}
2237
2238/* Test behavior if RSL EST IND for invalid SAPI */
2239testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2240 var RslChannelNr chan_nr;
2241
Harald Welte89d42e82017-12-17 16:42:41 +01002242 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002243
2244 chan_nr := f_chreq_act_ack()
2245
2246 var octetstring l3 := '00010203040506'O;
2247 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2248
2249 timer T := 2.0;
2250 T.start;
2251 alt {
2252 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2253 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2254 }
2255 [] BSSAP.receive { repeat; }
2256 [] IPA_RSL[0].receive { repeat; }
2257 [] T.timeout {}
2258 }
2259
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002260 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002261}
2262
2263/* Test behavior if RSL EST IND for invalid SAPI */
2264testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2265 timer T := 2.0;
2266
Harald Welte89d42e82017-12-17 16:42:41 +01002267 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002268
2269 var RslChannelNr chan_nr := f_chreq_act_ack();
2270
2271 var octetstring l3 := '00010203040506'O;
2272 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2273
2274 T.start;
2275 alt {
2276 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2277 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2278 }
2279 [] BSSAP.receive { repeat; }
2280 [] IPA_RSL[0].receive { repeat; }
2281 [] T.timeout {}
2282 }
2283
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002284 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002285}
2286
2287/* Test behavior if RSL EST IND for invalid SACCH */
2288testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2289 timer T := 2.0;
2290
Harald Welte89d42e82017-12-17 16:42:41 +01002291 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002292
2293 var RslChannelNr chan_nr := f_chreq_act_ack();
2294
2295 var octetstring l3 := '00010203040506'O;
2296 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2297
2298 T.start;
2299 alt {
2300 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2301 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2302 }
2303 [] BSSAP.receive { repeat; }
2304 [] IPA_RSL[0].receive { repeat; }
2305 [] T.timeout {}
2306 }
2307
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002308 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002309}
2310
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002311/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2312private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2313 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2314 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2315
2316 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2317 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2318
2319 f_establish_fully(ass_cmd, exp_compl);
2320
2321 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2322 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2323 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2324 BSSAP.receive(PDU_BSSAP:{
2325 discriminator := '1'B,
2326 spare := '0000000'B,
2327 dlci := 'C3'O,
2328 lengthIndicator := ?,
2329 pdu := { dtap := '0904'O }
2330 });
2331
2332 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2333 for (var integer i := 0; i < 32; i := i + 1) {
2334 var octetstring l3 := '09'O & f_rnd_octstring(14);
2335 var template (value) RslLinkId link_id;
2336 var template (value) OCT1 dlci;
2337
2338 if (i mod 2 == 0) {
2339 /* SAPI0 on FACCH or SDCCH */
2340 link_id := ts_RslLinkID_DCCH(0);
2341 dlci := '80'O;
2342 } else {
2343 /* SAPI3 on SACCH */
2344 link_id := ts_RslLinkID_SACCH(3);
2345 dlci := 'C3'O;
2346 }
2347
2348 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002349 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002350 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002351 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002352 }
2353}
2354testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2355 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2356 var MSC_ConnHdlr vc_conn;
2357
2358 f_init(1, true);
2359 f_sleep(1.0);
2360
2361 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2362 vc_conn.done;
2363
2364 f_shutdown_helper();
2365}
2366
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002367private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2368 template myBSSMAP_Cause cause := ?,
2369 float T_val := 2.0)
2370runs on test_CT {
2371 var BSSAP_N_DATA_ind rx_di;
2372 timer T;
2373
2374 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2375 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2376
2377 T.start(T_val);
2378 alt {
2379 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2380 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2381 if (not match(rx_cause, tr_cause)) {
2382 setverdict(fail, "Rx unexpected Cause IE: ",
2383 rx_cause, " vs expected ", tr_cause);
2384 }
2385 setverdict(pass);
2386 }
2387 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2388 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2389 }
2390 [] T.timeout {
2391 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2392 }
2393 }
2394}
2395
2396/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2397testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2398 var octetstring rnd_data := f_rnd_octstring(16);
2399 var RSL_Message rx_rsl;
2400 var DchanTuple dt;
2401
2402 f_init(1);
2403
2404 /* MS establishes a SAPI=0 link on DCCH */
2405 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2406
2407 /* MSC sends some data on (not yet established) SAPI=3 link */
2408 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2409 /* BSC attempts to establish a SAPI=3 link on DCCH */
2410 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2411
2412 /* MS sends unexpected RELease INDication on SAPI=3 */
2413 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2414 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2415 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2416
2417 /* Clean up the connection */
2418 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2419 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2420
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002421 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002422}
2423
2424/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2425testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2426 var octetstring rnd_data := f_rnd_octstring(16);
2427 var RSL_Message rx_rsl;
2428 var DchanTuple dt;
2429
2430 f_init(1);
2431
2432 /* MS establishes a SAPI=0 link on DCCH */
2433 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2434
2435 /* MSC sends some data on (not yet established) SAPI=3 link */
2436 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2437 /* BSC attempts to establish a SAPI=3 link on DCCH */
2438 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2439
2440 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2441 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2442 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2443 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2444
2445 /* Clean up the connection */
2446 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2447 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2448
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002449 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002450}
2451
2452/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2453testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2454 var octetstring rnd_data := f_rnd_octstring(16);
2455 var RSL_Message rx_rsl;
2456 var DchanTuple dt;
2457
2458 f_init(1);
2459
2460 /* MS establishes a SAPI=0 link on DCCH */
2461 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2462
2463 /* MSC sends some data on (not yet established) SAPI=3 link */
2464 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2465 /* BSC attempts to establish a SAPI=3 link on DCCH */
2466 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2467
2468 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2469 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2470
2471 /* Clean up the connection */
2472 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2473 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2474
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002475 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002476}
2477
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002478testcase TC_si_default() runs on test_CT {
2479 f_init(0);
2480 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002481 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002482}
Harald Welte4003d112017-12-09 22:35:39 +01002483
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002484/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2485 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2486private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2487{
2488 select (earfcn_index) {
2489 case (0) {
2490 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2491 return 111;
2492 }
2493 case (1) {
2494 return 1;
2495 }
2496 case (2) {
2497 return 0;
2498 }
2499 case (3) {
2500 return 65535;
2501 }
2502 case else {
2503 return 23 * (earfcn_index - 3);
2504 }
2505 }
2506}
2507
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002508function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2509 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002510
2511 f_init(0);
2512
2513 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2514 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002515 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2516 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002517 }
2518
2519 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2520
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002521 if (not istemplatekind(expect_cells, "omit")) {
2522 /* Also check that RR Channel Release contains these EARFCNs.
2523 * (copied code from TC_chan_rel_hard_clear_csfb) */
2524 var BSSAP_N_DATA_ind rx_di;
2525 var DchanTuple dt;
2526
2527 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002528 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2529 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2530 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002531
2532 /* Instruct BSC to clear channel */
2533 var BssmapCause cause := 0;
2534 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2535
2536 /* expect Clear Complete from BSC on A */
2537 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2538 /* release the SCCP connection */
2539 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2540 }
2541
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002542 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002543 }
2544
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002545 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002546 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list del earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002547 }
2548}
2549
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002550private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2551{
2552 var template SI2quaterRestOctetsList si2quater := {};
2553 var integer si2quater_count := (count + 2) / 3;
2554
2555 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002556 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002557 var integer index := i / 3;
2558 var integer earfcn_index := i mod 3;
2559 if (index >= lengthof(si2quater)) {
2560 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2561 }
2562 si2quater[index].rel_additions.rel5.rel6.rel7.rel8.prio_eutran_params_desc.desc.eutran_params_desc.desc.repeated_neigh_cells[0].cell_desc_list[earfcn_index] := tr_EUTRAN_CellDesc_default(e_arfcn := earfcn);
2563 }
2564
2565 return si2quater;
2566}
2567
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002568private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2569{
2570 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2571
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002572 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002573 for (var integer i := 0; i < count; i := i + 1) {
2574 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002575 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002576 }
2577
2578 return tr_CellSelIndValue_EUTRAN(cells);
2579}
2580
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002581private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2582{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002583 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002584 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002585 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2586 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002587}
2588
2589testcase TC_si2quater_2_earfcns() runs on test_CT {
2590 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002591 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002592}
2593
2594testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002595 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002596 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002597}
2598
2599testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002600 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002601 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002602}
2603
2604testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002605 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002606 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002607}
2608
2609testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002610 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002611 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002612}
2613
2614testcase TC_si2quater_12_earfcns() runs on test_CT {
2615 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002616 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002617}
2618
2619testcase TC_si2quater_23_earfcns() runs on test_CT {
2620 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002621 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002622}
2623
2624testcase TC_si2quater_32_earfcns() runs on test_CT {
2625 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002626 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002627}
2628
2629testcase TC_si2quater_33_earfcns() runs on test_CT {
2630 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002631 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002632}
2633
2634testcase TC_si2quater_42_earfcns() runs on test_CT {
2635 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002636 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002637}
2638
2639testcase TC_si2quater_48_earfcns() runs on test_CT {
2640 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002641 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002642}
2643
2644/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2645 * 48 EARFCNs. */
2646testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002647 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002648 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2649 f_init(0);
2650
2651 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002652 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2653 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002654 }
2655
2656 /* The 49th EARFCN no longer fits, expect VTY error */
2657 f_vty_enter_cfg_bts(BSCVTY, 0);
2658 var charstring vty_error;
2659 vty_error := f_vty_transceive_ret(BSCVTY,
2660 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2661 f_vty_transceive(BSCVTY, "end");
2662
2663 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2664 log("Got expected VTY error: ", vty_error);
2665 setverdict(pass);
2666 } else {
2667 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2668 }
2669
2670 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2671
2672 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002673 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list del earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002674 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002675 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002676}
2677
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002678private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2679{
2680 var uint8_t count := 0;
2681 for (var integer i := 5; i < 16; i := i + 1) {
2682 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2683 count := count + 1;
2684 }
2685 }
2686 return count;
2687}
2688
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002689private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2690{
2691 var ASP_RSL_Unitdata rx_rsl_ud;
2692 var SystemInformationType1 last_si1;
2693
2694 timer T := 30.0;
2695 T.start;
2696 alt {
2697 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2698 tr_RSL_BCCH_INFO,
2699 tr_RSL_NO_SACCH_FILL,
2700 tr_RSL_SACCH_FILL))
2701 ) -> value rx_rsl_ud {
2702 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2703 if (g_system_information[rsl_idx].si1 == omit) {
2704 repeat;
2705 }
2706 last_si1 := g_system_information[rsl_idx].si1;
2707 g_system_information[rsl_idx].si1 := omit;
2708 T.stop;
2709 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002710 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002711 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2712 }
2713 return last_si1;
2714}
2715
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002716/* verify ACC rotate feature */
2717testcase TC_si_acc_rotate() runs on test_CT {
2718 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002719 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002720 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002721 var uint8_t count;
2722 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2723
2724 f_init(0, guard_timeout := 60.0);
2725
2726 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2727 "access-control-class-rotate 3",
2728 "access-control-class-rotate-quantum 1"});
2729
2730 /* Init and get first sysinfo */
2731 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2732
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002733 for (var integer i:= 0; i < 20; i := i + 1) {
2734 last_si1 := f_recv_next_si1(0);
2735 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002736 count := f_acc09_count_allowed(acc);
2737 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2738
2739 if (count != 3) {
2740 log("RSL: EXPECTED SI ACC len=3");
2741 setverdict(fail, "received SI does not match expectations");
2742 break;
2743 }
2744
2745 for (var integer j := 0; j < 10; j := j + 1) {
2746 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2747 times_allowed[j] := times_allowed[j] + 1;
2748 }
2749 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002750 }
2751
2752 for (var integer j := 0; j < 10; j := j + 1) {
2753 log("ACC", j, " allowed ", times_allowed[j], " times" );
2754 if (j != 5 and times_allowed[j] < 3) {
2755 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2756 } else if (j == 5 and times_allowed[j] > 0) {
2757 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2758 }
2759 }
2760
2761 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2762 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002763 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002764}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002765
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002766/* verify ACC startup ramp+rotate feature */
2767testcase TC_si_acc_ramp_rotate() runs on test_CT {
2768 var template SystemInformationConfig sic := SystemInformationConfig_default;
2769 var SystemInformationType1 last_si1;
2770 var AccessControlClass acc;
2771 var ASP_RSL_Unitdata rx_rsl_ud;
2772 var uint8_t count;
2773 var uint8_t prev_count;
2774 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2775
2776 f_init(0, guard_timeout := 80.0);
2777
2778 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2779 "access-control-class-rotate 0",
2780 "access-control-class-rotate-quantum 1",
2781 "access-control-class-ramping",
2782 "access-control-class-ramping-step-interval 5",
2783 "access-control-class-ramping-step-size 5"});
2784
2785 /* Init and get first sysinfo */
2786 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2787 last_si1 := g_system_information[0].si1;
2788 acc := last_si1.rach_control.acc;
2789 count := f_acc09_count_allowed(acc);
2790 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2791 while (count > 0) {
2792 last_si1 := f_recv_next_si1(0);
2793 acc := last_si1.rach_control.acc;
2794 count := f_acc09_count_allowed(acc);
2795 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2796 }
2797
2798 /* Increase adm subset size, we should see ramping start up */
2799 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2800 prev_count := 0;
2801 while (true) {
2802 last_si1 := f_recv_next_si1(0);
2803 acc := last_si1.rach_control.acc;
2804 count := f_acc09_count_allowed(acc);
2805 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2806
2807 if (prev_count > count) {
2808 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2809 break;
2810 }
2811
2812 if (count == 9) {
2813 break; /* Maximum reached (10 - 1 perm barred), done here */
2814 }
2815
2816 prev_count := count;
2817 }
2818
2819 setverdict(pass);
2820
2821 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2822 "rach access-control-class 4 allowed",
2823 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002824 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002825}
2826
Harald Welte4003d112017-12-09 22:35:39 +01002827testcase TC_ctrl_msc_connection_status() runs on test_CT {
2828 var charstring ctrl_resp;
2829
Harald Welte89d42e82017-12-17 16:42:41 +01002830 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002831
2832 /* See https://osmocom.org/issues/2729 */
2833 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002834 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002835}
2836
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002837testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2838 var charstring ctrl_resp;
2839
2840 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002841
2842 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002843 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002844}
2845
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002846/* Verify correct stats on the number of configured and connected MSCs */
2847private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2848 g_pars := f_gen_test_hdlr_pars();
2849 var StatsDExpects expect := {
2850 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2851 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2852 };
2853 f_statsd_expect(expect);
2854}
2855
2856private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2857{
2858 var MSC_ConnHdlr vc_conn;
2859
2860 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2861 f_sleep(1.0);
2862 vc_conn := f_start_handler(tc_fn);
2863 vc_conn.done;
2864
2865 /* Also verify stat exposed on CTRL interface */
2866 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2867 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2868
2869 f_shutdown_helper();
2870}
2871
2872/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2873private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2874 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2875}
2876testcase TC_stat_num_msc_connected_1() runs on test_CT {
2877 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2878}
2879
2880/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2881private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2882 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2883}
2884testcase TC_stat_num_msc_connected_2() runs on test_CT {
2885 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2886}
2887
2888/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2889private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2890 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2891}
2892testcase TC_stat_num_msc_connected_3() runs on test_CT {
2893 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2894}
2895
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002896/* Verify correct stats on the number of configured and connected MSCs */
2897private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
2898 g_pars := f_gen_test_hdlr_pars();
2899 var StatsDExpects expect := {
2900 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
2901 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2902 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
2903 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2904 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
2905 };
2906 f_statsd_expect(expect);
2907}
2908
2909private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
2910 var MSC_ConnHdlr vc_conn;
2911
2912 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
2913 f_sleep(1.0);
2914 vc_conn := f_start_handler(tc_fn);
2915 vc_conn.done;
2916
2917 /* Also verify stat exposed on CTRL interface */
2918 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
2919 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
2920 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
2921 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
2922
Neels Hofmeyra41ae302021-09-06 22:06:02 +02002923 /* Verify rf_states exposed on CTRL interface */
2924 var charstring expect_net_rf_states := "";
2925 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
2926 var charstring expect_bts_rf_states := int2str(i) & ",0,";
2927 if (i < NUM_BTS) {
2928 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
2929 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
2930 } else {
2931 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
2932 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
2933 }
2934 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
2935 expect_bts_rf_states := expect_bts_rf_states & "on,";
2936 if (i < nr_bts) {
2937 /* For BTS where RSL is connected, the RSL state will be "up" */
2938 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
2939 } else {
2940 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
2941 }
2942
2943 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
2944 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
2945 }
2946 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
2947
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002948 f_shutdown_helper();
2949}
2950
2951/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
2952private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
2953 f_tc_stat_num_bts_connected_msc_connhdlr(1);
2954}
2955testcase TC_stat_num_bts_connected_1() runs on test_CT {
2956 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
2957}
2958
2959/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
2960private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
2961 f_tc_stat_num_bts_connected_msc_connhdlr(2);
2962}
2963testcase TC_stat_num_bts_connected_2() runs on test_CT {
2964 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
2965}
2966
2967/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
2968private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
2969 f_tc_stat_num_bts_connected_msc_connhdlr(3);
2970}
2971testcase TC_stat_num_bts_connected_3() runs on test_CT {
2972 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
2973}
2974
Harald Welte4003d112017-12-09 22:35:39 +01002975testcase TC_ctrl() runs on test_CT {
2976 var charstring ctrl_resp;
2977
Harald Welte89d42e82017-12-17 16:42:41 +01002978 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002979
2980 /* all below values must match the osmo-bsc.cfg config file used */
2981
Harald Welte6a129692018-03-17 17:30:14 +01002982 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2983 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002984 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002985
2986 var integer bts_nr := 0;
2987 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2988 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2989 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2990 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2991 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2992 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2993 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2994
2995 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2996 f_sleep(2.0);
2997 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2998 setverdict(fail, "oml-uptime not incrementing as expected");
2999 }
3000 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3001
3002 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3003
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003004 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003005}
3006
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003007/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3008 "location-state" over the SCCPlite IPA conn */
3009testcase TC_ctrl_location() runs on test_CT {
3010 var MSC_ConnHdlr vc_conn;
3011 var integer bts_nr := 0;
3012
3013 f_init(1, true);
3014 f_sleep(1.0);
3015
3016 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3017 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3018 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3019
3020 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3021 f_sleep(2.0);
3022
3023 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3024 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3025 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3026
3027 /* should match the one from config */
3028 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3029
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003030 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003031}
3032
Harald Welte6f521d82017-12-11 19:52:02 +01003033
3034/***********************************************************************
3035 * Paging Testing
3036 ***********************************************************************/
3037
3038type record Cell_Identity {
3039 GsmMcc mcc,
3040 GsmMnc mnc,
3041 GsmLac lac,
3042 GsmCellId ci
3043};
Harald Welte24135bd2018-03-17 19:27:53 +01003044private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003045private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003046
Harald Welte5d1a2202017-12-13 19:51:29 +01003047type set of integer BtsIdList;
3048
3049private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3050 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3051 if (bts_id == bts_ids[j]) {
3052 return true;
3053 }
3054 }
3055 return false;
3056}
Harald Welte6f521d82017-12-11 19:52:02 +01003057
3058/* core paging test helper function; used by most paging test cases */
3059private function f_pageing_helper(hexstring imsi,
3060 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003061 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003062 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003063 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003064{
3065 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003066 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003067 var RSL_Message rx_rsl;
3068 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003069 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003070
3071 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003072
3073 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003074 for (i := 0; i < NUM_BTS; i := i + 1) {
3075 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003076 }
Harald Welte6f521d82017-12-11 19:52:02 +01003077
3078 if (isvalue(rsl_chneed)) {
3079 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3080 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3081 } else {
3082 bssmap_chneed := omit;
3083 }
3084
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003085 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3086 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003087
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003088 if (not istemplatekind(tmsi, "omit")) {
3089 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003090 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003091 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003092 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003093
Harald Welte5d1a2202017-12-13 19:51:29 +01003094 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003095 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003096 /* check channel type, paging group */
3097 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3098 setverdict(fail, "Paging for wrong paging group");
3099 }
3100 if (ispresent(rsl_chneed) and
3101 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3102 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3103 }
Harald Welte6f521d82017-12-11 19:52:02 +01003104 }
Harald Welte2fccd982018-01-31 15:48:19 +01003105 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003106 /* do a quick check on all not-included BTSs if they received paging */
3107 for (i := 0; i < NUM_BTS; i := i + 1) {
3108 timer T := 0.1;
3109 if (f_bts_in_list(i, bts_ids)) {
3110 continue;
3111 }
3112 T.start;
3113 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003114 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003115 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3116 }
3117 [] IPA_RSL[i].receive { repeat; }
3118 [] T.timeout { }
3119 }
Harald Welte6f521d82017-12-11 19:52:02 +01003120 }
3121
3122 setverdict(pass);
3123}
3124
Harald Welte5d1a2202017-12-13 19:51:29 +01003125const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003126const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003127const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3128const BtsIdList c_BtsId_LAC2 := { 2 };
3129
Harald Welte6f521d82017-12-11 19:52:02 +01003130/* PAGING by IMSI + TMSI */
3131testcase TC_paging_imsi_nochan() runs on test_CT {
3132 var BSSMAP_FIELD_CellIdentificationList cid_list;
3133 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003134 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003135 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003136}
3137
3138/* PAGING by IMSI + TMSI */
3139testcase TC_paging_tmsi_nochan() runs on test_CT {
3140 var BSSMAP_FIELD_CellIdentificationList cid_list;
3141 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003142 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003143 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003144}
3145
3146/* Paging with different "channel needed' values */
3147testcase TC_paging_tmsi_any() runs on test_CT {
3148 var BSSMAP_FIELD_CellIdentificationList cid_list;
3149 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003150 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003151 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003152}
3153testcase TC_paging_tmsi_sdcch() runs on test_CT {
3154 var BSSMAP_FIELD_CellIdentificationList cid_list;
3155 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003156 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003157 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003158}
3159testcase TC_paging_tmsi_tch_f() runs on test_CT {
3160 var BSSMAP_FIELD_CellIdentificationList cid_list;
3161 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003162 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003163 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003164}
3165testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3166 var BSSMAP_FIELD_CellIdentificationList cid_list;
3167 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003168 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003169 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003170}
3171
3172/* Paging by CGI */
3173testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3174 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3175 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003176 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003177 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003178}
3179
3180/* Paging by LAC+CI */
3181testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3182 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3183 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003184 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003185 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003186}
3187
3188/* Paging by CI */
3189testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3190 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3191 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003192 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003193 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003194}
3195
3196/* Paging by LAI */
3197testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3198 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3199 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003200 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003201 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003202}
3203
3204/* Paging by LAC */
3205testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3206 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3207 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003208 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003209 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003210}
3211
3212/* Paging by "all in BSS" */
3213testcase TC_paging_imsi_nochan_all() runs on test_CT {
3214 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3215 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003216 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003217 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003218}
3219
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003220/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003221testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3222 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3223 cid_list := { cIl_PLMN_LAC_RNC := { ts_BSSMAP_CI_PLMN_LAC_RNC(cid.mcc, cid.mnc, cid.lac, 12) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003224 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003225 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003226}
Harald Welte6f521d82017-12-11 19:52:02 +01003227
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003228/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003229testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3230 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3231 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003232 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003233 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003234}
3235
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003236/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003237testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3238 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3239 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003240 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003241 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003242}
3243
Harald Welte6f521d82017-12-11 19:52:02 +01003244/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003245testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3246 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3247 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3248 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003249 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003250}
3251
3252/* Paging on empty list: Verify none of them page */
3253testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3254 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3255 cid_list := { cIl_LAC := { } };
3256 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003257 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003258}
3259
Stefan Sperling049a86e2018-03-20 15:51:00 +01003260/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3261testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3262 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3263 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3264 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3265 f_shutdown_helper();
3266}
3267
Harald Welte6f521d82017-12-11 19:52:02 +01003268/* Verify paging retransmission interval + count */
3269/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003270/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003271
Harald Weltee65d40e2017-12-13 00:09:06 +01003272/* Verify PCH load */
3273testcase TC_paging_imsi_load() runs on test_CT {
3274 var BSSMAP_FIELD_CellIdentificationList cid_list;
3275 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003276 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003277 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003278 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003279
3280 /* tell BSC there is no paging space anymore */
3281 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003282 f_sleep(0.2);
3283 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003284
3285 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3286 * there would be 8 retransmissions during 4 seconds */
3287 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003288 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003289 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003290 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003291 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003292 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003293 }
Harald Welte2caa1062018-03-17 18:19:05 +01003294 [] T_retrans.timeout {
3295 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3296 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3297 T_retrans.start;
3298 repeat;
3299 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003300 [] T.timeout {
3301 setverdict(pass);
3302 }
3303 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003304
3305 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003306}
3307
Harald Welte235ebf12017-12-15 14:18:16 +01003308/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003309testcase TC_paging_counter() runs on test_CT {
3310 var BSSMAP_FIELD_CellIdentificationList cid_list;
3311 timer T := 4.0;
3312 var integer i;
3313 var integer paging_attempted_bsc;
3314 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003315 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003316 var integer paging_expired_bts[NUM_BTS];
3317 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3318
3319 f_init();
3320
3321 /* read counters before paging */
3322 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003323 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3324 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3325 }
Harald Welte1ff69992017-12-14 12:31:17 +01003326 for (i := 0; i < NUM_BTS; i := i+1) {
3327 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3328 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3329 }
3330
3331 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3332
3333 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3334 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3335 for (i := 0; i < NUM_BTS; i := i+1) {
3336 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3337 paging_attempted_bts[i]+1);
3338 }
3339
3340 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3341 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003342 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3343 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3344 }
Harald Welte1ff69992017-12-14 12:31:17 +01003345 for (i := 0; i < NUM_BTS; i := i+1) {
3346 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3347 paging_expired_bts[i]+1);
3348 }
Harald Welte1ff69992017-12-14 12:31:17 +01003349
Philipp Maier282ca4b2018-02-27 17:17:00 +01003350 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003351}
3352
3353
Harald Welte10985002017-12-12 09:29:15 +01003354/* Verify paging stops after A-RESET */
3355testcase TC_paging_imsi_a_reset() runs on test_CT {
3356 var BSSMAP_FIELD_CellIdentificationList cid_list;
3357 timer T := 3.0;
3358 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003359 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003360
3361 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003362 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 +01003363 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003364 [] 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 +01003365 [] BSSAP.receive { repeat; }
3366 }
3367
Daniel Willmanncbef3982018-07-30 09:22:40 +02003368 /* Wait to avoid a possible race condition if a paging message is
3369 * received right before the reset ACK. */
3370 f_sleep(0.2);
3371
Harald Welte10985002017-12-12 09:29:15 +01003372 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003373 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3374 IPA_RSL[i].clear;
3375 }
Harald Welte10985002017-12-12 09:29:15 +01003376
3377 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3378 T.start;
3379 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003380 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003381 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003382 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003383 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003384 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003385 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003386 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003387 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003388 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003389 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003390 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003391 }
Harald Welte10985002017-12-12 09:29:15 +01003392 [] T.timeout {
3393 setverdict(pass);
3394 }
3395 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003396
3397 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003398}
Harald Welteae026692017-12-09 01:03:01 +01003399
Philipp Maierf45824a2019-08-14 14:44:10 +02003400/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3401 * paging response we can not know which MSC is in charge, so we will blindly
3402 * pick the first configured MSC. This behavior is required in order to make
3403 * MT-CSFB calls working because in those cases the BSC can not know that the
3404 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3405 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003406 */
3407testcase TC_paging_resp_unsol() runs on test_CT {
3408
3409 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003410 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003411
3412 var BSSAP_N_CONNECT_ind rx_c_ind;
3413 var DchanTuple dt;
3414 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003415 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003416
3417 /* Send CHAN RQD and wait for allocation; acknowledge it */
3418 dt.rsl_chan_nr := f_chreq_act_ack();
3419
3420 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3421 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3422
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003423
Philipp Maierf45824a2019-08-14 14:44:10 +02003424 /* Expevct a CR with a matching Paging response on the A-Interface */
3425 T.start;
3426 alt {
3427 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3428 setverdict(pass);
3429 }
3430 [] BSSAP.receive {
3431 setverdict(fail, "Received unexpected message on A-Interface!");
3432 }
3433 [] T.timeout {
3434 setverdict(fail, "Received nothing on A-Interface!");
3435 }
3436 }
3437
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003438 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003439}
3440
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003441/* Test RSL link drop causes counter increment */
3442testcase TC_rsl_drop_counter() runs on test_CT {
3443 var integer rsl_fail;
3444
Harald Welte89d42e82017-12-17 16:42:41 +01003445 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003446
3447 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3448
3449 bts[0].rsl.vc_IPA.stop;
3450
3451 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3452
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003453 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003454}
3455
3456/* TODO: Test OML link drop causes counter increment */
3457
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003458/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3459function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3460 timer T := 10.0;
3461
3462 bts[0].rsl.id := "IPA-0-RSL";
3463 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3464 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3465 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003466 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003467
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003468 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003469
3470 f_init_mgcp("VirtMSC");
3471
3472 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3473 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3474 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3475 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3476
3477 /* wait for IPA OML link to connect and then disconnect */
3478 T.start;
3479 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003480 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003481 T.stop;
3482 return true;
3483 }
3484 [] IPA_RSL[0].receive { repeat }
3485 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003486 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003487 }
3488 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003489 return false;
3490}
3491
3492/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3493testcase TC_rsl_unknown_unit_id() runs on test_CT {
3494 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3495 setverdict(pass);
3496 } else {
3497 setverdict(fail, "Timeout RSL waiting for connection to close");
3498 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003499 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003500}
3501
3502
3503/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3504testcase TC_oml_unknown_unit_id() runs on test_CT {
3505 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3506 setverdict(pass);
3507 } else {
3508 setverdict(fail, "Timeout OML waiting for connection to close");
3509 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003510 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003511}
3512
3513
Harald Weltec1a2fff2017-12-17 11:06:19 +01003514/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003515 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003516 ***********************************************************************/
3517
Harald Welte6811d102019-04-14 22:23:14 +02003518import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003519import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003520import from RSL_Emulation all;
3521import from MSC_ConnectionHandler all;
3522
3523type function void_fn(charstring id) runs on MSC_ConnHdlr;
3524
Harald Welte336820c2018-05-31 20:34:52 +02003525/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003526private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3527 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003528 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003529 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003530 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003531 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003532 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3533 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3534 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003535 if (isvalue(bts[2])) {
3536 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3537 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3538 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003539 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003540 if (mp_enable_lcs_tests) {
3541 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3542 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3543 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003544 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003545 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003546 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003547}
3548
Neels Hofmeyrda436782021-07-20 22:09:06 +02003549function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003550runs on test_CT return MSC_ConnHdlr {
3551 var charstring id := testcasename();
3552 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003553 var integer bssap_idx := 0;
3554 if (isvalue(pars)) {
3555 bssap_idx := valueof(pars).mscpool.bssap_idx;
3556 }
Harald Welte336820c2018-05-31 20:34:52 +02003557 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003558 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003559 return vc_conn;
3560}
3561
3562function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3563runs on test_CT return MSC_ConnHdlr {
3564 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003565 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003566 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003567 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003568 return vc_conn;
3569}
3570
Neels Hofmeyrda436782021-07-20 22:09:06 +02003571function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3572runs on test_CT return MSC_ConnHdlr {
3573 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3574}
3575
Harald Weltea0630032018-03-20 21:09:55 +01003576/* first function inside ConnHdlr component; sets g_pars + starts function */
3577private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3578runs on MSC_ConnHdlr {
3579 if (isvalue(pars)) {
3580 g_pars := valueof(pars);
3581 }
3582 fn.apply(id);
3583}
3584
Oliver Smith26a3db72021-07-09 13:51:29 +02003585private function f_vty_encryption_a5(charstring options) runs on test_CT {
3586 f_vty_transceive(BSCVTY, "configure terminal");
3587 f_vty_transceive(BSCVTY, "network");
3588 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3589 f_vty_transceive(BSCVTY, "exit");
3590 f_vty_transceive(BSCVTY, "exit");
3591}
3592
3593private function f_vty_encryption_a5_reset() runs on test_CT {
3594 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3595 f_vty_encryption_a5("0 1 3");
3596}
3597
Harald Welte3c86ea02018-05-10 22:28:05 +02003598/* Establish signalling channel (non-assignment case) followed by cipher mode */
3599private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003600 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3601 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003602 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003603 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3604 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3605 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3606 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003607
Philipp Maier23000732018-05-18 11:25:37 +02003608 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003609}
3610testcase TC_ciph_mode_a5_0() runs on test_CT {
3611 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003612 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003613 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3614
3615 f_init(1, true);
3616 f_sleep(1.0);
3617 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3618 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003619 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003620}
3621testcase TC_ciph_mode_a5_1() runs on test_CT {
3622 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003623 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003624 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3625
3626 f_init(1, true);
3627 f_sleep(1.0);
3628 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3629 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003630 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003631}
Oliver Smith50b98122021-07-09 15:00:28 +02003632/* OS#4975: verify that A5/2 is preferred over A5/0 */
3633testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3634 var MSC_ConnHdlr vc_conn;
3635 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3636
3637 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3638 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3639
3640 f_init(1, true);
3641 f_vty_encryption_a5("0 1 2 3");
3642 f_sleep(1.0);
3643 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3644 vc_conn.done;
3645 f_vty_encryption_a5_reset();
3646 f_shutdown_helper();
3647}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003648/* OS#4975: verify that A5/1 is preferred over A5/2 */
3649testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3650 var MSC_ConnHdlr vc_conn;
3651 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3652
3653 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3654 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3655
3656 f_init(1, true);
3657 f_vty_encryption_a5("1 2");
3658 f_sleep(1.0);
3659 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3660 vc_conn.done;
3661 f_vty_encryption_a5_reset();
3662 f_shutdown_helper();
3663}
Harald Welte3c86ea02018-05-10 22:28:05 +02003664testcase TC_ciph_mode_a5_3() runs on test_CT {
3665 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003666 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003667 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3668
3669 f_init(1, true);
3670 f_sleep(1.0);
3671 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3672 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003673 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003674}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003675/* Establish a Signalling channel with A5/4 encryption. */
3676testcase TC_ciph_mode_a5_4() runs on test_CT {
3677 var MSC_ConnHdlr vc_conn;
3678 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3679 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003680
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003681 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003682 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003683 f_sleep(1.0);
3684 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3685 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003686 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003687 f_shutdown_helper();
3688}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003689/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3690private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3691 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3692 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3693 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3694 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3695
3696 f_establish_fully(ass_cmd, exp_compl);
3697}
3698testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3699 var MSC_ConnHdlr vc_conn;
3700 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3701
3702 f_init(1, true);
3703 f_sleep(1.0);
3704 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3705 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003706 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003707}
3708
Harald Welte3c86ea02018-05-10 22:28:05 +02003709
3710/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003711private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003712 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3713 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003714
Harald Welte552620d2017-12-16 23:21:36 +01003715 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3716 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003717
Harald Weltea0630032018-03-20 21:09:55 +01003718 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003719}
Harald Welte552620d2017-12-16 23:21:36 +01003720testcase TC_assignment_fr_a5_0() runs on test_CT {
3721 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003722 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003723 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003724
Harald Welte89d42e82017-12-17 16:42:41 +01003725 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003726 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003727 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003728 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003729 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003730}
Harald Welte552620d2017-12-16 23:21:36 +01003731testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003732 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003733 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003734 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003735
Harald Welte89d42e82017-12-17 16:42:41 +01003736 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003737 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003738 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3739 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003740 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003741}
3742testcase TC_assignment_fr_a5_3() runs on test_CT {
3743 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003744 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003745 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003746
Harald Welte651fcdc2018-05-10 20:23:16 +02003747 f_init(1, true);
3748 f_sleep(1.0);
3749 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003750 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003751 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003752}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003753/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3754testcase TC_assignment_fr_a5_4() runs on test_CT {
3755 var MSC_ConnHdlr vc_conn;
3756 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3757 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3758
3759 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003760 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003761 f_sleep(1.0);
3762 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3763 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003764 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003765 f_shutdown_helper();
3766}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003767
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003768/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3769testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3770 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3771 var MSC_ConnHdlr vc_conn;
3772
3773 f_init(1, true);
3774 f_sleep(1.0);
3775
3776 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3777 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3778 vc_conn.done;
3779 f_shutdown_helper();
3780}
3781
Harald Welte552620d2017-12-16 23:21:36 +01003782/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3783private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003784 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003785 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003786 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003787
3788 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003789 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3790
Harald Weltea0630032018-03-20 21:09:55 +01003791 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003792}
Harald Welte552620d2017-12-16 23:21:36 +01003793testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3794 var MSC_ConnHdlr vc_conn;
3795
Harald Welte89d42e82017-12-17 16:42:41 +01003796 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003797 f_sleep(1.0);
3798
Harald Welte8863fa12018-05-10 20:15:27 +02003799 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003800 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003801 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003802}
3803
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003804private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3805 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3806 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003807
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003808 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3809 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3810
3811 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3812
3813 var BSSMAP_FIELD_CodecType codecType;
3814 timer T := 10.0;
3815
3816 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3817 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3818
3819 f_create_chan_and_exp();
3820 /* we should now have a COMPL_L3 at the MSC */
3821
3822 var template PDU_BSSAP exp_l3_compl;
3823 exp_l3_compl := tr_BSSMAP_ComplL3()
3824 if (g_pars.aoip == false) {
3825 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3826 } else {
3827 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3828 }
3829 T.start;
3830 alt {
3831 [] BSSAP.receive(exp_l3_compl);
3832 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3833 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3834 }
3835 [] T.timeout {
3836 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3837 }
3838 }
3839
3840 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003841 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003842}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003843testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3844 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003845 var MSC_ConnHdlr vc_conn;
3846
Harald Welte89d42e82017-12-17 16:42:41 +01003847 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003848 f_sleep(1.0);
3849
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003850 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003851 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003852 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003853 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003854}
3855
3856
Harald Welte4532e0a2017-12-23 02:05:44 +01003857private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003858 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003859 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003860 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003861 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003862
3863 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003864 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003865
3866 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003867 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3868 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003869 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3870 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3871 };
3872 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003873}
3874
3875testcase TC_assignment_sign() runs on test_CT {
3876 var MSC_ConnHdlr vc_conn;
3877
3878 f_init(1, true);
3879 f_sleep(1.0);
3880
Harald Welte8863fa12018-05-10 20:15:27 +02003881 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003882 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003883 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003884}
3885
Harald Welte60aa5762018-03-21 19:33:13 +01003886/***********************************************************************
3887 * Codec (list) testing
3888 ***********************************************************************/
3889
3890/* check if the given rsl_mode is compatible with the a_elem */
3891private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3892return boolean {
3893 select (a_elem.codecType) {
3894 case (GSM_FR) {
3895 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3896 return true;
3897 }
3898 }
3899 case (GSM_HR) {
3900 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3901 return true;
3902 }
3903 }
3904 case (GSM_EFR) {
3905 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3906 return true;
3907 }
3908 }
3909 case (FR_AMR) {
3910 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3911 return true;
3912 }
3913 }
3914 case (HR_AMR) {
3915 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3916 return true;
3917 }
3918 }
3919 case else { }
3920 }
3921 return false;
3922}
3923
3924/* check if the given rsl_mode is compatible with the a_list */
3925private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3926return boolean {
3927 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3928 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3929 return true;
3930 }
3931 }
3932 return false;
3933}
3934
3935/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003936function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003937return BSSMAP_IE_ChannelType {
3938 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3939 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3940 select (a_elem.codecType) {
3941 case (GSM_FR) {
3942 ret.channelRateAndType := ChRate_TCHF;
3943 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3944 }
3945 case (GSM_HR) {
3946 ret.channelRateAndType := ChRate_TCHH;
3947 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3948 }
3949 case (GSM_EFR) {
3950 ret.channelRateAndType := ChRate_TCHF;
3951 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3952 }
3953 case (FR_AMR) {
3954 ret.channelRateAndType := ChRate_TCHF;
3955 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3956 }
3957 case (HR_AMR) {
3958 ret.channelRateAndType := ChRate_TCHH;
3959 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3960 }
3961 case else {
3962 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003963 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003964 }
3965 }
3966 return ret;
3967}
3968
Harald Weltea63b9102018-03-22 20:36:16 +01003969private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3970return template RSL_IE_Body {
3971 var template RSL_IE_Body mode_ie := {
3972 chan_mode := {
3973 len := ?,
3974 reserved := ?,
3975 dtx_d := ?,
3976 dtx_u := ?,
3977 spd_ind := RSL_SPDI_SPEECH,
3978 ch_rate_type := -,
3979 coding_alg_rate := -
3980 }
3981 }
3982
3983 select (a_elem.codecType) {
3984 case (GSM_FR) {
3985 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3986 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3987 }
3988 case (GSM_HR) {
3989 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3990 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3991 }
3992 case (GSM_EFR) {
3993 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3994 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3995 }
3996 case (FR_AMR) {
3997 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3998 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3999 }
4000 case (HR_AMR) {
4001 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4002 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4003 }
4004 }
4005 return mode_ie;
4006}
4007
Harald Welte60aa5762018-03-21 19:33:13 +01004008type record CodecListTest {
4009 BSSMAP_IE_SpeechCodecList codec_list,
4010 charstring id
4011}
4012type record of CodecListTest CodecListTests
4013
4014private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004015 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
4016 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01004017
4018 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004019 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004020 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4021 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4022 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004023 if (isvalue(g_pars.expect_mr_s0_s7)) {
4024 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4025 g_pars.expect_mr_s0_s7;
4026 }
Harald Welte79f3f542018-05-25 20:02:37 +02004027 }
Harald Welte60aa5762018-03-21 19:33:13 +01004028 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4029 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004030 log("expecting ASS COMPL like this: ", exp_compl);
4031
4032 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004033
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004034 if (not g_pars.expect_channel_mode_modify) {
4035 /* Verify that the RSL-side activation actually matches our expectations */
4036 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004037
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004038 var RSL_IE_Body mode_ie;
4039 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4040 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004041 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004042 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004043 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4044 if (not match(mode_ie, t_mode_ie)) {
4045 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4046 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004047 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004048
4049 var RSL_IE_Body mr_conf;
4050 if (g_pars.expect_mr_conf_ie != omit) {
4051 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4052 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4053 mtc.stop;
4054 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004055 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004056
4057 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4058 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4059 g_pars.expect_mr_conf_ie);
4060 }
4061 } else {
4062 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4063 log("found RSL MR CONFIG IE: ", mr_conf);
4064 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4065 mtc.stop;
4066 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004067 }
4068 }
Harald Welte60aa5762018-03-21 19:33:13 +01004069}
4070
Philipp Maierd0e64b02019-03-13 14:15:23 +01004071private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4072
4073 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4074 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4075
4076 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004077 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004078 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4079 }
4080 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4081 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4082 log("expecting ASS FAIL like this: ", exp_fail);
4083
4084 f_establish_fully(ass_cmd, exp_fail);
4085}
4086
Harald Welte60aa5762018-03-21 19:33:13 +01004087testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004088 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004089 var MSC_ConnHdlr vc_conn;
4090
4091 f_init(1, true);
4092 f_sleep(1.0);
4093
4094 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004095 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004096 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004097 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004098}
4099
4100testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004101 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004102 var MSC_ConnHdlr vc_conn;
4103
4104 f_init(1, true);
4105 f_sleep(1.0);
4106
4107 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004108 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004109 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004110 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004111}
4112
4113testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004114 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004115 var MSC_ConnHdlr vc_conn;
4116
4117 f_init(1, true);
4118 f_sleep(1.0);
4119
4120 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004121 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004122 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004123 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004124}
4125
Philipp Maierd0e64b02019-03-13 14:15:23 +01004126/* Allow 5,90k only (current default config) */
4127private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004128 f_vty_cfg_msc(BSCVTY, 0, {
4129 "amr-config 12_2k forbidden",
4130 "amr-config 10_2k forbidden",
4131 "amr-config 7_95k forbidden",
4132 "amr-config 7_40k forbidden",
4133 "amr-config 6_70k forbidden",
4134 "amr-config 5_90k allowed",
4135 "amr-config 5_15k forbidden",
4136 "amr-config 4_75k forbidden"
4137 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004138}
4139
4140/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4141 * ("Config-NB-Code = 1") */
4142private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004143 f_vty_cfg_msc(BSCVTY, 0, {
4144 "amr-config 12_2k allowed",
4145 "amr-config 10_2k forbidden",
4146 "amr-config 7_95k forbidden",
4147 "amr-config 7_40k allowed",
4148 "amr-config 6_70k forbidden",
4149 "amr-config 5_90k allowed",
4150 "amr-config 5_15k forbidden",
4151 "amr-config 4_75k allowed"
4152 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004153}
4154
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004155private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4156 var charstring tch;
4157 if (fr) {
4158 tch := "tch-f";
4159 } else {
4160 tch := "tch-h";
4161 }
4162 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4163}
4164
4165/* Set the AMR start-mode for this TCH back to the default configuration. */
4166private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4167 f_vty_amr_start_mode_set(fr, "auto");
4168}
4169
Harald Welte60aa5762018-03-21 19:33:13 +01004170testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004171 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004172 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004173
4174 /* Note: This setups the codec configuration. The parameter payload in
4175 * mr_conf must be consistant with the parameter codecElements in pars
4176 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004177 var RSL_IE_Body mr_conf := {
4178 other := {
4179 len := 2,
4180 payload := '2804'O
4181 }
4182 };
Harald Welte60aa5762018-03-21 19:33:13 +01004183
Philipp Maier7695a0d2018-09-27 17:52:14 +02004184 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004185 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004186 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4187 pars.expect_mr_conf_ie := mr_conf;
4188
Harald Welte60aa5762018-03-21 19:33:13 +01004189 f_init(1, true);
4190 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004191 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004192
Harald Welte8863fa12018-05-10 20:15:27 +02004193 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004194 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004195
4196 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004197 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004198}
4199
4200testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004201 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004202 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004203
4204 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004205 var RSL_IE_Body mr_conf := {
4206 other := {
4207 len := 2,
4208 payload := '2804'O
4209 }
4210 };
Harald Welte60aa5762018-03-21 19:33:13 +01004211
Philipp Maier7695a0d2018-09-27 17:52:14 +02004212 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004213 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004214 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4215 pars.expect_mr_conf_ie := mr_conf;
4216
Harald Welte60aa5762018-03-21 19:33:13 +01004217 f_init(1, true);
4218 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004219 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004220
Harald Welte8863fa12018-05-10 20:15:27 +02004221 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004222 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004223
4224 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004225 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004226}
4227
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004228/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4229testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4230 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4231 var MSC_ConnHdlr vc_conn;
4232
4233 f_init(1, true);
4234 f_sleep(1.0);
4235
4236 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4237 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4238 * expecting a Channel Mode Modify if the channel type is compatible. */
4239 f_disable_all_sdcch();
4240 f_disable_all_tch_h();
4241
4242 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4243 pars.expect_channel_mode_modify := true;
4244 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4245 vc_conn.done;
4246
4247 f_enable_all_sdcch();
4248 f_enable_all_tch();
4249 f_shutdown_helper();
4250}
4251
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004252/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4253testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4254 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4255 var MSC_ConnHdlr vc_conn;
4256
4257 var RSL_IE_Body mr_conf := {
4258 other := {
4259 len := 2,
4260 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4261 }
4262 };
4263
4264 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4265 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4266 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4267 pars.expect_mr_conf_ie := mr_conf;
4268
4269 f_init(1, true);
4270 f_sleep(1.0);
4271
4272 /* First set nonzero start mode bits */
4273 f_vty_amr_start_mode_set(true, "4");
4274 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4275 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4276 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4277 f_vty_amr_start_mode_set(true, "auto");
4278
4279 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4280 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004281
4282 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4283 f_vty_amr_start_mode_set(true, "1");
4284 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004285 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004286}
4287
Neels Hofmeyr21863562020-11-26 00:34:33 +00004288function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4289 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004290runs on test_CT {
4291
4292 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4293 var MSC_ConnHdlr vc_conn;
4294
4295 /* See note above */
4296 var RSL_IE_Body mr_conf := {
4297 other := {
4298 len := lengthof(mrconf),
4299 payload := mrconf
4300 }
4301 };
4302
4303 if (fr) {
4304 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4305 } else {
4306 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4307 }
4308 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4309 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4310 pars.expect_mr_conf_ie := mr_conf;
4311 pars.expect_mr_s0_s7 := exp_s8_s0;
4312
4313 f_init(1, true);
4314 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004315 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004316 f_sleep(1.0);
4317
4318 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4319 vc_conn.done;
4320 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004321 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004322}
4323
4324function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4325runs on test_CT {
4326
4327 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4328 var MSC_ConnHdlr vc_conn;
4329
4330 if (fr) {
4331 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4332 } else {
4333 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4334 }
4335 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4336 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4337
4338 f_init(1, true);
4339 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004340 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004341 f_sleep(1.0);
4342
4343 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4344 vc_conn.done;
4345 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004346 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004347}
4348
4349
4350/* Set S1, we expect an AMR multirate configuration IE with all four rates
4351 * set. */
4352testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004353 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004354 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004355}
4356
4357/* Set S1, we expect an AMR multirate configuration IE with the lower three
4358 * rates set. */
4359testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004360 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004361 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004362}
4363
4364/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4365 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4366testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004367 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004368 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004369}
4370
4371/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4372 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4373testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004374 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004375 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004376}
4377
4378/* The following block of tests selects more and more rates until all four
4379 * possible rates are in the active set (full rate) */
4380testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004381 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004382 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004383}
4384
4385testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004386 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004387 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004388}
4389
4390testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004391 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004392 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004393}
4394
4395testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004396 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004397 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004398}
4399
4400/* The following block of tests selects more and more rates until all three
4401 * possible rates are in the active set (half rate) */
4402testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004403 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004404 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004405}
4406
4407testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004408 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004409 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004410}
4411
4412testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004413 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004414 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004415}
4416
4417/* The following block tests what happens when the MSC does offer rate
4418 * configurations that are not supported by the BSC. Normally such situations
4419 * should not happen because the MSC gets informed by the BSC in advance via
4420 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4421 * to offer rates that are not applicable anyway. */
4422
4423testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004424 /* Try to include 12,2k in into the active set even though the channel
4425 * is half rate only. The BSC is expected to remove the 12,0k */
4426 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004427 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004428}
4429
4430testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004431 /* See what happens when all rates are selected at once. Since then
4432 * Also S1 is selected, this setting will be prefered and we should
4433 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4434 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004435 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004436}
4437
4438testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004439 /* Same as above, but with S1 missing, the MSC is then expected to
4440 * select the currently supported rates, which are also 12.2k, 7,40k,
4441 * 5,90k, and 4,75k, into the active set. */
4442 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004443 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004444}
4445
4446testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004447 /* Try to select no rates at all */
4448 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004449 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004450}
4451
4452testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004453 /* Try to select only unsupported rates */
4454 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004455 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004456}
4457
4458testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004459 /* Try to select 12,2k for half rate */
4460 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004461 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004462}
4463
Neels Hofmeyr21863562020-11-26 00:34:33 +00004464testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4465 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4466 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004467 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004468}
4469
4470testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4471 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4472 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004473 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004474}
4475
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004476testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004477 /* "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 +00004478 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4479 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004480 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004481}
4482
4483testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004484 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4485 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004486 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004487 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004488}
4489
Philipp Maierac09bfc2019-01-08 13:41:39 +01004490private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004491 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4492 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4493 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4494 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004495}
4496
4497private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004498 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4499 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004500}
4501
4502private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004503 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4504 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4505 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4506 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4507 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4508 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004509}
4510
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004511private function f_disable_all_sdcch() runs on test_CT {
4512 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4513 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4514 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4515 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4516}
4517
4518private function f_enable_all_sdcch() runs on test_CT {
4519 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4520 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4521 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4522 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4523}
4524
Philipp Maierac09bfc2019-01-08 13:41:39 +01004525/* Allow HR only */
4526private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4527 g_pars := f_gen_test_hdlr_pars();
4528 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4529 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4530 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4531 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4532 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4533 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4534 f_establish_fully(ass_cmd, exp_compl);
4535}
4536
4537/* Allow FR only */
4538private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4539 g_pars := f_gen_test_hdlr_pars();
4540 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4541 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4542 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4543 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4544 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4545 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4546 f_establish_fully(ass_cmd, exp_compl);
4547}
4548
4549/* Allow HR only (expect assignment failure) */
4550private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4551 g_pars := f_gen_test_hdlr_pars();
4552 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4553 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4554 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4555 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4556 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4557 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4558 f_establish_fully(ass_cmd, exp_fail);
4559}
4560
4561/* Allow FR only (expect assignment failure) */
4562private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4563 g_pars := f_gen_test_hdlr_pars();
4564 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4565 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4566 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4567 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4568 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4569 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4570 f_establish_fully(ass_cmd, exp_fail);
4571}
4572
4573/* Allow FR and HR, but prefer FR */
4574private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4575 g_pars := f_gen_test_hdlr_pars();
4576 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4577 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4578 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4579 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4580 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4581 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4582 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4583 f_establish_fully(ass_cmd, exp_compl);
4584}
4585
4586/* Allow FR and HR, but prefer HR */
4587private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4588 g_pars := f_gen_test_hdlr_pars();
4589 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4590 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4591 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4592 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4593 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4594 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4595 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4596 f_establish_fully(ass_cmd, exp_compl);
4597}
4598
4599/* Allow FR and HR, but prefer FR */
4600private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4601 g_pars := f_gen_test_hdlr_pars();
4602 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4603 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4604 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4605 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4606 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4607 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4608 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4609 f_establish_fully(ass_cmd, exp_compl);
4610}
4611
4612/* Allow FR and HR, but prefer HR */
4613private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4614 g_pars := f_gen_test_hdlr_pars();
4615 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4616 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4617 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4618 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4619 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4620 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4621 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4622 f_establish_fully(ass_cmd, exp_compl);
4623}
4624
4625/* Request a HR channel while all FR channels are exhausted, this is expected
4626 * to work without conflicts */
4627testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4628 var MSC_ConnHdlr vc_conn;
4629 f_init(1, true);
4630 f_sleep(1.0);
4631 f_enable_all_tch();
4632 f_disable_all_tch_f();
4633 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4634 vc_conn.done;
4635 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004636 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004637}
4638
4639/* Request a FR channel while all FR channels are exhausted, this is expected
4640 * to fail. */
4641testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4642 var MSC_ConnHdlr vc_conn;
4643 f_init(1, true);
4644 f_sleep(1.0);
4645 f_enable_all_tch();
4646 f_disable_all_tch_f();
4647 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4648 vc_conn.done;
4649 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004650 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004651}
4652
4653/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4654 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4655testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4656 var MSC_ConnHdlr vc_conn;
4657 f_init(1, true);
4658 f_sleep(1.0);
4659 f_enable_all_tch();
4660 f_disable_all_tch_f();
4661 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4662 vc_conn.done;
4663 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004664 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004665}
4666
4667/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4668 * are exhausted, this is expected to work without conflicts. */
4669testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4670 var MSC_ConnHdlr vc_conn;
4671 f_init(1, true);
4672 f_sleep(1.0);
4673 f_enable_all_tch();
4674 f_disable_all_tch_f();
4675 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4676 vc_conn.done;
4677 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004678 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004679}
4680
4681/* Request a FR channel while all HR channels are exhausted, this is expected
4682 * to work without conflicts */
4683testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4684 var MSC_ConnHdlr vc_conn;
4685 f_init(1, true);
4686 f_sleep(1.0);
4687 f_enable_all_tch();
4688 f_disable_all_tch_h();
4689 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4690 vc_conn.done;
4691 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004692 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004693}
4694
4695/* Request a HR channel while all HR channels are exhausted, this is expected
4696 * to fail. */
4697testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4698 var MSC_ConnHdlr vc_conn;
4699 f_init(1, true);
4700 f_sleep(1.0);
4701 f_enable_all_tch();
4702 f_disable_all_tch_h();
4703 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4704 vc_conn.done;
4705 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004706 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004707}
4708
4709/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4710 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4711testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4712 var MSC_ConnHdlr vc_conn;
4713 f_init(1, true);
4714 f_sleep(1.0);
4715 f_enable_all_tch();
4716 f_disable_all_tch_h();
4717 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4718 vc_conn.done;
4719 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004720 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004721}
4722
4723/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4724 * are exhausted, this is expected to work without conflicts. */
4725testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4726 var MSC_ConnHdlr vc_conn;
4727 f_init(1, true);
4728 f_sleep(1.0);
4729 f_enable_all_tch();
4730 f_disable_all_tch_h();
4731 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4732 vc_conn.done;
4733 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004734 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004735}
4736
4737/* Allow FR and HR, but prefer HR */
4738private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4739 g_pars := f_gen_test_hdlr_pars();
4740 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4741 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4742 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4743 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4744 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4745 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4746 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4747 f_establish_fully(ass_cmd, exp_compl);
4748}
4749
4750/* Allow FR and HR, but prefer FR */
4751private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4752 g_pars := f_gen_test_hdlr_pars();
4753 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4754 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4755 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4756 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4757 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4758 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4759 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4760 f_establish_fully(ass_cmd, exp_compl);
4761}
4762
4763/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4764 * HR, which is the prefered type, is selected. */
4765testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4766 var MSC_ConnHdlr vc_conn;
4767 f_init(1, true);
4768 f_sleep(1.0);
4769 f_enable_all_tch();
4770 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4771 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004772 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004773}
4774
4775/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4776 * FR, which is the prefered type, is selected. */
4777testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4778 var MSC_ConnHdlr vc_conn;
4779 f_init(1, true);
4780 f_sleep(1.0);
4781 f_enable_all_tch();
4782 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4783 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004784 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004785}
4786
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004787/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4788private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4789 g_pars := f_gen_test_hdlr_pars();
4790 g_pars.ra := '02'O; /* RA containing reason=LU */
4791
4792 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4793 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4794 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4795 var template uint3_t tsc := ?;
4796
4797 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4798 f_create_bssmap_exp(l3_enc);
4799 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4800 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4801
4802 /* we should now have a COMPL_L3 at the MSC */
4803 timer T := 10.0;
4804 T.start;
4805 alt {
4806 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4807 [] T.timeout {
4808 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4809 }
4810 }
4811}
4812testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4813 var MSC_ConnHdlr vc_conn;
4814 f_init(1, true);
4815 f_sleep(1.0);
4816 f_disable_all_sdcch();
4817 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4818 vc_conn.done;
4819 f_enable_all_sdcch();
4820 f_shutdown_helper();
4821}
4822
4823/* Request a signalling channel with all SDCCH exhausted, it is
4824 expected that no TCH will be selected for signalling and assigment will fail
4825 because it's dictated by VTY config */
4826testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4827 var RSL_Message rsl_unused, rsl_msg;
4828 var GsmRrMessage rr;
4829 f_init(1, false);
4830 f_sleep(1.0);
4831 f_vty_allow_tch_for_signalling(false, 0);
4832 f_disable_all_sdcch();
4833
4834 /* RA containing reason=LU */
4835 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4836 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4837 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4838 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4839 setverdict(fail, "Expected reject");
4840 }
4841
4842 f_vty_allow_tch_for_signalling(true, 0);
4843 f_enable_all_sdcch();
4844 f_shutdown_helper();
4845}
4846
4847/* Request a voice channel with all SDCCH exhausted, it is
4848 * expected that TCH channel will be allocated since the VTY option is only
4849 * aimed at signalling requests */
4850private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4851 g_pars := f_gen_test_hdlr_pars();
4852 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4853
4854 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4855 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4856 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4857 var template uint3_t tsc := ?;
4858
4859 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4860 f_create_bssmap_exp(l3_enc);
4861 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4862 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4863
4864 /* we should now have a COMPL_L3 at the MSC */
4865 timer T := 10.0;
4866 T.start;
4867 alt {
4868 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4869 [] T.timeout {
4870 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4871 }
4872 }
4873}
4874testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4875 var MSC_ConnHdlr vc_conn;
4876 f_init(1, true);
4877 f_sleep(1.0);
4878 f_vty_allow_tch_for_signalling(false, 0);
4879 f_disable_all_sdcch();
4880
4881 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4882 vc_conn.done;
4883
4884 f_vty_allow_tch_for_signalling(true, 0);
4885 f_enable_all_sdcch();
4886 f_shutdown_helper();
4887}
4888
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004889testcase TC_assignment_osmux() runs on test_CT {
4890 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4891 var MSC_ConnHdlr vc_conn;
4892
4893 /* See note above */
4894 var RSL_IE_Body mr_conf := {
4895 other := {
4896 len := 2,
4897 payload := '2804'O
4898 }
4899 };
4900
4901 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4902 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4903 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4904 pars.expect_mr_conf_ie := mr_conf;
4905 pars.use_osmux := true;
4906
4907 f_init(1, true, true);
4908 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004909 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004910
4911 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4912 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004913
4914 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004915 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004916}
4917
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004918/* test the procedure of the MSC requesting a Classmark Update:
4919 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4920 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004921private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004922 g_pars := f_gen_test_hdlr_pars();
4923
Harald Weltea0630032018-03-20 21:09:55 +01004924 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004925 /* we should now have a COMPL_L3 at the MSC */
4926 BSSAP.receive(tr_BSSMAP_ComplL3);
4927
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004928 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4929 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4930
Harald Welte898113b2018-01-31 18:32:21 +01004931 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4932 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4933 setverdict(pass);
4934}
4935testcase TC_classmark() runs on test_CT {
4936 var MSC_ConnHdlr vc_conn;
4937 f_init(1, true);
4938 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004939 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004940 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004941 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004942}
4943
Harald Welteeddf0e92020-06-21 19:42:15 +02004944/* Send a CommonID from the simulated MSC and verify that the information is used to
4945 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4946private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4947 g_pars := f_gen_test_hdlr_pars();
4948 f_MscConnHdlr_init_vty();
4949
4950 f_create_chan_and_exp();
4951 /* we should now have a COMPL_L3 at the MSC */
4952 BSSAP.receive(tr_BSSMAP_ComplL3);
4953
4954 /* Send CommonID */
4955 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4956
4957 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4958 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4959 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4960
4961 setverdict(pass);
4962}
4963testcase TC_common_id() runs on test_CT {
4964 var MSC_ConnHdlr vc_conn;
4965 f_init(1, true);
4966 f_sleep(1.0);
4967 vc_conn := f_start_handler(refers(f_tc_common_id));
4968 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004969 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004970}
4971
Harald Weltee3bd6582018-01-31 22:51:25 +01004972private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004973 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004974 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004975 /* we should now have a COMPL_L3 at the MSC */
4976 BSSAP.receive(tr_BSSMAP_ComplL3);
4977
Harald Weltee3bd6582018-01-31 22:51:25 +01004978 /* send the single message we want to send */
4979 f_rsl_send_l3(l3);
4980}
4981
4982private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4983 timer T := sec;
4984 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004985 T.start;
4986 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004987 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4988 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004989 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004990 }
4991 [] T.timeout {
4992 setverdict(pass);
4993 }
4994 }
4995}
4996
Harald Weltee3bd6582018-01-31 22:51:25 +01004997/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4998private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4999 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5000 f_bssap_expect_nothing();
5001}
Harald Welte898113b2018-01-31 18:32:21 +01005002testcase TC_unsol_ass_fail() runs on test_CT {
5003 var MSC_ConnHdlr vc_conn;
5004 f_init(1, true);
5005 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005006 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005007 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005008 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005009}
Harald Welte552620d2017-12-16 23:21:36 +01005010
Harald Welteea99a002018-01-31 20:46:43 +01005011
5012/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5013private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005014 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5015 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01005016}
5017testcase TC_unsol_ass_compl() runs on test_CT {
5018 var MSC_ConnHdlr vc_conn;
5019 f_init(1, true);
5020 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005021 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005022 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005023 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005024}
5025
5026
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005027/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5028private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005029 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5030 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005031}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005032testcase TC_unsol_ho_fail() runs on test_CT {
5033 var MSC_ConnHdlr vc_conn;
5034 f_init(1, true);
5035 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005036 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005037 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005038 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005039}
5040
5041
Harald Weltee3bd6582018-01-31 22:51:25 +01005042/* short message from MS should be ignored */
5043private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005044 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005045 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005046 /* we should now have a COMPL_L3 at the MSC */
5047 BSSAP.receive(tr_BSSMAP_ComplL3);
5048
5049 /* send short message */
5050 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5051 f_bssap_expect_nothing();
5052}
5053testcase TC_err_82_short_msg() runs on test_CT {
5054 var MSC_ConnHdlr vc_conn;
5055 f_init(1, true);
5056 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005057 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005058 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005059 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005060}
5061
5062
Harald Weltee9e02e42018-01-31 23:36:25 +01005063/* 24.008 8.4 Unknown message must trigger RR STATUS */
5064private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5065 f_est_single_l3(ts_RRM_UL_REL('00'O));
5066 timer T := 3.0
5067 alt {
5068 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5069 setverdict(pass);
5070 }
5071 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005072 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005073 }
5074}
5075testcase TC_err_84_unknown_msg() runs on test_CT {
5076 var MSC_ConnHdlr vc_conn;
5077 f_init(1, true);
5078 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005079 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005080 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005081 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005082}
5083
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005084/***********************************************************************
5085 * Handover
5086 ***********************************************************************/
5087
Harald Welte94e0c342018-04-07 11:33:23 +02005088/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5089private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5090runs on test_CT {
5091 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5092 " timeslot "&int2str(ts_nr)&" ";
5093 f_vty_transceive(BSCVTY, cmd & suffix);
5094}
5095
Harald Welte261af4b2018-02-12 21:20:39 +01005096/* 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 +07005097private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5098 uint8_t bts_nr, uint8_t trx_nr,
5099 in RslChannelNr chan_nr)
5100{
Harald Welte261af4b2018-02-12 21:20:39 +01005101 /* FIXME: resolve those from component-global state */
5102 var integer ts_nr := chan_nr.tn;
5103 var integer ss_nr;
5104 if (ischosen(chan_nr.u.ch0)) {
5105 ss_nr := 0;
5106 } else if (ischosen(chan_nr.u.lm)) {
5107 ss_nr := chan_nr.u.lm.sub_chan;
5108 } else if (ischosen(chan_nr.u.sdcch4)) {
5109 ss_nr := chan_nr.u.sdcch4.sub_chan;
5110 } else if (ischosen(chan_nr.u.sdcch8)) {
5111 ss_nr := chan_nr.u.sdcch8.sub_chan;
5112 } else {
5113 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005114 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005115 }
5116
5117 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5118 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005119 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005120}
5121
Neels Hofmeyr91401012019-07-11 00:42:35 +02005122/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5123 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5124 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5125 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5126 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005127private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5128 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5129{
5130 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005131}
5132
5133/* intra-BSC hand-over between BTS0 and BTS1 */
5134private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005135 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5136 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005137
5138 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5139 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5140
Harald Weltea0630032018-03-20 21:09:55 +01005141 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005142 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005143
5144 var HandoverState hs := {
5145 rr_ho_cmpl_seen := false,
5146 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005147 old_chan_nr := -,
5148 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005149 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005150 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005151 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005152 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5153 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005154
5155 /* From the MGW perspective, a handover is is characterized by
5156 * performing one MDCX operation with the MGW. So we expect to see
5157 * one more MDCX during handover. */
5158 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5159
Harald Welte261af4b2018-02-12 21:20:39 +01005160 alt {
5161 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005162 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005163
Philipp Maier4dae0652018-11-12 12:03:26 +01005164 /* Since this is an internal handover we expect the BSC to inform the
5165 * MSC about the event */
5166 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5167
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005168 /* Check the amount of MGCP transactions is still consistant with the
5169 * test expectation */
5170 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005171
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005172 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5173
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005174 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5175 * g_chan_nr to the new lchan that was handed over to. It lives in bts 1, so look it up at RSL1_PROC. */
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005176 f_verify_encr_info(chan_act);
5177
5178 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005179
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005180 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005181}
5182
5183testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005184 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005185 var MSC_ConnHdlr vc_conn;
5186 f_init(2, true);
5187 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005188
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005189 pars.expect_tsc := BTS_TSC[0];
5190
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005191 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005192
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005193 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005194 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005195
5196 /* from f_establish_fully() */
5197 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5198 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5199 /* from handover */
5200 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5201 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5202 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5203 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005204 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5205 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005206 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005207 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005208}
Harald Weltee9e02e42018-01-31 23:36:25 +01005209
Oliver Smith7eabd312021-07-12 14:18:56 +02005210function 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 +02005211 var MSC_ConnHdlr vc_conn;
5212 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5213 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5214
5215 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005216 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005217 f_sleep(1.0);
5218
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005219 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005220
5221 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5222 vc_conn.done;
5223
5224 /* from f_establish_fully() */
5225 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5226 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5227 /* from handover */
5228 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5229 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5230 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5231 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005232 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5233 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005234 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005235 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005236 f_shutdown_helper();
5237}
5238
5239testcase TC_ho_int_a5_0() runs on test_CT {
5240 f_tc_ho_int_a5('01'O);
5241}
5242
5243testcase TC_ho_int_a5_1() runs on test_CT {
5244 f_tc_ho_int_a5('02'O);
5245}
5246
5247testcase TC_ho_int_a5_3() runs on test_CT {
5248 f_tc_ho_int_a5('08'O);
5249}
5250
5251testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005252 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005253}
5254
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005255/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5256private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5257 g_pars := f_gen_test_hdlr_pars();
5258 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5259 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005260
5261 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5262 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5263
5264 f_establish_fully(ass_cmd, exp_compl);
5265 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5266
5267 var HandoverState hs := {
5268 rr_ho_cmpl_seen := false,
5269 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005270 old_chan_nr := -,
5271 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005272 };
5273 /* issue hand-over command on VTY */
5274 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5275 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5276 f_rslem_suspend(RSL1_PROC);
5277
5278 /* From the MGW perspective, a handover is is characterized by
5279 * performing one MDCX operation with the MGW. So we expect to see
5280 * one more MDCX during handover. */
5281 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5282
5283 var RSL_Message rsl;
5284 var PDU_ML3_NW_MS l3;
5285 var RslChannelNr new_chan_nr;
5286 var GsmArfcn arfcn;
5287 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5288 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5289 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5290 setverdict(fail, "Expected handoverCommand");
5291 mtc.stop;
5292 }
5293 }
5294 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5295 new_chan_nr, arfcn);
5296
5297 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5298
5299 /* resume processing of RSL DChan messages, which was temporarily suspended
5300 * before performing a hand-over */
5301 f_rslem_resume(RSL1_PROC);
5302 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5303
5304 f_sleep(1.0);
5305
5306 /* Handover fails because no HANDO DET appears on the new lchan,
5307 * and the old lchan reports a Radio Link Failure. */
5308 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5309
5310 var PDU_BSSAP rx_clear_request;
5311 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5312 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5313 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5314
5315 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5316
5317 var MgcpCommand mgcp;
5318 interleave {
5319 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5320 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005321 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005322 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005323 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005324 }
5325 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005326 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005327 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005328 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005329 }
5330 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5331 }
5332
5333 f_sleep(0.5);
5334 setverdict(pass);
5335}
5336testcase TC_ho_int_radio_link_failure() runs on test_CT {
5337 var MSC_ConnHdlr vc_conn;
5338 f_init(2, true);
5339 f_sleep(1.0);
5340
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005341 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005342
5343 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5344 vc_conn.done;
5345
5346 /* from f_establish_fully() */
5347 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5348 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5349 /* from handover */
5350 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5351 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5352 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5353 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005354 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5355 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005356 f_ctrs_bsc_and_bts_verify();
5357 f_shutdown_helper();
5358}
5359
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005360/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005361private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005362 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005363 var template MgcpResponse mgcp_resp;
5364 var MGCP_RecvFrom mrf;
5365 var template MgcpMessage msg_resp;
5366 var template MgcpMessage msg_dlcx := {
5367 command := tr_DLCX()
5368 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005369
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005370 if (g_pars.aoip) {
5371 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005372 log("Got first DLCX: ", mgcp);
5373 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005374 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005375
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005376 MGCP.receive(tr_DLCX()) -> value mgcp {
5377 log("Got second DLCX: ", mgcp);
5378 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5379 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005380 } else {
5381 /* For SCCPLite, BSC doesn't handle the MSC-side */
5382 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5383 log("Got first DLCX: ", mrf.msg.command);
5384 msg_resp := {
5385 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5386 }
5387 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5388 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005389 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005390}
5391
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005392private 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 +01005393
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005394 var NcellReports neighbor_rep := {
5395 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5396 };
5397 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5398 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5399 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005400
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005401 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005402
5403 f_sleep(0.5);
5404 /* The MSC negotiates Handover Request and Handover Request Ack with
5405 * the other BSS and comes back with a BSSMAP Handover Command
5406 * containing an RR Handover Command coming from the target BSS... */
5407
5408 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5409 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5410 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5411 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5412 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5413
5414 /* expect the Handover Command to go out on RR */
5415 var RSL_Message rsl_ho_cmd
5416 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5417 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5418 var RSL_IE_Body rsl_ho_cmd_l3;
5419 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5420 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5421 setverdict(fail);
5422 } else {
5423 log("Found L3 Info: ", rsl_ho_cmd_l3);
5424 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5425 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5426 setverdict(fail);
5427 } else {
5428 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5429 setverdict(pass);
5430 }
5431 }
5432
5433 /* When the other BSS has reported a completed handover, this side is
5434 * torn down. */
5435
5436 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5437 var BssmapCause cause := enum2int(cause_val);
5438 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5439
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005440 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005441
5442 interleave {
5443 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5444 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5445 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005446 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005447 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005448 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005449}
5450
5451private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5452 g_pars := f_gen_test_hdlr_pars();
5453 var PDU_BSSAP ass_req := f_gen_ass_req();
5454 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5455 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5456 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5457 f_establish_fully(ass_req, exp_compl);
5458
5459 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005460}
5461testcase TC_ho_out_of_this_bsc() runs on test_CT {
5462 var MSC_ConnHdlr vc_conn;
5463
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005464 f_init_vty();
5465 f_bts_0_cfg(BSCVTY,
5466 {"neighbor-list mode automatic",
5467 "handover 1",
5468 "handover algorithm 2",
5469 "handover2 window rxlev averaging 1",
5470 "neighbor lac 99 arfcn 123 bsic any"});
5471 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5472
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005473 f_init(1, true);
5474 f_sleep(1.0);
5475
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005476 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005477
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005478 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5479 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005480
5481 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5482 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5483 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5484 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5485 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5486 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5487 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005488 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005489}
5490
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005491private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5492 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005493 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005494 octetstring l3 := '0123456789'O)
5495runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005496 /* The old lchan and conn should still be active. See that arbitrary L3
5497 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005498 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005499 var template PDU_BSSAP exp_data := {
5500 discriminator := '1'B,
5501 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005502 dlci := dlci,
5503 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005504 pdu := {
5505 dtap := l3
5506 }
5507 };
5508 BSSAP.receive(exp_data);
5509 setverdict(pass);
5510}
5511
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005512private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5513 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005514 template (value) OCT1 dlci := '00'O,
5515 octetstring l3 := '0123456789'O)
5516runs on MSC_ConnHdlr {
5517 BSSAP.send(PDU_BSSAP:{
5518 discriminator := '1'B,
5519 spare := '0000000'B,
5520 dlci := dlci,
5521 lengthIndicator := lengthof(l3),
5522 pdu := {
5523 dtap := l3
5524 }
5525 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005526 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005527 setverdict(pass);
5528}
5529
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005530/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5531 * simply never sends a BSSMAP Handover Command. */
5532private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005533 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005534
5535 var PDU_BSSAP ass_req := f_gen_ass_req();
5536 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5537 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5538 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5539 f_establish_fully(ass_req, exp_compl);
5540
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005541 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005542 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5543
5544 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5545
5546 /* osmo-bsc should time out 10 seconds after the handover started.
5547 * Let's give it a bit extra. */
5548 f_sleep(15.0);
5549
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005550 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005551 f_sleep(1.0);
5552}
5553testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5554 var MSC_ConnHdlr vc_conn;
5555
5556 f_init(1, true);
5557 f_sleep(1.0);
5558
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005559 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005560
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005561 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5562 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005563
5564 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5565 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5566 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5567 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5568 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5569 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5570 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005571 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005572}
5573
5574/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5575 * RR Handover Failure. */
5576private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005577 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005578
5579 var PDU_BSSAP ass_req := f_gen_ass_req();
5580 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5581 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5582 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5583 f_establish_fully(ass_req, exp_compl);
5584
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005585 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005586 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5587
5588 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5589
5590 f_sleep(0.5);
5591 /* The MSC negotiates Handover Request and Handover Request Ack with
5592 * the other BSS and comes back with a BSSMAP Handover Command
5593 * containing an RR Handover Command coming from the target BSS... */
5594
5595 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5596 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5597 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5598 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5599 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5600
5601 /* expect the Handover Command to go out on RR */
5602 var RSL_Message rsl_ho_cmd
5603 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5604 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5605 var RSL_IE_Body rsl_ho_cmd_l3;
5606 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5607 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5608 setverdict(fail);
5609 } else {
5610 log("Found L3 Info: ", rsl_ho_cmd_l3);
5611 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5612 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5613 setverdict(fail);
5614 } else {
5615 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5616 setverdict(pass);
5617 }
5618 }
5619
5620 f_sleep(0.2);
5621 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5622
5623 /* Should tell the MSC about the failure */
5624 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5625
5626 f_sleep(1.0);
5627
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005628 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005629 f_sleep(1.0);
5630
5631 setverdict(pass);
5632 f_sleep(1.0);
5633}
5634testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5635 var MSC_ConnHdlr vc_conn;
5636
5637 f_init(1, true);
5638 f_sleep(1.0);
5639
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005640 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005641
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005642 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5643 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005644
5645 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5646 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5647 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5648 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5649 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5650 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5651 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005652 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005653}
5654
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005655/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5656 * (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 +02005657 * and the lchan is released. */
5658private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005659 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005660
5661 var PDU_BSSAP ass_req := f_gen_ass_req();
5662 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5663 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5664 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5665 f_establish_fully(ass_req, exp_compl);
5666
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005667 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005668 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5669
5670 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5671
5672 f_sleep(0.5);
5673 /* The MSC negotiates Handover Request and Handover Request Ack with
5674 * the other BSS and comes back with a BSSMAP Handover Command
5675 * containing an RR Handover Command coming from the target BSS... */
5676
5677 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5678 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5679 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5680 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5681 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5682
5683 /* expect the Handover Command to go out on RR */
5684 var RSL_Message rsl_ho_cmd
5685 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5686 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5687 var RSL_IE_Body rsl_ho_cmd_l3;
5688 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5689 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5690 setverdict(fail);
5691 } else {
5692 log("Found L3 Info: ", rsl_ho_cmd_l3);
5693 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5694 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5695 setverdict(fail);
5696 } else {
5697 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5698 setverdict(pass);
5699 }
5700 }
5701
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005702 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5703 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5704 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005705
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005706 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005707 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5708 log("Got BSSMAP Clear Request");
5709 /* Instruct BSC to clear channel */
5710 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5711 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5712
5713 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005714 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005715 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5716 log("Got Deact SACCH");
5717 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005718 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005719 log("Got RR Release");
5720 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005721 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005722 log("Got RF Chan Rel");
5723 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005724 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005725 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005726 }
5727
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005728 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005729 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005730
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005731 setverdict(pass);
5732 f_sleep(1.0);
5733}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005734testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005735 var MSC_ConnHdlr vc_conn;
5736
5737 f_init(1, true);
5738 f_sleep(1.0);
5739
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005740 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005741
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005742 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005743 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005744
5745 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5746 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5747 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5748 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5749 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5750 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5751 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005752 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005753}
5754
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005755private 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 +01005756 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5757 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5758 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5759 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5760 * before we get started. */
5761 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5762 f_rslem_register(0, new_chan_nr);
5763 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005764 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005765 f_sleep(1.0);
5766
5767 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5768 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5769 activate(as_Media());
5770
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005771 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005772 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005773 oldToNewBSSIEs := oldToNewBSSIEs,
5774 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005775 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005776
5777 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5778
5779 var PDU_BSSAP rx_bssap;
5780 var octetstring ho_command_str;
5781
5782 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005783
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005784 /* we're sure that the channel activation is done now, verify the parameters in it */
5785 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
5786 f_verify_encr_info(chan_act);
5787 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005788
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005789 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5790 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5791 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5792 log("L3 Info in HO Request Ack is ", ho_command);
5793
5794 var GsmArfcn arfcn;
5795 var RslChannelNr actual_new_chan_nr;
5796 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5797 actual_new_chan_nr, arfcn);
5798
5799 if (actual_new_chan_nr != new_chan_nr) {
5800 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5801 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5802 setverdict(fail);
5803 return;
5804 }
5805 log("Handover Command chan_nr is", actual_new_chan_nr);
5806
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005807 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
5808 if (not match(got_tsc, expect_target_tsc)) {
5809 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
5810 expect_target_tsc, " got ", got_tsc);
5811 mtc.stop;
5812 } else {
5813 log("handoverCommand: verified TSC = ", got_tsc);
5814 }
5815
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005816 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5817 * tells the MS to handover to the new lchan. Here comes the new MS on
5818 * the new lchan with a Handover RACH: */
5819
5820 /* send handover detect */
5821
5822 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5823
5824 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5825
5826 /* send handover complete over the new channel */
5827
5828 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5829 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5830 enc_PDU_ML3_MS_NW(l3_tx)));
5831
5832 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005833 setverdict(pass);
5834}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005835
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005836private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005837 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005838 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5839 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5840 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005841 }
5842 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005843 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005844 } else {
5845 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005846 }
5847 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005848 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005849 setverdict(pass);
5850}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005851function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005852 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005853
5854 f_init(1, true);
5855 f_sleep(1.0);
5856
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005857 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005858
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005859 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5860 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005861
5862 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5863 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005864
5865 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5866 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5867 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5868 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5869 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005870}
5871
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005872testcase TC_ho_into_this_bsc() runs on test_CT {
5873 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5874 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005875 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005876}
5877
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005878function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5879 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5880 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5881 f_tc_ho_into_this_bsc_main(pars);
5882 f_shutdown_helper();
5883}
5884
5885testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5886 f_tc_ho_into_this_bsc_a5('01'O);
5887}
5888
5889testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5890 f_tc_ho_into_this_bsc_a5('02'O);
5891}
5892
5893testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5894 f_tc_ho_into_this_bsc_a5('08'O);
5895}
5896
5897testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5898 f_tc_ho_into_this_bsc_a5('10'O);
5899}
5900
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005901testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5902 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5903 pars.host_aoip_tla := "::6";
5904 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005905 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005906}
5907
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005908/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005909 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005910 channel is later released (RR CHannel Release), should trigger inclusion of
5911 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5912 neighbors. */
5913testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5914 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5915 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005916 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005917 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005918
5919 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5920 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5921 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005922 f_shutdown_helper();
5923}
5924
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005925/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5926 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5927 list when the channel is released. */
5928testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5929 f_init_vty();
5930 f_vty_allow_srvcc_fast_return(true, 0)
5931
5932 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5933 pars.last_used_eutran_plmn := '323454'O;
5934 pars.exp_fast_return := false;
5935 f_tc_ho_into_this_bsc_main(pars);
5936 f_vty_allow_srvcc_fast_return(false, 0);
5937 f_shutdown_helper();
5938}
5939
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005940private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5941 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5942 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5943 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5944 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5945 setverdict(pass);
5946}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005947
5948private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5949 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005950 var MSC_ConnHdlr vc_conn;
5951 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5952
5953 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005954 if (disable_fast_return) {
5955 f_vty_allow_srvcc_fast_return(true, 0);
5956 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005957 f_sleep(1.0);
5958
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005959 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005960
5961 pars.last_used_eutran_plmn := '323454'O;
5962 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5963 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5964
5965 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5966 vc_conn.done;
5967
5968 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5969 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5970 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5971 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5972 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5973 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005974
5975 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5976 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005977 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005978
5979 if (disable_fast_return) {
5980 f_vty_allow_srvcc_fast_return(false, 0);
5981 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005982 f_shutdown_helper();
5983}
5984
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005985/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5986 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5987 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5988 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5989testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5990 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5991}
5992/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5993 * independently of fast-reture allowed/forbidden in local BTS */
5994testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5995 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5996}
5997
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005998private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5999 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6000 f_rslem_register(0, new_chan_nr);
6001 g_chan_nr := new_chan_nr;
6002 f_sleep(1.0);
6003
6004 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6005 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6006 activate(as_Media());
6007
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006008 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006009 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006010 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006011
6012 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6013
6014 var PDU_BSSAP rx_bssap;
6015 var octetstring ho_command_str;
6016
6017 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6018
6019 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6020 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6021 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6022 log("L3 Info in HO Request Ack is ", ho_command);
6023
6024 var GsmArfcn arfcn;
6025 var RslChannelNr actual_new_chan_nr;
6026 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6027 actual_new_chan_nr, arfcn);
6028
6029 if (actual_new_chan_nr != new_chan_nr) {
6030 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6031 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6032 setverdict(fail);
6033 return;
6034 }
6035 log("Handover Command chan_nr is", actual_new_chan_nr);
6036
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006037 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6038 f_sleep(1.0);
6039
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006040 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6041 * tells the MS to handover to the new lchan. In this case, the MS
6042 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6043 * Handover Failure to the MSC. The procedure according to 3GPP TS
6044 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6045 * BSSMAP Clear Command: */
6046
6047 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6048 var BssmapCause cause := enum2int(cause_val);
6049 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6050
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006051 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006052 BSSAP.receive(tr_BSSMAP_ClearComplete);
6053
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006054 setverdict(pass);
6055 f_sleep(1.0);
6056
6057 setverdict(pass);
6058}
6059testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6060 var MSC_ConnHdlr vc_conn;
6061 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6062
6063 f_init(1, true);
6064 f_sleep(1.0);
6065
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006066 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006067
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006068 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6069 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006070
6071 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6072 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006073
6074 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6075 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6076 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6077 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6078 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006079 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006080}
6081
6082private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6083 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6084 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6085 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6086 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6087 * before we get started. */
6088 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6089 f_rslem_register(0, new_chan_nr);
6090 g_chan_nr := new_chan_nr;
6091 f_sleep(1.0);
6092
6093 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6094 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6095 activate(as_Media());
6096
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006097 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006098 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006099 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006100
6101 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6102
6103 var PDU_BSSAP rx_bssap;
6104 var octetstring ho_command_str;
6105
6106 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6107
6108 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6109 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6110 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6111 log("L3 Info in HO Request Ack is ", ho_command);
6112
6113 var GsmArfcn arfcn;
6114 var RslChannelNr actual_new_chan_nr;
6115 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6116 actual_new_chan_nr, arfcn);
6117
6118 if (actual_new_chan_nr != new_chan_nr) {
6119 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6120 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6121 setverdict(fail);
6122 return;
6123 }
6124 log("Handover Command chan_nr is", actual_new_chan_nr);
6125
6126 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6127 * tells the MS to handover to the new lchan. Here comes the new MS on
6128 * the new lchan with a Handover RACH: */
6129
6130 /* send handover detect */
6131
6132 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6133
6134 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6135
6136 /* The MSC chooses to clear the connection now, maybe we got the
6137 * Handover RACH on the new cell but the MS still signaled Handover
6138 * Failure to the old BSS? */
6139
6140 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6141 var BssmapCause cause := enum2int(cause_val);
6142 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6143
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006144 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006145 BSSAP.receive(tr_BSSMAP_ClearComplete);
6146
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006147 f_sleep(1.0);
6148}
6149testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6150 var MSC_ConnHdlr vc_conn;
6151 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6152
6153 f_init(1, true);
6154 f_sleep(1.0);
6155
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006156 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006157
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006158 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6159 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006160
6161 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6162 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006163
6164 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6165 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6166 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6167 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6168 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006169 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006170}
6171
6172/* The new BSS's lchan times out before the MSC decides that handover failed. */
6173private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6174 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6175 f_rslem_register(0, new_chan_nr);
6176 g_chan_nr := new_chan_nr;
6177 f_sleep(1.0);
6178
6179 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6180 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6181 activate(as_Media());
6182
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006183 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006184 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006185 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006186
6187 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6188
6189 var PDU_BSSAP rx_bssap;
6190 var octetstring ho_command_str;
6191
6192 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6193
6194 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6195 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6196 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6197 log("L3 Info in HO Request Ack is ", ho_command);
6198
6199 var GsmArfcn arfcn;
6200 var RslChannelNr actual_new_chan_nr;
6201 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6202 actual_new_chan_nr, arfcn);
6203
6204 if (actual_new_chan_nr != new_chan_nr) {
6205 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6206 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6207 setverdict(fail);
6208 return;
6209 }
6210 log("Handover Command chan_nr is", actual_new_chan_nr);
6211
6212 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6213 * tells the MS to handover to the new lchan. But the MS never shows up
6214 * on the new lchan. */
6215
6216 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6217
6218 /* Did osmo-bsc also send a Clear Request? */
6219 timer T := 0.5;
6220 T.start;
6221 alt {
6222 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6223 [] T.timeout { }
6224 }
6225
6226 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6227 * asked for it, this is a Handover Failure after all). */
6228
6229 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6230 var BssmapCause cause := enum2int(cause_val);
6231 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6232
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006233 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006234 BSSAP.receive(tr_BSSMAP_ClearComplete);
6235
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006236 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006237}
6238testcase TC_ho_in_fail_no_detect() runs on test_CT {
6239 var MSC_ConnHdlr vc_conn;
6240 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6241
6242 f_init(1, true);
6243 f_sleep(1.0);
6244
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006245 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006246
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006247 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6248 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006249
6250 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6251 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006252
6253 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6254 f_ctrs_bsc_and_bts_add(0, "handover:error");
6255 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6256 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6257 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006258 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006259}
6260
6261/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6262private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6263 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6264 f_rslem_register(0, new_chan_nr);
6265 g_chan_nr := new_chan_nr;
6266 f_sleep(1.0);
6267
6268 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6269 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6270 activate(as_Media());
6271
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006272 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006273 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006274 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006275
6276 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6277
6278 var PDU_BSSAP rx_bssap;
6279 var octetstring ho_command_str;
6280
6281 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6282
6283 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6284 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6285 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6286 log("L3 Info in HO Request Ack is ", ho_command);
6287
6288 var GsmArfcn arfcn;
6289 var RslChannelNr actual_new_chan_nr;
6290 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6291 actual_new_chan_nr, arfcn);
6292
6293 if (actual_new_chan_nr != new_chan_nr) {
6294 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6295 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6296 setverdict(fail);
6297 return;
6298 }
6299 log("Handover Command chan_nr is", actual_new_chan_nr);
6300
6301 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6302 * tells the MS to handover to the new lchan. But the MS never shows up
6303 * on the new lchan. */
6304
6305 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6306
6307 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006308 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006309
6310 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006311 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6312 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6313 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006314 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006315 BSSAP.receive(tr_BSSMAP_ClearComplete);
6316
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006317 f_sleep(1.0);
6318}
6319testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6320 var MSC_ConnHdlr vc_conn;
6321 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6322
6323 f_init(1, true);
6324 f_sleep(1.0);
6325
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006326 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006327
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006328 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6329 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006330
6331 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6332 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006333
6334 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6335 f_ctrs_bsc_and_bts_add(0, "handover:error");
6336 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6337 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6338 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006339 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006340}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006341
Neels Hofmeyr91401012019-07-11 00:42:35 +02006342type record of charstring Commands;
6343
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006344private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006345{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006346 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006347 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006348 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006349 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006350 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006351}
6352
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006353private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6354{
6355 f_vty_enter_cfg_cs7_inst(pt, 0);
6356 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6357 f_vty_transceive(pt, cmds[i]);
6358 }
6359 f_vty_transceive(pt, "end");
6360}
6361
Neels Hofmeyr91401012019-07-11 00:42:35 +02006362private function f_probe_for_handover(charstring log_label,
6363 charstring log_descr,
6364 charstring handover_vty_cmd,
6365 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006366 boolean is_inter_bsc_handover := false,
6367 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006368runs on MSC_ConnHdlr
6369{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006370 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6371 * lchans to be established on bts 1 or bts 2. */
6372 f_rslem_suspend(RSL1_PROC);
6373 f_rslem_suspend(RSL2_PROC);
6374
Neels Hofmeyr91401012019-07-11 00:42:35 +02006375 var RSL_Message rsl;
6376
6377 var charstring log_msg := " (expecting handover)"
6378 if (not expect_handover) {
6379 log_msg := " (expecting NO handover)";
6380 }
6381 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6382 f_vty_transceive(BSCVTY, handover_vty_cmd);
6383
Neels Hofmeyr91401012019-07-11 00:42:35 +02006384 timer T := 2.0;
6385 T.start;
6386
6387 alt {
6388 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6389 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6390 log("Rx L3 from net: ", l3);
6391 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6392 var RslChannelNr new_chan_nr;
6393 var GsmArfcn arfcn;
6394 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6395 new_chan_nr, arfcn);
6396 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6397 log(l3.msgs.rrm.handoverCommand);
6398
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006399 /* Verify correct TSC in handoverCommand */
6400 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6401 if (not match(got_tsc, expect_target_tsc)) {
6402 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6403 expect_target_tsc, " got ", got_tsc);
6404 mtc.stop;
6405 } else {
6406 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6407 expect_target_tsc, ")");
6408 }
6409
Neels Hofmeyr91401012019-07-11 00:42:35 +02006410 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6411 * matter on which BTS it really is, we're not going to follow through an entire handover
6412 * anyway. */
6413 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6414 f_rslem_resume(RSL1_PROC);
6415 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6416 f_rslem_resume(RSL2_PROC);
6417
6418 if (expect_handover and not is_inter_bsc_handover) {
6419 setverdict(pass);
6420 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6421 } else {
6422 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6423 & log_label & ": " & log_descr);
6424 }
6425
6426 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6427 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6428 * Handover Failure. */
6429 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6430
6431 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6432 f_sleep(0.5);
6433 RSL1.clear;
6434 RSL2.clear;
6435 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6436 break;
6437 } else {
6438 repeat;
6439 }
6440 }
6441 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6442 if (expect_handover and is_inter_bsc_handover) {
6443 setverdict(pass);
6444 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6445 } else {
6446 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6447 & log_label & ": " & log_descr);
6448 }
6449
6450 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6451
6452 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6453 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6454 * setting a short timeout and waiting is the only way. */
6455 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6456 f_sleep(1.5);
6457 log("f_probe_for_handover(" & log_label & "): ...done");
6458
6459 break;
6460 }
6461 [] T.timeout {
6462 if (expect_handover) {
6463 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6464 & log_label & ": " & log_descr);
6465 } else {
6466 setverdict(pass);
6467 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6468 }
6469 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6470 break;
6471 }
6472 }
6473
6474 f_rslem_resume(RSL1_PROC);
6475 f_rslem_resume(RSL2_PROC);
6476 f_sleep(3.0);
6477 RSL.clear;
6478
6479 log("f_probe_for_handover(" & log_label & "): done clearing");
6480}
6481
6482/* Test the effect of various neighbor configuration scenarios:
6483 *
6484 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6485 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6486 */
6487private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6488 g_pars := f_gen_test_hdlr_pars();
6489 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6490 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006491
6492 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6493 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6494
6495 /* Establish lchan at bts 0 */
6496 f_establish_fully(ass_cmd, exp_compl);
6497
6498 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6499 f_vty_enter_cfg_network(BSCVTY);
6500 f_vty_transceive(BSCVTY, "timer T7 1");
6501 f_vty_transceive(BSCVTY, "end");
6502}
6503
6504private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6505 f_tc_ho_neighbor_config_start();
6506
6507 /*
6508 * bts 0 ARFCN 871 BSIC 10
6509 * bts 1 ARFCN 871 BSIC 11
6510 * bts 2 ARFCN 871 BSIC 12
6511 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6512 */
6513
6514 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006515 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006516 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6517 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006518 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006519
6520 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6521 "handover any to arfcn 13 bsic 39",
6522 false);
6523
6524 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6525 "handover any to arfcn 871 bsic 12",
6526 false);
6527
6528 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6529 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006530 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006531}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006532testcase TC_ho_neighbor_config_1() runs on test_CT {
6533 var MSC_ConnHdlr vc_conn;
6534 f_init(3, true, guard_timeout := 60.0);
6535 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006536 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006537 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6538 vc_conn.done;
6539
6540 /* f_tc_ho_neighbor_config_start() */
6541 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6542 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6543
6544 /* 1.a */
6545 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6546 * handover quickly by sending a Handover Failure message. */
6547 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6548 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6549 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6550 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006551 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6552 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006553
6554 /* 1.b */
6555 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6556 f_ctrs_bsc_and_bts_add(0, "handover:error");
6557
6558 /* 1.c */
6559 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6560 f_ctrs_bsc_and_bts_add(0, "handover:error");
6561
6562 /* 1.d */
6563 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6564 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6565 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6566 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006567 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6568 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006569
6570 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006571 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006572}
6573
Neels Hofmeyr91401012019-07-11 00:42:35 +02006574private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6575 f_tc_ho_neighbor_config_start();
6576
6577 /*
6578 * bts 0 ARFCN 871 BSIC 10
6579 * bts 1 ARFCN 871 BSIC 11
6580 * bts 2 ARFCN 871 BSIC 12
6581 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6582 */
6583
6584 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006585 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006586 f_sleep(0.5);
6587
6588 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6589 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006590 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006591
6592 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6593 "handover any to arfcn 871 bsic 12",
6594 false);
6595}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006596testcase TC_ho_neighbor_config_2() runs on test_CT {
6597 var MSC_ConnHdlr vc_conn;
6598 f_init(3, true, guard_timeout := 50.0);
6599 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006600 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006601 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6602 vc_conn.done;
6603
6604 /* f_tc_ho_neighbor_config_start() */
6605 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6606 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6607
6608 /* 2.a */
6609 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6610 * handover quickly by sending a Handover Failure message. */
6611 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6612 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6613 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6614 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006615 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6616 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006617
6618 /* 2.b */
6619 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6620 f_ctrs_bsc_and_bts_add(0, "handover:error");
6621
6622 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006623 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006624}
6625
Neels Hofmeyr91401012019-07-11 00:42:35 +02006626private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6627 f_tc_ho_neighbor_config_start();
6628
6629 /*
6630 * bts 0 ARFCN 871 BSIC 10
6631 * bts 1 ARFCN 871 BSIC 11
6632 * bts 2 ARFCN 871 BSIC 12
6633 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6634 */
6635
6636 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006637 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006638 f_sleep(0.5);
6639
6640 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6641 "handover any to arfcn 871 bsic 11",
6642 false);
6643 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",
6644 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006645 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006646}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006647testcase TC_ho_neighbor_config_3() runs on test_CT {
6648 var MSC_ConnHdlr vc_conn;
6649 f_init(3, true, guard_timeout := 50.0);
6650 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006651 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006652 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6653 vc_conn.done;
6654
6655 /* f_tc_ho_neighbor_config_start() */
6656 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6657 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6658
6659 /* 3.a */
6660 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6661 f_ctrs_bsc_and_bts_add(0, "handover:error");
6662
6663 /* 3.b */
6664 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6665 * handover quickly by sending a Handover Failure message. */
6666 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6667 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6668 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6669 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006670 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
6671 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006672
6673 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006674 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006675}
6676
Neels Hofmeyr91401012019-07-11 00:42:35 +02006677private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6678 f_tc_ho_neighbor_config_start();
6679
6680 /*
6681 * bts 0 ARFCN 871 BSIC 10
6682 * bts 1 ARFCN 871 BSIC 11
6683 * bts 2 ARFCN 871 BSIC 12
6684 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6685 */
6686
6687 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006688 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006689 f_sleep(0.5);
6690
6691 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6692 "handover any to arfcn 871 bsic 11",
6693 false);
6694 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6695 "handover any to arfcn 871 bsic 12",
6696 false);
6697 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6698 "handover any to arfcn 123 bsic 45",
6699 true, true);
6700}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006701testcase TC_ho_neighbor_config_4() runs on test_CT {
6702 var MSC_ConnHdlr vc_conn;
6703 f_init(3, true, guard_timeout := 50.0);
6704 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006705 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006706 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6707 vc_conn.done;
6708
6709 /* f_tc_ho_neighbor_config_start() */
6710 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6711 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6712
6713 /* 4.a */
6714 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6715 f_ctrs_bsc_and_bts_add(0, "handover:error");
6716
6717 /* 4.b */
6718 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6719 f_ctrs_bsc_and_bts_add(0, "handover:error");
6720
6721 /* 4.c */
6722 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6723 * handover quickly by timing out after the Handover Required message */
6724 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6725 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6726 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6727 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6728
6729 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006730 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006731}
6732
Neels Hofmeyr91401012019-07-11 00:42:35 +02006733private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6734 f_tc_ho_neighbor_config_start();
6735
6736 /*
6737 * bts 0 ARFCN 871 BSIC 10
6738 * bts 1 ARFCN 871 BSIC 11
6739 * bts 2 ARFCN 871 BSIC 12
6740 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6741 */
6742
6743 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 +02006744 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006745 f_sleep(0.5);
6746
6747 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6748 "handover any to arfcn 871 bsic 12",
6749 true, true);
6750}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006751testcase TC_ho_neighbor_config_5() runs on test_CT {
6752 var MSC_ConnHdlr vc_conn;
6753 f_init(3, true);
6754 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006755 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006756 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6757 vc_conn.done;
6758
6759 /* f_tc_ho_neighbor_config_start() */
6760 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6761 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6762
6763 /* 5 */
6764 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6765 * handover quickly by timing out after the Handover Required message */
6766 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6767 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6768 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6769 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6770
6771 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006772 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006773}
6774
Neels Hofmeyr91401012019-07-11 00:42:35 +02006775private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6776 f_tc_ho_neighbor_config_start();
6777
6778 /*
6779 * bts 0 ARFCN 871 BSIC 10
6780 * bts 1 ARFCN 871 BSIC 11
6781 * bts 2 ARFCN 871 BSIC 12
6782 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6783 */
6784
6785 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6786 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006787 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006788 f_sleep(0.5);
6789
6790 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6791 "handover any to arfcn 871 bsic 12",
6792 false);
6793}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006794testcase TC_ho_neighbor_config_6() runs on test_CT {
6795 var MSC_ConnHdlr vc_conn;
6796 f_init(3, true);
6797 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006798 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006799 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6800 vc_conn.done;
6801
6802 /* f_tc_ho_neighbor_config_start() */
6803 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6804 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6805
6806 /* 6.a */
6807 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6808 * handover quickly by timing out after the Handover Required message */
6809 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6810 f_ctrs_bsc_and_bts_add(0, "handover:error");
6811
6812 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006813 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006814}
6815
Neels Hofmeyr91401012019-07-11 00:42:35 +02006816private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6817 f_tc_ho_neighbor_config_start();
6818
6819 /*
6820 * bts 0 ARFCN 871 BSIC 10
6821 * bts 1 ARFCN 871 BSIC 11
6822 * bts 2 ARFCN 871 BSIC 12
6823 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6824 */
6825
6826 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6827 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006828 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006829 f_sleep(0.5);
6830
6831 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6832 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006833 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006834 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6835 "handover any to arfcn 123 bsic 45",
6836 true, true);
6837}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006838testcase TC_ho_neighbor_config_7() runs on test_CT {
6839 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006840 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006841 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006842 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006843 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6844 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006845
6846 /* f_tc_ho_neighbor_config_start() */
6847 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6848 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6849
6850 /* 7.a */
6851 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6852 * handover quickly by sending a Handover Failure message. */
6853 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6854 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6855 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6856 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006857 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
6858 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006859
6860 /* 7.b */
6861 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6862 * handover quickly by timing out after the Handover Required message */
6863 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6864 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6865 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6866 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6867
6868 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006869 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006870}
6871
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006872/* OS#3041: Open and close N connections in a normal fashion, and expect no
6873 * BSSMAP Reset just because of that. */
6874testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6875 var default d;
6876 var integer i;
6877 var DchanTuple dt;
6878
6879 f_init();
6880
6881 /* Wait for initial BSSMAP Reset to pass */
6882 f_sleep(4.0);
6883
6884 d := activate(no_bssmap_reset());
6885
6886 /* Setup up a number of connections and RLSD them again from the MSC
6887 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6888 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006889 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006890 /* Since we're doing a lot of runs, give each one a fresh
6891 * T_guard from the top. */
6892 T_guard.start;
6893
6894 /* Setup a BSSAP connection and clear it right away. This is
6895 * the MSC telling the BSC about a planned release, it's not an
6896 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006897 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006898
6899 /* MSC disconnects (RLSD). */
6900 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6901 }
6902
6903 /* In the buggy behavior, a timeout of 2 seconds happens between above
6904 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6905 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6906 f_sleep(4.0);
6907
6908 deactivate(d);
6909 f_shutdown_helper();
6910}
Harald Welte552620d2017-12-16 23:21:36 +01006911
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006912/* OS#3041: Open and close N connections in a normal fashion, and expect no
6913 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6914 * the MSC. */
6915testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6916 var default d;
6917 var integer i;
6918 var DchanTuple dt;
6919 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006920 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6921 var BssmapCause cause := enum2int(cause_val);
6922
6923 f_init();
6924
6925 /* Wait for initial BSSMAP Reset to pass */
6926 f_sleep(4.0);
6927
6928 d := activate(no_bssmap_reset());
6929
6930 /* Setup up a number of connections and RLSD them again from the MSC
6931 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6932 * Let's do it some more times for good measure. */
6933 for (i := 0; i < 8; i := i+1) {
6934 /* Since we're doing a lot of runs, give each one a fresh
6935 * T_guard from the top. */
6936 T_guard.start;
6937
6938 /* Setup a BSSAP connection and clear it right away. This is
6939 * the MSC telling the BSC about a planned release, it's not an
6940 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006941 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006942
6943 /* Instruct BSC to clear channel */
6944 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6945
6946 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006947 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006948 }
6949
6950 /* In the buggy behavior, a timeout of 2 seconds happens between above
6951 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6952 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6953 f_sleep(4.0);
6954
6955 deactivate(d);
6956 f_shutdown_helper();
6957}
6958
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006959/* OS#3041: Open and close N connections in a normal fashion, and expect no
6960 * BSSMAP Reset just because of that. Close connections from the MS side with a
6961 * Release Ind on RSL. */
6962testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6963 var default d;
6964 var integer i;
6965 var DchanTuple dt;
6966 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006967 var integer j;
6968
6969 f_init();
6970
6971 /* Wait for initial BSSMAP Reset to pass */
6972 f_sleep(4.0);
6973
6974 d := activate(no_bssmap_reset());
6975
6976 /* Setup up a number of connections and RLSD them again from the MSC
6977 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6978 * Let's do it some more times for good measure. */
6979 for (i := 0; i < 8; i := i+1) {
6980 /* Since we're doing a lot of runs, give each one a fresh
6981 * T_guard from the top. */
6982 T_guard.start;
6983
6984 /* Setup a BSSAP connection and clear it right away. This is
6985 * the MSC telling the BSC about a planned release, it's not an
6986 * erratic loss of a connection. */
6987 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6988
6989 /* simulate RLL REL IND */
6990 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6991
6992 /* expect Clear Request on MSC side */
6993 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6994
6995 /* Instruct BSC to clear channel */
6996 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6997 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6998
6999 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007000 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007001 }
7002
7003 /* In the buggy behavior, a timeout of 2 seconds happens between above
7004 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7005 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7006 f_sleep(4.0);
7007
7008 deactivate(d);
7009 f_shutdown_helper();
7010}
7011
Harald Welte94e0c342018-04-07 11:33:23 +02007012/***********************************************************************
7013 * IPA style dynamic PDCH
7014 ***********************************************************************/
7015
7016private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7017 template (omit) RSL_Cause nack := omit)
7018runs on test_CT {
7019 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7020 var RSL_Message rsl_unused;
7021 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7022 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7023 /* expect the BSC to issue the related RSL command */
7024 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7025 if (istemplatekind(nack, "omit")) {
7026 /* respond with a related acknowledgement */
7027 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7028 } else {
7029 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
7030 }
7031}
7032
7033private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7034 template (omit) RSL_Cause nack := omit)
7035runs on test_CT {
7036 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7037 var RSL_Message rsl_unused;
7038 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7039 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7040 /* expect the BSC to issue the related RSL command */
7041 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
7042 if (istemplatekind(nack, "omit")) {
7043 /* respond with a related acknowledgement */
7044 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
7045 } else {
7046 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
7047 }
7048}
7049
7050private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7051runs on test_CT return charstring {
7052 var charstring cmd, resp;
7053 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007054 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007055}
7056
7057private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7058 template charstring exp)
7059runs on test_CT {
7060 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7061 if (not match(mode, exp)) {
7062 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007063 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007064 }
7065}
7066
7067private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7068runs on test_CT {
7069 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7070 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7071 f_vty_transceive(BSCVTY, "end");
7072}
7073
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007074
7075private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7076 var integer i;
7077 for (i := 0; i < 8; i := i + 1) {
7078 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7079 }
7080}
7081
Harald Welte94e0c342018-04-07 11:33:23 +02007082private const charstring TCHF_MODE := "TCH/F mode";
7083private const charstring TCHH_MODE := "TCH/H mode";
7084private const charstring PDCH_MODE := "PDCH mode";
7085private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007086private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007087
7088/* Test IPA PDCH activation / deactivation triggered by VTY */
7089testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7090 var RSL_Message rsl_unused;
7091
7092 /* change Timeslot 6 before f_init() starts RSL */
7093 f_init_vty();
7094 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7095 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7096
7097 f_init(1, false);
7098 f_sleep(1.0);
7099
7100 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7101
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007102 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007103 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7104 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7105 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7106 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7107 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007108 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007109 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7110
7111 /* De-activate it via VTY */
7112 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7113 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007114 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007115 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7116
7117 /* re-activate it via VTY */
7118 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7119 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007120 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007121 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7122
7123 /* and finally de-activate it again */
7124 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7125 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007126 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007127 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7128
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007129 /* clean up config */
7130 f_ts_set_chcomb(0, 0, 6, "PDCH");
7131
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007132 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007133}
7134
7135/* Test IPA PDCH activation NACK */
7136testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7137 var RSL_Message rsl_unused;
7138
7139 /* change Timeslot 6 before f_init() starts RSL */
7140 f_init_vty();
7141 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7142 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7143
7144 f_init(1, false);
7145 f_sleep(1.0);
7146
7147 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7148
7149 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7150 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7151 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7152 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7153 f_sleep(1.0);
7154 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7155
7156 /* De-activate it via VTY */
7157 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7158 f_sleep(1.0);
7159 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7160
7161 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7162 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7163 f_sleep(1.0);
7164 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7165
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007166 /* clean up config */
7167 f_ts_set_chcomb(0, 0, 6, "PDCH");
7168
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007169 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007170}
7171
7172
7173/***********************************************************************
7174 * Osmocom style dynamic PDCH
7175 ***********************************************************************/
7176
7177private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7178 template (omit) RSL_Cause nack := omit)
7179runs on test_CT {
7180 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7181 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007182 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007183 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7184 /* expect the BSC to issue the related RSL command */
7185 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7186 if (istemplatekind(nack, "omit")) {
7187 /* respond with a related acknowledgement */
7188 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7189 } else {
7190 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7191 }
7192}
7193
7194private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7195 template (omit) RSL_Cause nack := omit)
7196runs on test_CT {
7197 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7198 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007199 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007200 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7201 /* expect the BSC to issue the related RSL command */
7202 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7203 if (istemplatekind(nack, "omit")) {
7204 /* respond with a related acknowledgement */
7205 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7206 } else {
7207 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7208 }
7209}
7210
7211/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7212testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7213 var RSL_Message rsl_unused;
7214
7215 /* change Timeslot 6 before f_init() starts RSL */
7216 f_init_vty();
7217 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
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 chan_nr := valueof(t_RslChanNr_PDCH(6));
7224
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007225 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007226 f_ts_dyn_mode_assert(0, 0, 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(chan_nr, ?));
7229
7230 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7231 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007232 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 +02007233 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7234
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007235 /* clean up config */
7236 f_ts_set_chcomb(0, 0, 6, "PDCH");
7237
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007238 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007239}
7240
7241/* Test Osmocom dyn PDCH activation NACK behavior */
7242testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7243 var RSL_Message rsl_unused;
7244
7245 /* change Timeslot 6 before f_init() starts RSL */
7246 f_init_vty();
7247 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7248 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7249
7250 f_init(1, false);
7251 f_sleep(1.0);
7252
7253 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7254
7255 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7256 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7257 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7258
7259 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7260 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7261 f_sleep(1.0);
7262 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7263
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007264 /* clean up config */
7265 f_ts_set_chcomb(0, 0, 6, "PDCH");
7266
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007267 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007268}
7269
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007270/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7271testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7272 var RSL_Message rsl_unused, rsl_msg;
7273 var DchanTuple dt;
7274 var BSSAP_N_CONNECT_ind rx_c_ind;
7275
7276 /* change Timeslot 6 before f_init() starts RSL */
7277 f_init_vty();
7278 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7279 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7280
7281 f_init(1, false);
7282 f_sleep(1.0);
7283
7284 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7285
7286 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7287 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7288 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7289 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7290
7291 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7292 f_sleep(1.0);
7293 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7294 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7295
7296 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7297 * on CCCH+SDCCH4+CBCH) */
7298 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007299 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007300 dt := f_est_dchan('23'O, i, '00010203040506'O);
7301 }
7302
7303 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7304 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7305 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7306 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7307
7308 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7309 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7310
7311 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7312 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7313 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7314 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7315
7316 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7317 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7318 dt.sccp_conn_id := rx_c_ind.connectionId;
7319 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7320
7321 /* Instruct BSC to clear channel */
7322 var BssmapCause cause := 0;
7323 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7324 f_exp_chan_rel_and_clear(dt, 0);
7325
7326 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7327 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7328 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7329 f_sleep(1.0);
7330 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7331
7332 /* clean up config */
7333 f_ts_set_chcomb(0, 0, 6, "PDCH");
7334
7335 f_shutdown_helper();
7336}
7337
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007338/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7339testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7340 var ASP_RSL_Unitdata rsl_ud;
7341 var integer i;
7342 var integer chreq_total, chreq_nochan;
7343
7344 f_init_vty();
7345 for (i := 1; i < 8; i := i + 1) {
7346 if (i == 2) {
7347 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7348 } else {
7349 f_ts_set_chcomb(0, 0, i, "PDCH");
7350 }
7351 }
7352 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7353
7354 f_init(1);
7355
7356 /* The dyn TS want to activate PDCH mode, ACK that. */
7357 var RslChannelNr chan_nr;
7358 chan_nr := valueof(t_RslChanNr_PDCH(2));
7359 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7360 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7361
7362 f_sleep(1.0);
7363
7364 /* Exhaust all dedicated SDCCH lchans.
7365 /* GSM 44.018 Table 9.1.8.2:
7366 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7367 */
7368 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
7369 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7370 }
7371
7372 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
7373 f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7374 /* Also occupy the seven other SDCCH of the dyn TS */
7375 for (i := 0; i < 7; i := i+1) {
7376 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7377 }
7378
7379 /* clean up config */
7380 f_ts_reset_chcomb(0);
7381
7382 f_shutdown_helper();
7383}
7384
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007385/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7386 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7387 it as TCH directly instead. SYS#5309. */
7388testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7389 var RSL_Message rsl_unused, rsl_msg;
7390 var DchanTuple dt;
7391 var BSSAP_N_CONNECT_ind rx_c_ind;
7392 var integer i;
7393
7394 /* change Timeslot 6 before f_init() starts RSL */
7395 f_init_vty();
7396 for (i := 1; i < 8; i := i + 1) {
7397 if (i == 6) {
7398 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7399 } else {
7400 f_ts_set_chcomb(0, 0, i, "PDCH");
7401 }
7402 }
7403 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7404
7405 f_init(1, false);
7406 f_sleep(1.0);
7407
7408 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7409
7410 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7411 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7412 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7413 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7414
7415 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7416 f_sleep(1.0);
7417 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7418 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7419
7420 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7421 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007422 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007423 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007424 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007425 }
7426
7427 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007428 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007429 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7430 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7431
7432 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7433 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7434
7435 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7436 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7437 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7438 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7439
7440 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7441 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7442 dt.sccp_conn_id := rx_c_ind.connectionId;
7443 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7444
7445 /* Instruct BSC to clear channel */
7446 var BssmapCause cause := 0;
7447 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7448 f_exp_chan_rel_and_clear(dt, 0);
7449
7450 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7451 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7452 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7453 f_sleep(1.0);
7454 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7455
7456 /* clean up config */
7457 f_ts_reset_chcomb(0);
7458 /* TODO: clean up other channels? */
7459
7460 f_shutdown_helper();
7461}
7462
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007463/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7464testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7465 var RSL_Message rsl_unused, rsl_msg;
7466 var DchanTuple dt;
7467 var BSSAP_N_CONNECT_ind rx_c_ind;
7468 var GsmRrMessage rr;
7469
7470 /* change Timeslot 6 before f_init() starts RSL */
7471 f_init_vty();
7472 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7473 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7474
7475 f_init(1, false);
7476 f_sleep(1.0);
7477
7478 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7479
7480 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7481 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7482 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7483 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7484
7485 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7486 f_sleep(1.0);
7487 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7488 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7489
7490 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7491 * on CCCH+SDCCH4+CBCH) */
7492 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007493 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007494 dt := f_est_dchan('23'O, i, '00010203040506'O);
7495 }
7496
7497 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7498 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7499 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7500 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7501
7502 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7503 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7504
7505 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7506 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7507 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7508 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7509 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7510 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7511 }
7512
7513 /* FIXME? Currently the TS stays in state BORKEN: */
7514
7515 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7516 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7517 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7518 * f_sleep(1.0);
7519 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7520 */
7521
7522 /* clean up config */
7523 f_ts_set_chcomb(0, 0, 6, "PDCH");
7524
7525 f_shutdown_helper();
7526}
7527
Stefan Sperling0796a822018-10-05 13:01:39 +02007528testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007529 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007530 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7531 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7532 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007533 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007534}
7535
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007536testcase TC_chopped_ipa_payload() runs on test_CT {
7537 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7538 /* TODO: mp_bsc_ctrl_port does not work yet */};
7539 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7540 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7541 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007542 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007543}
7544
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007545/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7546 the BTS does autonomous MS power control loop */
7547testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7548 var MSC_ConnHdlr vc_conn;
7549 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7550 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7551 pars.exp_ms_power_params := true;
7552
7553 f_init(1, true);
7554 f_sleep(1.0);
7555 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7556 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007557 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007558}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007559
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007560/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7561testcase TC_c0_power_red_mode() runs on test_CT {
7562 f_init(1);
7563
7564 for (var integer red := 6; red >= 0; red := red - 2) {
7565 /* Configure BCCH carrier power reduction mode via the VTY */
7566 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7567
7568 /* Expect Osmocom specific BS Power Control message on the RSL */
7569 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7570 chan_nr := t_RslChanNr_BCCH(0),
7571 bs_power := tr_RSL_IE_BS_Power(red / 2));
7572 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7573 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7574
7575 /* Additionally verify the applied value over the CTRL interface */
7576 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7577 if (cred != int2str(red)) {
7578 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7579 cred, " (expected ", red, ")");
7580 }
7581 }
7582
7583 f_shutdown_helper();
7584}
7585
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007586/***********************************************************************
7587 * MSC Pooling
7588 ***********************************************************************/
7589
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007590template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007591 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 +02007592
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007593private 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 +02007594runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007595 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007596 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007597 f_logp(BSCVTY, "Got RSL RR Release");
7598 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007599 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007600 f_logp(BSCVTY, "Got RSL Deact SACCH");
7601 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007602 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007603 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007604 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7605 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007606 break;
7607 }
7608 }
7609}
7610
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007611friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7612 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007613runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007614 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007615 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7616 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007617 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007618 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007619 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007620 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007621 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007622 }
7623 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007624 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007625 /* Also drop the SCCP connection */
7626 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7627 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007628 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007629 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007630 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7631 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007632 }
7633 }
7634}
7635
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007636private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7637 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007638runs on MSC_ConnHdlr {
7639 timer T := 10.0;
7640 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7641
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007642 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007643 f_create_bssmap_exp(l3_enc);
7644
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007645 /* RSL_Emulation.f_chan_est() on rsl_pt:
7646 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007647 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7648 */
7649 var RSL_Message rx_rsl;
7650 var GsmRrMessage rr;
7651
7652 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007653 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007654 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007655 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007656 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7657 */
7658 timer Tt := 10.0;
7659
7660 /* request a channel to be established */
7661 Tt.start;
7662 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007663 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007664 Tt.stop;
7665 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007666 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007667 setverdict(fail, "Unexpected RSL message on DCHAN");
7668 mtc.stop;
7669 }
7670 [] Tt.timeout {
7671 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7672 mtc.stop;
7673 }
7674 }
7675 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7676 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007677 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007678
7679
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007680 if (expect_bssmap_l3) {
7681 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7682 var template PDU_BSSAP exp_l3_compl;
7683 exp_l3_compl := tr_BSSMAP_ComplL3()
7684 if (g_pars.aoip == false) {
7685 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7686 } else {
7687 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7688 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007689
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007690 var PDU_BSSAP bssap;
7691 T.start;
7692 alt {
7693 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7694 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7695 log("rx exp_l3_compl = ", bssap);
7696 }
7697 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7698 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7699 }
7700 [] T.timeout {
7701 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7702 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007703 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007704
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007705 /* start ciphering, if requested */
7706 if (ispresent(g_pars.encr)) {
7707 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007708 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007709 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007710 }
7711
7712 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007713 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007714 }
7715 setverdict(pass);
7716 f_sleep(1.0);
7717}
7718
7719private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7720 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7721 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007722 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007723 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007724 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007725 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007726 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007727 }
7728}
7729
7730/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7731private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7732 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007733 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7734 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7735 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7736 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 +02007737}
7738testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7739
7740 f_init(1, true);
7741 f_sleep(1.0);
7742 var MSC_ConnHdlr vc_conn;
7743 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007744
7745 f_ctrs_msc_init();
7746
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007747 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7748 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007749
7750 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007751 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007752}
7753
7754/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7755/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7756 * just as well using only RSL. */
7757testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7758
7759 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7760 f_sleep(1.0);
7761
7762 /* Control which MSC gets chosen next by the round-robin, otherwise
7763 * would be randomly affected by which other tests ran before this. */
7764 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7765
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007766 f_ctrs_msc_init();
7767
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007768 var MSC_ConnHdlr vc_conn1;
7769 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7770 pars1.mscpool.rsl_idx := 0;
7771 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7772 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7773 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007774 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007775
7776 var MSC_ConnHdlr vc_conn2;
7777 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7778 pars2.mscpool.rsl_idx := 1;
7779 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7780 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7781 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007782 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007783
7784 /* Test round-robin wrap to the first MSC */
7785 var MSC_ConnHdlr vc_conn3;
7786 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7787 pars3.mscpool.rsl_idx := 2;
7788 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7789 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7790 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007791 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007792 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007793}
7794
7795/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7796 * (configured in osmo-bsc.cfg). */
7797/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7798 * just as well using only RSL. */
7799testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7800
7801 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7802 f_sleep(1.0);
7803
7804 /* Control which MSC gets chosen next by the round-robin, otherwise
7805 * would be randomly affected by which other tests ran before this. */
7806 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7807
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007808 f_ctrs_msc_init();
7809
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007810 var MSC_ConnHdlr vc_conn1;
7811 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7812 pars1.mscpool.rsl_idx := 0;
7813 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7814 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7815 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007816 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007817
7818 var MSC_ConnHdlr vc_conn2;
7819 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7820 pars2.mscpool.rsl_idx := 1;
7821 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7822 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7823 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007824 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007825
7826 /* Test round-robin wrap to the first MSC */
7827 var MSC_ConnHdlr vc_conn3;
7828 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7829 pars3.mscpool.rsl_idx := 2;
7830 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7831 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7832 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007833 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007834 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007835}
7836
7837/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7838 * (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
7839 * NULL-NRI setting is stronger than that. */
7840/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7841 * just as well using only RSL. */
7842testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7843
7844 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7845 f_sleep(1.0);
7846
7847 /* Control which MSC gets chosen next by the round-robin, otherwise
7848 * would be randomly affected by which other tests ran before this. */
7849 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7850
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007851 f_ctrs_msc_init();
7852
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007853 var MSC_ConnHdlr vc_conn1;
7854 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7855 pars1.mscpool.rsl_idx := 0;
7856 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7857 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7858 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007859 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007860
7861 var MSC_ConnHdlr vc_conn2;
7862 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7863 pars2.mscpool.rsl_idx := 1;
7864 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7865 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7866 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007867 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007868
7869 /* Test round-robin wrap to the first MSC */
7870 var MSC_ConnHdlr vc_conn3;
7871 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7872 pars3.mscpool.rsl_idx := 2;
7873 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7874 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7875 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007876 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007877 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007878}
7879
7880/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7881 * assigned to any MSC (configured in osmo-bsc.cfg). */
7882/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7883 * just as well using only RSL. */
7884testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7885
7886 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7887 f_sleep(1.0);
7888
7889 /* Control which MSC gets chosen next by the round-robin, otherwise
7890 * would be randomly affected by which other tests ran before this. */
7891 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7892
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007893 f_ctrs_msc_init();
7894
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007895 var MSC_ConnHdlr vc_conn1;
7896 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7897 pars1.mscpool.rsl_idx := 0;
7898 /* An NRI that is not assigned to any MSC */
7899 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7900 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7901 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007902 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007903
7904 var MSC_ConnHdlr vc_conn2;
7905 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7906 pars2.mscpool.rsl_idx := 1;
7907 /* An NRI that is not assigned to any MSC */
7908 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7909 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7910 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007911 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007912
7913 /* Test round-robin wrap to the first MSC */
7914 var MSC_ConnHdlr vc_conn3;
7915 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7916 pars3.mscpool.rsl_idx := 2;
7917 /* An NRI that is not assigned to any MSC */
7918 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7919 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7920 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007921 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007922 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007923}
7924
7925/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7926 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7927/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7928 * just as well using only RSL. */
7929testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7930
7931 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7932 f_sleep(1.0);
7933
7934 /* Control which MSC gets chosen next by the round-robin, otherwise
7935 * would be randomly affected by which other tests ran before this. */
7936 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7937
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007938 f_ctrs_msc_init();
7939
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007940 var MSC_ConnHdlr vc_conn1;
7941 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7942 pars1.mscpool.rsl_idx := 0;
7943 /* An NRI that is assigned to an unconnected MSC */
7944 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7945 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7946 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007947 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7948 f_ctrs_msc_add(0, "mscpool:subscr:new");
7949 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007950
7951 var MSC_ConnHdlr vc_conn2;
7952 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7953 pars2.mscpool.rsl_idx := 1;
7954 /* An NRI that is assigned to an unconnected MSC */
7955 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7956 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7957 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007958 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7959 f_ctrs_msc_add(1, "mscpool:subscr:new");
7960 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007961
7962 /* Test round-robin wrap to the first MSC */
7963 var MSC_ConnHdlr vc_conn3;
7964 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7965 pars3.mscpool.rsl_idx := 2;
7966 /* An NRI that is assigned to an unconnected MSC */
7967 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7968 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7969 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007970 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7971 f_ctrs_msc_add(0, "mscpool:subscr:new");
7972 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007973 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007974}
7975
7976/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7977 * osmo-bsc.cfg). */
7978/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7979 * just as well using only RSL. */
7980testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7981
7982 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7983 f_sleep(1.0);
7984
7985 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7986 * this is not using round-robin. */
7987 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7988
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007989 f_ctrs_msc_init();
7990
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007991 var MSC_ConnHdlr vc_conn1;
7992 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7993 pars1.mscpool.rsl_idx := 0;
7994 /* An NRI of the second MSC's range (256-511) */
7995 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7996 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7997 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007998 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007999
8000 var MSC_ConnHdlr vc_conn2;
8001 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8002 pars2.mscpool.rsl_idx := 1;
8003 /* An NRI of the second MSC's range (256-511) */
8004 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8005 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8006 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008007 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008008
8009 var MSC_ConnHdlr vc_conn3;
8010 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8011 pars3.mscpool.rsl_idx := 2;
8012 /* An NRI of the second MSC's range (256-511) */
8013 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8014 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8015 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008016 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008017 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008018}
8019
8020/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8021 * while a round-robin remains unaffected by that. */
8022/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8023 * just as well using only RSL. */
8024testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8025
8026 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8027 f_sleep(1.0);
8028
8029 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8030 * this is not using round-robin. */
8031 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8032
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008033 f_ctrs_msc_init();
8034
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008035 var MSC_ConnHdlr vc_conn1;
8036 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8037 pars1.mscpool.rsl_idx := 0;
8038 /* An NRI of the third MSC's range (512-767) */
8039 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8040 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8041 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008042 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008043
8044 var MSC_ConnHdlr vc_conn2;
8045 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8046 pars2.mscpool.rsl_idx := 1;
8047 /* An NRI of the third MSC's range (512-767) */
8048 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8049 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8050 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008051 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008052
8053 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8054 var MSC_ConnHdlr vc_conn3;
8055 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8056 pars3.mscpool.rsl_idx := 2;
8057 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8058 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8059 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008060 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008061 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008062}
8063
8064/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8065/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8066 * just as well using only RSL. */
8067testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8068
8069 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8070 f_sleep(1.0);
8071
8072 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8073 * instead, and hits msc 0. */
8074 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8075
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008076 f_ctrs_msc_init();
8077
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008078 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8079 var MSC_ConnHdlr vc_conn1;
8080 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8081 pars1.mscpool.rsl_idx := 0;
8082 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8083 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8084 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008085 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008086
8087 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8088 var MSC_ConnHdlr vc_conn2;
8089 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8090 pars2.mscpool.rsl_idx := 1;
8091 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8092 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8093 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008094 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008095 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008096}
8097
8098/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8099 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8100private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8101 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8102 //cid_list := { cIl_allInBSS := ''O };
8103 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8104 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8105 var BSSAP_N_UNITDATA_req paging;
8106 var hexstring imsi := '001010000000123'H;
8107
8108 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8109
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008110 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008111 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8112 BSSAP.send(paging);
8113
8114 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8115 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8116 * channel number is picked here. */
8117 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8118 f_rslem_register(0, new_chan_nr);
8119 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8120 f_rslem_unregister(0, new_chan_nr);
8121
8122 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8123 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008124 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008125 f_sleep(1.0);
8126}
8127testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8128 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8129 f_sleep(1.0);
8130
8131 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8132 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8133 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8134
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008135 f_ctrs_msc_init();
8136
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008137 var MSC_ConnHdlr vc_conn1;
8138 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8139 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008140 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8141 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008142 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8143 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008144 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008145 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008146}
8147
8148/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8149 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8150private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8151 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8152 //cid_list := { cIl_allInBSS := ''O };
8153 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8154 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8155 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008156 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008157 var BSSAP_N_UNITDATA_req paging;
8158
8159 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8160
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008161 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008162 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8163 BSSAP.send(paging);
8164
8165 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8166 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8167 * channel number is picked here. */
8168 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8169 f_rslem_register(0, new_chan_nr);
8170 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8171 f_rslem_unregister(0, new_chan_nr);
8172
8173 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8174 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8175 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008176 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 +02008177 f_sleep(1.0);
8178}
8179testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8180 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8181 f_sleep(1.0);
8182
8183 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8184 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8185 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8186
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008187 f_ctrs_msc_init();
8188
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008189 var MSC_ConnHdlr vc_conn1;
8190 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8191 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008192 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8193 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008194 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8195 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008196 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008197 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008198}
8199
8200/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8201/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8202 * just as well using only RSL. */
8203testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8204
8205 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8206 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008207 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8208 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008209
8210 /* Control which MSC gets chosen next by the round-robin, otherwise
8211 * would be randomly affected by which other tests ran before this. */
8212 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8213
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008214 f_ctrs_msc_init();
8215
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008216 var MSC_ConnHdlr vc_conn1;
8217 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8218 pars1.mscpool.rsl_idx := 0;
8219 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8220 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8221 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008222 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008223
8224 var MSC_ConnHdlr vc_conn2;
8225 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8226 pars2.mscpool.rsl_idx := 1;
8227 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8228 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8229 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008230 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008231
8232 var MSC_ConnHdlr vc_conn3;
8233 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8234 pars3.mscpool.rsl_idx := 2;
8235 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8236 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8237 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008238 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008239 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008240}
8241
8242/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8243 * TMSI NRI. */
8244testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8245
8246 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8247 f_sleep(1.0);
8248
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008249 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8250 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8251
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008252 /* Control which MSC gets chosen next by the round-robin, otherwise
8253 * would be randomly affected by which other tests ran before this. */
8254 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8255
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008256 f_ctrs_msc_init();
8257
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008258 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8259 var MSC_ConnHdlr vc_conn1;
8260 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8261 pars1.mscpool.rsl_idx := 0;
8262 /* An NRI of the second MSC's range (256-511) */
8263 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8264 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8265 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008266 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008267
8268 var MSC_ConnHdlr vc_conn2;
8269 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8270 pars2.mscpool.rsl_idx := 1;
8271 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8272 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8273 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008274 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008275
8276 var MSC_ConnHdlr vc_conn3;
8277 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8278 pars3.mscpool.rsl_idx := 2;
8279 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8280 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8281 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008282 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008283 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008284}
8285
Philipp Maier783681c2020-07-16 16:47:06 +02008286/* Allow/Deny emergency calls globally via VTY */
8287private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8288 f_vty_enter_cfg_msc(BSCVTY, 0);
8289 if (allow) {
8290 f_vty_transceive(BSCVTY, "allow-emergency allow");
8291 } else {
8292 f_vty_transceive(BSCVTY, "allow-emergency deny");
8293 }
8294 f_vty_transceive(BSCVTY, "exit");
8295 f_vty_transceive(BSCVTY, "exit");
8296}
8297
8298/* Allow/Deny emergency calls per BTS via VTY */
8299private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8300 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8301 if (allow) {
8302 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8303 } else {
8304 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8305 }
8306 f_vty_transceive(BSCVTY, "exit");
8307 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008308 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008309}
8310
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008311/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8312private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8313 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8314 if (allow) {
8315 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8316 } else {
8317 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8318 }
8319 f_vty_transceive(BSCVTY, "exit");
8320 f_vty_transceive(BSCVTY, "exit");
8321 f_vty_transceive(BSCVTY, "exit");
8322}
8323
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008324/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8325private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8326 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8327 if (allow) {
8328 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8329 } else {
8330 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8331 }
8332 f_vty_transceive(BSCVTY, "exit");
8333 f_vty_transceive(BSCVTY, "exit");
8334 f_vty_transceive(BSCVTY, "exit");
8335}
8336
Philipp Maier783681c2020-07-16 16:47:06 +02008337/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8338private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8339 var PDU_ML3_MS_NW emerg_setup;
8340 var octetstring emerg_setup_enc;
8341 var RSL_Message emerg_setup_data_ind;
8342
8343 f_establish_fully(omit, omit);
8344
8345 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8346 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8347 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8348
8349 RSL.send(emerg_setup_data_ind);
8350}
8351
8352/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8353 * CALLS are permitted by the BSC config. */
8354private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8355 var PDU_BSSAP emerg_setup_data_ind_bssap;
8356 var PDU_ML3_MS_NW emerg_setup;
8357 timer T := 3.0;
8358
8359 f_assignment_emerg_setup()
8360
8361 T.start;
8362 alt {
8363 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8364 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8365 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8366 setverdict(fail, "no emergency setup");
8367 }
8368 }
8369 [] BSSAP.receive {
8370 setverdict(fail, "unexpected BSSAP message!");
8371 }
8372 [] T.timeout {
8373 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8374 }
8375 }
8376
8377 setverdict(pass);
8378}
8379
8380/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8381 * forbidden by the BSC config. */
8382private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8383 var PDU_BSSAP emerg_setup_data_ind_bssap;
8384 timer T := 3.0;
8385
8386 f_assignment_emerg_setup()
8387
8388 T.start;
8389 alt {
8390 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8391 setverdict(pass);
8392 }
8393 [] RSL.receive {
8394 setverdict(fail, "unexpected RSL message!");
8395 }
8396 [] T.timeout {
8397 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8398 }
8399 }
8400}
8401
8402/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8403testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8404 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8405 var MSC_ConnHdlr vc_conn;
8406
8407 f_init(1, true);
8408 f_sleep(1.0);
8409
8410 f_vty_allow_emerg_msc(true);
8411 f_vty_allow_emerg_bts(true, 0);
8412 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8413 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008414 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008415}
8416
8417/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8418testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8419 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8420 var MSC_ConnHdlr vc_conn;
8421
8422 f_init(1, true);
8423 f_sleep(1.0);
8424
8425 f_vty_allow_emerg_msc(false);
8426 f_vty_allow_emerg_bts(true, 0);
8427 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8428 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008429 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008430}
8431
8432/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8433testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8434 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8435 var MSC_ConnHdlr vc_conn;
8436
8437 /* Note: This simulates a spec violation by the MS, correct MS
8438 * implementations would not try to establish an emergency call because
8439 * the system information tells in advance that emergency calls are
8440 * not forbidden */
8441
8442 f_init(1, true);
8443 f_sleep(1.0);
8444
8445 f_vty_allow_emerg_msc(true);
8446 f_vty_allow_emerg_bts(false, 0);
8447 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8448 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008449 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008450}
8451
Philipp Maier82812002020-08-13 18:48:27 +02008452/* Test what happens when an emergency call arrives while all TCH channels are
8453 * busy, the BSC is expected to terminate one call in favor of the incoming
8454 * emergency call */
8455testcase TC_emerg_premption() runs on test_CT {
8456 var ASP_RSL_Unitdata rsl_ud;
8457 var integer i;
8458 var integer chreq_total, chreq_nochan;
8459 var RSL_Message rx_rsl;
8460 var RslChannelNr chan_nr;
8461
8462 f_init(1);
8463 f_sleep(1.0);
8464
8465 f_vty_allow_emerg_msc(true);
8466 f_vty_allow_emerg_bts(true, 0);
8467
8468 /* Fill up all channels on the BTS */
8469 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8470 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8471 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8472 chan_nr := f_chreq_act_ack('33'O, i);
8473 }
8474 IPA_RSL[0].clear;
8475 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8476 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8477
8478 /* Send Channel request for emegergency call */
8479 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8480
8481 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8482 chan_nr := valueof(t_RslChanNr_Bm(1));
8483 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8484
8485 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8486 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8487 chan_nr := rx_rsl.ies[0].body.chan_nr;
8488 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8489 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008490
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008491 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008492}
8493
8494/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008495private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008496private type record FHParamsTs {
8497 boolean enabled,
8498 uint6_t hsn,
8499 uint6_t maio,
8500 ArfcnList ma
8501};
8502
8503/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008504private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02008505 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008506 FHParamsTs ts[8]
8507};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008508
8509/* Randomly generate the hopping parameters for the given timeslot numbers */
8510private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8511runs on test_CT return FHParamsTrx {
8512 var FHParamsTrx fhp;
8513
Philipp Maier798d8952021-10-19 14:43:19 +02008514 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
8515 * fall in the GSM900 band. */
8516 fhp.arfcn.arfcn := f_rnd_int(3);
8517 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008518
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008519 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8520 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008521 fhp.ts[tn].enabled := false;
8522 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008523 continue;
8524 }
8525
8526 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008527 fhp.ts[tn].hsn := f_rnd_int(64);
8528 fhp.ts[tn].maio := f_rnd_int(64);
8529 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008530
8531 /* Random Mobile Allocation (hopping channels) */
8532 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8533 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8534 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008535 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008536 }
8537
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008538 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008539 }
8540
8541 log("f_TC_fh_params_gen(): ", fhp);
8542 return fhp;
8543}
8544
8545/* Make sure that the given Channel Description IE matches the hopping configuration */
8546private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8547{
8548 var template (present) ChannelDescription tr_cd;
8549 var template (present) MaioHsn tr_maio_hsn;
8550 var uint3_t tn := cd.chan_nr.tn;
8551
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008552 if (fhp.ts[tn].enabled) {
8553 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008554 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8555 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02008556 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008557 }
8558
8559 if (not match(cd, tr_cd)) {
8560 setverdict(fail, "Channel Description IE does not match: ",
8561 cd, " vs expected ", tr_cd);
8562 }
8563}
8564
8565/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8566private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8567 in MobileAllocationLV ma)
8568{
8569 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8570
8571 if (not match(ma, tr_ma)) {
8572 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8573 tn, "): ", ma, " vs expected: ", tr_ma);
8574 } else {
8575 setverdict(pass);
8576 }
8577}
8578
8579private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8580 in MobileAllocationLV ma)
8581return template MobileAllocationLV {
8582 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008583 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008584 return { len := 0, ma := ''B };
8585 }
8586
8587 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8588 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8589 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008590
8591 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008592 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8593 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8594 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008595 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008596 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008597 }
8598 }
8599
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008600 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02008601 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008602
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008603 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008604 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8605 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008606 }
8607
8608 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008609 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008610 if (full_mask[i] != '1'B)
8611 { continue; }
8612
8613 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8614 if (slot_mask[i] == '1'B) {
8615 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008616 } else {
8617 ma_mask := ma_mask & '0'B;
8618 }
8619 }
8620
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008621 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8622 if (full_mask[0] == '1'B) {
8623 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8624 if (slot_mask[0] == '1'B) {
8625 ma_mask := ma_mask & '1'B;
8626 } else {
8627 ma_mask := ma_mask & '0'B;
8628 }
8629 }
8630
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008631 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008632 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008633 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8634
8635 return { len := ma_mask_len, ma := ma_mask };
8636}
8637
Philipp Maier798d8952021-10-19 14:43:19 +02008638/* Configure the appropriate band for a given arfcn, exc */
8639private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
8640{
8641 var charstring band;
8642 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
8643
8644 select (arfcn_) {
8645 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
8646 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
8647 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
8648 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
8649 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
8650 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
8651 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
8652 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
8653 case else { return; }
8654 }
8655
8656 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8657 f_vty_transceive(BSCVTY, "band " & band);
8658 f_vty_transceive(BSCVTY, "end");
8659}
8660
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008661/* Configure the hopping parameters in accordance with the given record */
8662private function f_TC_fh_params_set(in FHParamsTrx fhp,
8663 uint8_t bts_nr := 0,
8664 uint8_t trx_nr := 0)
8665runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008666
8667 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
8668
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008669 /* Enter the configuration node for the given BTS/TRX numbers */
8670 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8671
Philipp Maier798d8952021-10-19 14:43:19 +02008672 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008673
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008674 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008675 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8676
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008677 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008678 f_vty_transceive(BSCVTY, "hopping enabled 0");
8679 f_vty_transceive(BSCVTY, "exit"); /* go back */
8680 continue;
8681 }
8682
8683 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008684 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8685 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008686
8687 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008688 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8689 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008690 }
8691
8692 f_vty_transceive(BSCVTY, "hopping enabled 1");
8693 f_vty_transceive(BSCVTY, "exit"); /* go back */
8694 }
8695
8696 f_vty_transceive(BSCVTY, "end");
8697}
8698
8699/* Disable frequency hopping on all timeslots */
8700private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8701 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008702 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02008703 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008704runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008705
8706 f_TC_set_band_by_arfcn(bts_nr, arfcn);
8707
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008708 /* Enter the configuration node for the given BTS/TRX numbers */
8709 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8710
Philipp Maier798d8952021-10-19 14:43:19 +02008711 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008712
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008713 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008714 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8715
8716 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008717 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8718 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008719 }
8720
8721 f_vty_transceive(BSCVTY, "hopping enabled 0");
8722 f_vty_transceive(BSCVTY, "exit"); /* go back */
8723 }
8724
8725 f_vty_transceive(BSCVTY, "end");
8726 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8727}
8728
8729/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8730 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8731testcase TC_fh_params_chan_activ() runs on test_CT {
8732 var FHParamsTrx fhp := f_TC_fh_params_gen();
8733 var RSL_Message rsl_msg;
8734 var RSL_IE_Body ie;
8735
8736 f_init_vty();
8737
8738 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8739 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8740
8741 f_init(1);
8742
8743 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8744 for (var integer i := 0; i < 9; i := i + 1) {
8745 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8746 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8747
8748 /* Make sure that Channel Identification IE is present */
8749 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8750 setverdict(fail, "RSL Channel Identification IE is absent");
8751 continue;
8752 }
8753
8754 /* Make sure that hopping parameters (HSN/MAIO) match */
8755 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8756
8757 /* "Mobile Allocation shall be included but empty" - let's check this */
8758 if (ie.chan_ident.ma.v.len != 0) {
8759 setverdict(fail, "Mobile Allocation IE is not empty: ",
8760 ie.chan_ident.ma, ", despite it shall be");
8761 continue;
8762 }
8763 }
8764
8765 /* Disable frequency hopping */
8766 f_TC_fh_params_unset(fhp);
8767
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008768 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008769}
8770
8771/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8772testcase TC_fh_params_imm_ass() runs on test_CT {
8773 var FHParamsTrx fhp := f_TC_fh_params_gen();
8774 var RSL_Message rsl_msg;
8775 var RSL_IE_Body ie;
8776
8777 f_init_vty();
8778
8779 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8780 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8781
8782 f_init(1);
8783
8784 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8785 for (var integer i := 0; i < 9; i := i + 1) {
8786 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8787 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8788
8789 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8790 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8791
8792 /* Make sure that Full Immediate Assign Info IE is present */
8793 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8794 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8795 continue;
8796 }
8797
8798 /* Decode the actual Immediate Assignment message */
8799 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8800 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8801 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8802 continue;
8803 }
8804
8805 /* Make sure that hopping parameters (HSN/MAIO) match */
8806 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8807
8808 /* Make sure that the Mobile Allocation IE matches */
8809 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8810 rr_msg.payload.imm_ass.mobile_allocation);
8811 }
8812
8813 /* Disable frequency hopping */
8814 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008815
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008816 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008817}
8818
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008819/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8820testcase TC_fh_params_assignment_cmd() runs on test_CT {
8821 var FHParamsTrx fhp := f_TC_fh_params_gen();
8822 var RSL_Message rsl_msg;
8823 var RSL_IE_Body ie;
8824
8825 f_init_vty();
8826
8827 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8828 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8829
8830 f_init(1);
8831
8832 /* HACK: work around "Couldn't find Expect for CRCX" */
8833 vc_MGCP.stop;
8834
8835 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8836 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8837
8838 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8839 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8840 for (var integer i := 0; i < 3; i := i + 1) {
8841 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8842 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8843
8844 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8845 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8846 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8847
8848 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8849 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8850 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8851
8852 /* Make sure that L3 Information IE is present */
8853 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8854 setverdict(fail, "RSL L3 Information IE is absent");
8855 continue;
8856 }
8857
8858 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8859 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8860 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8861 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8862 continue;
8863 }
8864
8865 /* Make sure that hopping parameters (HSN/MAIO) match */
8866 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8867 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8868
8869 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8870 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008871 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008872 continue;
8873 }
8874
8875 /* Make sure that the Mobile Allocation IE matches (if present) */
8876 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8877 if (chan_desc.h and ma_present) {
8878 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8879 l3_msg.payload.ass_cmd.mobile_allocation.v);
8880 } else if (chan_desc.h and not ma_present) {
8881 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8882 continue;
8883 } else if (not chan_desc.h and ma_present) {
8884 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8885 continue;
8886 }
8887 }
8888
8889 /* Give the IUT some time to release all channels */
8890 f_sleep(3.0);
8891
8892 /* Disable frequency hopping */
8893 f_TC_fh_params_unset(fhp);
8894
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008895 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008896}
8897
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008898/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8899private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8900runs on test_CT {
8901 var RSL_Message rsl_msg;
8902 var RSL_IE_Body ie;
8903 var DchanTuple dt;
8904
8905 /* Establish a dedicated channel, so we can trigger handover */
8906 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03008907 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008908
8909 /* Trigger handover from BTS0 to BTS1 */
8910 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8911 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8912
8913 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8914 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8915
8916 /* ACKnowledge channel activation and expect (RR) Handover Command */
8917 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8918 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8919
8920 /* Make sure that L3 Information IE is present */
8921 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8922 setverdict(fail, "RSL L3 Information IE is absent");
8923 return;
8924 }
8925
8926 /* Decode the L3 message and make sure it is (RR) Handover Command */
8927 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8928 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8929 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8930 return;
8931 }
8932
8933 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8934 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8935 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8936 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8937 return;
8938 }
8939
8940 /* Make sure that hopping parameters (HSN/MAIO) match */
8941 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8942
8943 /* Make sure that Cell Channel Description IE is present */
8944 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8945 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8946 return;
8947 }
8948
8949 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8950 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8951 if (ma_present) {
8952 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8953 l3_msg.payload.ho_cmd.mobile_allocation.v);
8954 } else {
8955 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8956 return;
8957 }
8958}
8959testcase TC_fh_params_handover_cmd() runs on test_CT {
8960 var FHParamsTrx fhp := f_TC_fh_params_gen();
8961
8962 f_init_vty();
8963
8964 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8965 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8966
8967 f_vty_transceive(BSCVTY, "timeslot 0");
8968 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8969 f_vty_transceive(BSCVTY, "exit"); /* go back */
8970
8971 f_vty_transceive(BSCVTY, "timeslot 1");
8972 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8973 f_vty_transceive(BSCVTY, "end"); /* we're done */
8974
8975 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8976 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8977
8978 f_init(2);
8979
8980 f_TC_fh_params_handover_cmd(fhp);
8981
8982 /* Disable frequency hopping on BTS1 */
8983 f_TC_fh_params_unset(fhp, 1);
8984
8985 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8986 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8987
8988 f_vty_transceive(BSCVTY, "timeslot 0");
8989 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8990 f_vty_transceive(BSCVTY, "exit"); /* go back */
8991
8992 f_vty_transceive(BSCVTY, "timeslot 1");
8993 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8994 f_vty_transceive(BSCVTY, "end"); /* we're done */
8995
8996 f_shutdown_helper();
8997}
8998
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008999/* Verify the hopping parameters in System Information Type 4 */
9000testcase TC_fh_params_si4_cbch() runs on test_CT {
9001 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9002 var ASP_RSL_Unitdata rx_rsl_ud;
9003 timer T := 5.0;
9004
9005 f_init_vty();
9006
9007 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9008 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9009
9010 f_vty_transceive(BSCVTY, "timeslot 0");
9011 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9012 f_vty_transceive(BSCVTY, "exit"); /* go back */
9013
9014 f_vty_transceive(BSCVTY, "timeslot 1");
9015 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9016 f_vty_transceive(BSCVTY, "end"); /* we're done */
9017
9018 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9019 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9020
9021 f_init(1);
9022
9023 T.start;
9024 alt {
9025 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
9026 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9027 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9028
9029 /* Make sure that what we decoded is System Information Type 4 */
9030 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9031 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9032 repeat;
9033 }
9034
9035 /* Make sure that CBCH Channel Description IE is present */
9036 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9037 setverdict(fail, "CBCH Channel Description IE is absent");
9038 break;
9039 }
9040
9041 /* Finally, check the hopping parameters (HSN, MAIO) */
9042 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9043 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9044
9045 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9046 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9047 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9048 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9049 break;
9050 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9051 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9052 si.payload.si4.cbch_mobile_alloc.v);
9053 }
9054 }
9055 [] IPA_RSL[0].receive { repeat; }
9056 [] T.timeout {
9057 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9058 }
9059 }
9060
9061 /* Disable frequency hopping */
9062 f_TC_fh_params_unset(fhp);
9063
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009064 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009065 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9066
9067 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009068 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009069 f_vty_transceive(BSCVTY, "exit"); /* go back */
9070
9071 f_vty_transceive(BSCVTY, "timeslot 1");
9072 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9073 f_vty_transceive(BSCVTY, "end"); /* we're done */
9074
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009075 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009076}
9077
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009078template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9079 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9080
9081private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9082 template (present) BSSLAP_PDU expect_bsslap)
9083{
9084 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9085 if (not match(bsslap, expect_bsslap)) {
9086 log("EXPECTING BSSLAP: ", expect_bsslap);
9087 log("GOT BSSLAP: ", bsslap);
9088 setverdict(fail, "BSSLAP is not as expected");
9089 mtc.stop;
9090 }
9091 setverdict(pass);
9092}
9093
9094/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9095const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9096
9097private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9098 var PDU_BSSAP_LE rx_bsslap;
9099 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9100 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9101}
9102
9103/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9104 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9105private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9106 f_sleep(1.0);
9107
9108 f_establish_fully(omit, omit);
9109 f_bssap_le_register_imsi(g_pars.imsi, omit);
9110
9111 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9112 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9113
9114 var PDU_BSSAP_LE plr;
9115 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9116
9117 if (not do_ta_request) {
9118 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9119 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9120 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9121 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9122 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9123 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9124 mtc.stop;
9125 }
9126 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9127 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9128 if (not match(bsslap, expect_ta_layer3)) {
9129 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9130 log("GOT BSSLAP: ", bsslap);
9131 setverdict(fail, "BSSLAP is not as expected");
9132 mtc.stop;
9133 }
9134 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9135 * has no need to request the TA from the BSC and directly responds. */
9136 } else {
9137 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9138 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9139 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9140 }
9141
9142 /* SMLC got the TA from the BSC, now responds with geo information data. */
9143 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9144 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9145 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9146
9147 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9148 f_mo_l3_transceive();
9149
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009150 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009151
9152 f_sleep(2.0);
9153 setverdict(pass);
9154}
9155
9156/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9157 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9158private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9159 f_lcs_loc_req_for_active_ms(false);
9160}
9161testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9162 var MSC_ConnHdlr vc_conn;
9163 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9164
9165 f_init(1, true);
9166 f_sleep(1.0);
9167 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9168 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009169 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009170}
9171
9172/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9173 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9174private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9175 f_lcs_loc_req_for_active_ms(true);
9176}
9177testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9178 var MSC_ConnHdlr vc_conn;
9179 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9180
9181 f_init(1, true);
9182 f_sleep(1.0);
9183 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9184 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009185 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009186}
9187
9188/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9189 * conn without an active lchan. */
9190private function f_clear_A_conn() runs on MSC_ConnHdlr
9191{
9192 var BssmapCause cause := 0;
9193 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9194 BSSAP.receive(tr_BSSMAP_ClearComplete);
9195 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9196
9197 timer no_more_bssap := 5.0;
9198 no_more_bssap.start;
9199 alt {
9200 [] no_more_bssap.timeout { break; }
9201 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9202 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9203 mtc.stop;
9204 }
9205 }
9206 setverdict(pass);
9207}
9208
9209/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9210 * for LCS, for cases where there is only an A conn without an active lchan. */
9211private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9212{
9213 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9214
9215 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9216 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9217 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9218 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9219 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9220 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9221
9222 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9223 f_clear_A_conn();
9224 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9225 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9226}
9227
9228/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9229 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9230 */
9231private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9232 f_sleep(1.0);
9233
9234 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9235 f_bssap_le_register_imsi(g_pars.imsi, omit);
9236
9237 /* Register to receive the Paging Command */
9238 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9239 g_chan_nr := new_chan_nr;
9240 f_rslem_register(0, g_chan_nr);
9241
9242 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9243 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9244 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9245 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9246
9247 var PDU_BSSAP_LE plr;
9248 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9249
9250 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9251 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9252
9253 /* OsmoBSC needs to Page */
9254 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9255 f_logp(BSCVTY, "got Paging Command");
9256
9257 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9258 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009259 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);
9260 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009261
9262 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9263
9264 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9265
9266 /* SMLC got the TA from the BSC, now responds with geo information data. */
9267 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9268 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9269
9270 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9271
9272 /* The lchan is gone, the A-interface conn was created for the LCS only.
9273 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9274 f_verify_active_A_conn_and_clear();
9275
9276 f_sleep(2.0);
9277 setverdict(pass);
9278}
9279testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9280 var MSC_ConnHdlr vc_conn;
9281 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9282
9283 f_init(1, true);
9284 f_sleep(1.0);
9285
9286 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9287 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9288
9289 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9290 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009291 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009292}
9293
9294/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9295 */
9296private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9297 f_sleep(1.0);
9298
9299 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9300 f_bssap_le_register_imsi(g_pars.imsi, omit);
9301
9302 /* provoke an abort by omitting both IMSI and IMEI */
9303 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9304 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9305 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9306 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9307
9308 /* BSC tells MSC about failure */
9309 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9310 locationEstimate := omit, positioningData := omit,
9311 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9312
9313 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9314 f_verify_active_A_conn_and_clear();
9315
9316 f_sleep(2.0);
9317 setverdict(pass);
9318}
9319testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9320 var MSC_ConnHdlr vc_conn;
9321 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9322
9323 f_init(1, true);
9324 f_sleep(1.0);
9325
9326 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9327 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9328
9329 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9330 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009331 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009332}
9333
9334/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9335 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9336private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9337 f_sleep(1.0);
9338
9339 f_establish_fully(omit, omit);
9340 f_bssap_le_register_imsi(g_pars.imsi, omit);
9341
9342 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9343 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9344
9345 var PDU_BSSAP_LE plr;
9346 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9347
9348 if (do_ta) {
9349 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9350 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9351 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9352 }
9353
9354 /* SMLC fails to respond, BSC runs into timeout */
9355 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9356 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9357
9358 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9359 locationEstimate := omit, positioningData := omit,
9360 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9361
9362 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9363 f_verify_active_A_conn_and_clear();
9364
9365 f_sleep(2.0);
9366 setverdict(pass);
9367}
9368
9369/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9370 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9371private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9372 f_lcs_loc_req_for_active_ms_le_timeout(false);
9373}
9374
9375testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9376 var MSC_ConnHdlr vc_conn;
9377 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9378
9379 f_init(1, true);
9380 f_sleep(1.0);
9381 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9382 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009383 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009384}
9385
9386/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9387 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9388private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9389 f_lcs_loc_req_for_active_ms_le_timeout(true);
9390}
9391
9392testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9393 var MSC_ConnHdlr vc_conn;
9394 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9395
9396 f_init(1, true);
9397 f_sleep(1.0);
9398 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9399 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009400 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009401}
9402
9403/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9404private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9405 f_sleep(1.0);
9406
9407 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9408 f_bssap_le_register_imsi(g_pars.imsi, omit);
9409
9410 /* Register to receive the Paging Command */
9411 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9412 g_chan_nr := new_chan_nr;
9413 f_rslem_register(0, g_chan_nr);
9414
9415 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9416 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9417 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9418 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9419
9420 var PDU_BSSAP_LE plr;
9421 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9422
9423 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9424 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9425
9426 /* OsmoBSC needs to Page */
9427 var PDU_BSSAP_LE rx_bsslap;
9428 alt {
9429 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9430 f_logp(BSCVTY, "got Paging Command");
9431 repeat;
9432 }
9433 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9434 /* MS does not respond to Paging, TA Req runs into timeout. */
9435 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9436 }
9437 }
9438
9439 /* SMLC responds with failure */
9440 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9441 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9442
9443 /* BSC tells MSC about failure */
9444 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9445 locationEstimate := omit, positioningData := omit,
9446 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9447
9448 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9449 f_verify_active_A_conn_and_clear();
9450
9451 f_sleep(2.0);
9452 setverdict(pass);
9453}
9454testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9455 var MSC_ConnHdlr vc_conn;
9456 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9457
9458 f_init(1, true);
9459 f_sleep(1.0);
9460
9461 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9462 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9463
9464 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9465 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009466 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009467}
9468
9469/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9470 * over. */
9471private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9472 f_sleep(1.0);
9473
9474 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9475 f_bssap_le_register_imsi(g_pars.imsi, omit);
9476
9477 /* Register to receive the Paging Command */
9478 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9479 g_chan_nr := new_chan_nr;
9480 f_rslem_register(0, g_chan_nr);
9481
9482 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9483 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9484 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9485 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9486
9487 var PDU_BSSAP_LE plr;
9488 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9489
9490 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9491 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009492 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 +02009493 do_clear := false, expect_bssmap_l3 := true);
9494
9495 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9496 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9497
9498 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9499 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9500
9501 /* SMLC got the TA from the BSC, now responds with geo information data. */
9502 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9503 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9504 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9505
9506 /* The lchan should still exist, it was from a CM Service Request. */
9507 f_mo_l3_transceive();
9508
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009509 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009510
9511 f_sleep(2.0);
9512 setverdict(pass);
9513}
9514testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9515 var MSC_ConnHdlr vc_conn;
9516 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9517
9518 f_init(1, true);
9519 f_sleep(1.0);
9520
9521 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9522 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9523
9524 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9525 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009526 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009527}
9528
9529/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9530 * the new lchan after handover. */
9531private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9532 f_sleep(1.0);
9533
9534 f_establish_fully(omit, omit);
9535 f_bssap_le_register_imsi(g_pars.imsi, omit);
9536
9537 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9538 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9539
9540 var PDU_BSSAP_LE plr;
9541 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9542
9543 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9544 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9545
9546 var HandoverState hs := {
9547 rr_ho_cmpl_seen := false,
9548 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02009549 old_chan_nr := -,
9550 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009551 };
9552 /* issue hand-over command on VTY */
9553 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9554 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9555 f_rslem_suspend(RSL1_PROC);
9556
9557 /* From the MGW perspective, a handover is is characterized by
9558 * performing one MDCX operation with the MGW. So we expect to see
9559 * one more MDCX during handover. */
9560 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9561
9562 alt {
9563 [] as_handover(hs);
9564 }
9565
9566 var PDU_BSSAP_LE rx_bsslap;
9567
9568 interleave {
9569 /* Expect the BSC to inform the MSC about the handover */
9570 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9571
9572 /* Expect the BSC to inform the SMLC about the handover */
9573 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9574 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9575 }
9576 }
9577
9578 /* SMLC now responds with geo information data. */
9579 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9580 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9581 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9582
9583 /* lchan still active */
9584 f_mo_l3_transceive(RSL1);
9585
9586 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009587 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009588
9589 f_sleep(2.0);
9590 setverdict(pass);
9591}
9592testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9593 var MSC_ConnHdlr vc_conn;
9594 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9595
9596 f_init(2, true);
9597 f_sleep(1.0);
9598 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9599 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009600 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009601}
9602
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009603/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9604private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9605 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9606
9607 /* Also disable attach for the single connected MSC */
9608 f_vty_msc_allow_attach(BSCVTY, { false });
9609
9610 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) ));
9611 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9612
9613 /* No MSC is found, expecting a proper release on RSL */
9614 interleave {
9615 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9616 f_logp(BSCVTY, "Got RSL RR Release");
9617 }
9618 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9619 f_logp(BSCVTY, "Got RSL Deact SACCH");
9620 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009621 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009622 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9623 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009624 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009625 }
9626 }
9627 setverdict(pass);
9628}
9629testcase TC_no_msc() runs on test_CT {
9630
9631 f_init(1, true);
9632 f_sleep(1.0);
9633 var MSC_ConnHdlr vc_conn;
9634 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9635
9636 f_ctrs_bsc_init(counternames_bsc_mscpool);
9637
9638 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9639 vc_conn.done;
9640
9641 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9642 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009643 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009644}
9645
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009646/* Dyn PDCH todo:
9647 * activate OSMO as TCH/F
9648 * activate OSMO as TCH/H
9649 * does the BSC-located PCU socket get the updated INFO?
9650 * what if no PCU is connected at the time?
9651 * is the info correct on delayed PCU (re)connect?
9652 */
Harald Welte94e0c342018-04-07 11:33:23 +02009653
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009654private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9655 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9656 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9657
9658 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9659 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9660 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9661 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9662 g_pars.ass_codec_list.codecElements[0];
9663 if (isvalue(g_pars.expect_mr_s0_s7)) {
9664 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9665 g_pars.expect_mr_s0_s7;
9666 }
9667 }
9668 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9669 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9670 log("expecting ASS COMPL like this: ", exp_compl);
9671
9672 f_establish_fully(ass_cmd, exp_compl);
9673
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009674 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 +00009675
9676 var RSL_Message rsl;
9677
9678 timer T := 5.0;
9679 T.start;
9680 alt {
9681 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9682 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9683 log("Rx L3 from net: ", l3);
9684 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9685 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9686 mtc.stop;
9687 }
9688 }
9689 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9690 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9691 mtc.stop;
9692 }
9693 [] T.timeout {
9694 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9695 setverdict(pass);
9696 }
9697 }
9698 T.stop;
9699}
9700
9701/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9702 * osmo-bsc. */
9703testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9704 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9705 var MSC_ConnHdlr vc_conn;
9706
9707 f_init(1, true);
9708 f_sleep(1.0);
9709
9710 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9711 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9712 vc_conn.done;
9713 f_shutdown_helper();
9714}
9715
9716/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9717 */
9718testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9719 f_init_vty();
9720
9721 f_init(1, false);
9722 f_sleep(1.0);
9723
9724 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9725
9726 var ASP_RSL_Unitdata rx_rsl_ud;
9727 timer T := 5.0;
9728
9729 T.start;
9730 alt {
9731 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9732 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9733 T.stop;
9734 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9735 mtc.stop;
9736 }
9737 repeat;
9738 }
9739 [] T.timeout {
9740 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9741 setverdict(pass);
9742 }
9743 }
9744}
9745
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009746private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9747 /* First fully set up a speech lchan */
9748 f_TC_assignment_codec(id);
9749
9750 /* Trigger re-assignment to another lchan */
9751 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9752
9753 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9754 * one MDCX on MGCP. */
9755 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9756
9757 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9758 * as the old lchan used. */
9759 g_media.bts.ipa_crcx_seen := false;
9760 g_media.bts.ipa_mdcx_seen := false;
9761
9762 /* Send different BTS side RTP port number for the new lchan */
9763 g_media.bts.bts.port_nr := 4223;
9764
9765 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9766
9767 /* Trigger re-assignment. */
9768 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9769
9770 timer T := 5.0;
9771 T.start;
9772 alt {
9773 [] as_assignment(assignment_st);
9774 [] as_Media();
9775 [] T.timeout {
9776 break;
9777 }
9778 }
9779
9780 if (not assignment_st.assignment_done) {
9781 setverdict(fail, "Assignment did not complete");
9782 mtc.stop;
9783 }
9784
9785 f_check_mgcp_expectations()
9786 setverdict(pass);
9787
9788 f_sleep(2.0);
9789 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9790
9791 /* Instruct BSC to clear channel */
9792 var BssmapCause cause := 0;
9793 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9794 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009795 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9796 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009797 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009798 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009799 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009800 }
9801 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9802 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9803 }
9804 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +02009805 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009806
9807 f_sleep(0.5);
9808}
9809
9810testcase TC_reassignment_fr() runs on test_CT {
9811 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9812 var MSC_ConnHdlr vc_conn;
9813
9814 f_init(1, true);
9815 f_sleep(1.0);
9816
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01009817 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009818
9819 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9820 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9821 vc_conn.done;
9822
9823 /* from f_establish_fully() */
9824 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9825 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9826 /* from re-assignment */
9827 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9828 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9829 f_ctrs_bsc_and_bts_verify();
9830 f_shutdown_helper();
9831}
9832
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009833const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9834const charstring REEST_CLEAR := "REEST_CLEAR";
9835const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9836
9837/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9838 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9839 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9840 * the MSC as the CM Re-Establishment is handled.
9841 *
9842 * MS bts0 bts1 bsc msc test-component
9843 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9844 * | | _1 wait a bit, to settle down
9845 * |<-x x--| | _1 "lose connection"
9846 * | | REEST_LOST_CONNECTION
9847 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9848 * | | REEST_CLEAR
9849 * | |<-0---| _1 Clear Command on first A-conn
9850 * | |--0-->| _1 Clear Complete
9851 * | |<----------------->| | _1 Release first channel
9852 * | | REEST_CLEAR_DONE
9853 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9854 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9855 *
9856 */
9857private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9858 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9859 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9860
9861 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9862 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9863
9864 f_establish_fully(ass_cmd, exp_compl);
9865
9866 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9867 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9868 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9869 f_sleep(2.0);
9870 COORD.send(REEST_LOST_CONNECTION);
9871
9872 alt {
9873 [] COORD.receive(REEST_CLEAR);
9874 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9875 setverdict(fail, "Unexpected channel release");
9876 mtc.stop;
9877 }
9878 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9879 setverdict(fail, "Unexpected channel release");
9880 mtc.stop;
9881 }
9882 }
9883 f_perform_clear()
9884 f_expect_dlcx_conns();
Neels Hofmeyr969abd02021-09-23 22:24:08 +02009885 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009886 COORD.send(REEST_CLEAR_DONE);
9887}
9888
9889private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9890 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9891
9892 /* The MS lost the connection on the first channel, now establishes another one */
9893 COORD.receive(REEST_LOST_CONNECTION);
9894
9895 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9896 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9897 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9898
9899 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009900 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 +02009901 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9902
9903 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9904 COORD.send(REEST_CLEAR);
9905 COORD.receive(REEST_CLEAR_DONE);
9906
9907 f_sleep(2.0);
9908
9909 /* Answer the CM Re-Establishment with an Assignment Command. */
9910 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9911 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9912 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9913 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9914
9915 var AssignmentState st := valueof(ts_AssignmentStateInit);
9916 st.voice_call := true;
9917 st.is_assignment := true;
9918
9919 var ExpectCriteria mgcpcrit := {
9920 connid := omit,
9921 endpoint := omit,
9922 transid := omit
9923 };
9924 f_create_mgcp_expect(mgcpcrit);
9925
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009926 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009927
9928 BSSAP.send(ass_cmd);
9929
9930 var PDU_BSSAP bssap;
9931
9932 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009933 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9934 [] as_Media_ipacc(RSL1, RSL2);
9935 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009936 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9937 break;
9938 }
9939 }
9940
9941 f_sleep(3.0);
9942
9943 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009944 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009945 f_expect_dlcx_conns();
9946}
9947
9948testcase TC_cm_reestablishment() runs on test_CT {
9949 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9950 var MSC_ConnHdlr vc_conn1;
9951
9952 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9953 var MSC_ConnHdlr vc_conn2;
9954 pars2.imsi := pars1.imsi;
9955 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +02009956 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009957
9958 f_init(2, true, guard_timeout := 40.0);
9959 f_sleep(1.0);
9960
9961 vc_conn1 := f_start_handler_create(pars1);
9962 vc_conn2 := f_start_handler_create(pars2);
9963 connect(vc_conn1:COORD, vc_conn2:COORD);
9964 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9965 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9966 vc_conn1.done;
9967 vc_conn2.done;
9968
9969 f_shutdown_helper();
9970}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009971
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009972function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9973 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9974runs on test_CT return template (omit) RSL_Message {
9975 var ASP_RSL_Unitdata rx_rsl_ud;
9976 timer T := t_secs;
9977
9978 T.start;
9979 alt {
9980 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9981 T.stop;
9982 }
9983 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9984 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9985 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9986 T.stop;
9987 return omit;
9988 }
9989 [] T.timeout {
9990 return omit;
9991 }
9992 }
9993 return rx_rsl_ud.rsl;
9994}
9995
9996private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9997 f_vty_enter_cfg_bts(pt, bts_nr);
9998 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9999 f_vty_transceive(pt, "exit");
10000 f_vty_transceive(pt, "exit");
10001 f_vty_transceive(pt, "exit");
10002}
10003
10004private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010005 template RslChannelNr chan_nr := ?,
10006 template (present) uint12_t arfcn := ?,
10007 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010008{
10009 var RSL_IE_Body full_imm_ass_info;
10010 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10011 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10012 mtc.stop;
10013 }
10014
10015 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10016 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10017 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010018 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010019 page_mode := ?);
10020 if (not match(rr_imm_ass, expect_imm_ass)) {
10021 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10022 setverdict(fail, "Failed to match Immediate Assignment");
10023 mtc.stop;
10024 }
10025}
10026
10027testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10028 var RSL_Message chan_act;
10029 var RSL_Message imm_ass;
10030
10031 f_init(1, false);
10032 f_sleep(1.0);
10033
10034 /* (should be the default anyway, just to make things clear) */
10035 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10036
10037 /* RA containing reason=LU */
10038 var GsmFrameNumber fn := 2342;
10039 var uint8_t ra := 2;
10040 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10041
10042 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10043
10044 /* First send the Chan Act ACK */
10045 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010046 var RSL_IE_Body chan_ident_ie;
10047 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10048 setverdict(fail, "RSL Channel Identification IE is absent");
10049 mtc.stop;
10050 }
10051
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010052 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
10053
10054 /* Then expect the Immediate Assignment, after we ACKed the chan act */
10055 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10056
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010057 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10058 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010059
10060 /* Check that the lchan is working */
10061 var octetstring l3 := '00010203040506'O;
10062 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10063
10064 var BSSAP_N_CONNECT_ind rx_c_ind;
10065 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10066 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10067
10068 f_sleep(1.0);
10069 f_shutdown_helper();
10070}
10071
10072testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10073 var RSL_Message chan_act;
10074 var RSL_Message imm_ass;
10075
10076 f_init(1, false);
10077 f_sleep(1.0);
10078
10079 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10080
10081 /* RA containing reason=LU */
10082 var GsmFrameNumber fn := 2342;
10083 var uint8_t ra := 2;
10084 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10085
10086 /* (set bts 0 cfg back to default) */
10087 f_vty_set_imm_ass(BSCVTY);
10088
10089 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10090 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010091 var RSL_IE_Body chan_ident_ie;
10092 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10093 setverdict(fail, "RSL Channel Identification IE is absent");
10094 mtc.stop;
10095 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010096
10097 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10098 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010099 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10100 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010101
10102 /* Only now send the Chan Act ACK */
10103 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10104
10105 /* Check that the lchan is working */
10106 var octetstring l3 := '00010203040506'O;
10107 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10108
10109 var BSSAP_N_CONNECT_ind rx_c_ind;
10110 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10111 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10112
10113 f_sleep(1.0);
10114 f_shutdown_helper();
10115}
10116
Neels Hofmeyr23158742021-09-07 19:08:07 +020010117testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10118 var RSL_Message chan_act;
10119 var RSL_Message imm_ass;
10120
10121 f_init(1, false);
10122 f_sleep(1.0);
10123
10124 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10125
10126 /* RA containing reason=LU */
10127 var GsmFrameNumber fn := 2342;
10128 var uint8_t ra := 2;
10129 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10130
10131 /* (set bts 0 cfg back to default) */
10132 f_vty_set_imm_ass(BSCVTY);
10133
10134 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10135 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
10136 var RSL_IE_Body chan_ident_ie;
10137 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10138 setverdict(fail, "RSL Channel Identification IE is absent");
10139 mtc.stop;
10140 }
10141
10142 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10143 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10144 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10145 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10146
10147 /* Only now send the Chan Act ACK */
10148 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10149
10150 /* Check that the lchan is working */
10151 var octetstring l3 := '00010203040506'O;
10152 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10153
10154 var BSSAP_N_CONNECT_ind rx_c_ind;
10155 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10156 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10157
10158 f_sleep(1.0);
10159 f_shutdown_helper();
10160}
10161
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010162testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10163 /* change Timeslot 6 before f_init() starts RSL */
10164 f_init_vty();
10165 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10166 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10167
10168 f_init(1, false);
10169 f_sleep(1.0);
10170
10171 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10172 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10173 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10174 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10175
10176 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10177 f_ts_set_chcomb(0, 0, 6, "PDCH");
10178
10179 /* block all static timeslots so that the dyn TS will be used */
10180 f_disable_all_tch_f();
10181 f_disable_all_tch_h();
10182 f_disable_all_sdcch();
10183
10184 var RSL_Message chan_act;
10185 var RSL_Message imm_ass;
10186
10187 f_init(1, false);
10188 f_sleep(1.0);
10189
10190 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10191
10192 /* RA containing reason=LU */
10193 var GsmFrameNumber fn := 2342;
10194 var uint8_t ra := 2;
10195 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10196
10197 /* (set bts 0 cfg back to default) */
10198 f_vty_set_imm_ass(BSCVTY);
10199
10200 /* Expect the dyn TS to deactivate PDCH first */
10201 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10202 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10203
10204 /* Now activation as SDCCH8 */
10205 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10206
10207 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010208 var RSL_IE_Body chan_ident_ie;
10209 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10210 setverdict(fail, "RSL Channel Identification IE is absent");
10211 mtc.stop;
10212 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010213
10214 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10215 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010216 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10217 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010218
10219 /* Only now send the Chan Act ACK */
10220 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10221
10222 /* Check that the lchan is working */
10223 var octetstring l3 := '00010203040506'O;
10224 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10225
10226 var BSSAP_N_CONNECT_ind rx_c_ind;
10227 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10228 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10229
10230 f_sleep(1.0);
10231 f_shutdown_helper();
10232}
10233
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010234testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10235 /* change Timeslot 6 before f_init() starts RSL */
10236 f_init_vty();
10237 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10238 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10239
10240 f_init(1, false);
10241 f_sleep(1.0);
10242
10243 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10244 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10245 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10246 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10247
10248 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10249 f_ts_set_chcomb(0, 0, 6, "PDCH");
10250
10251 /* block all static timeslots so that the dyn TS will be used */
10252 f_disable_all_tch_f();
10253 f_disable_all_tch_h();
10254 f_disable_all_sdcch();
10255
10256 var RSL_Message chan_act;
10257 var RSL_Message imm_ass;
10258
10259 f_init(1, false);
10260 f_sleep(1.0);
10261
10262 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10263
10264 /* RA containing reason=LU */
10265 var GsmFrameNumber fn := 2342;
10266 var uint8_t ra := 2;
10267 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10268
10269 /* (set bts 0 cfg back to default) */
10270 f_vty_set_imm_ass(BSCVTY);
10271
10272 /* Expect the dyn TS to deactivate PDCH first */
10273 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10274
10275 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10276 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10277
10278 /* continue the Osmo style PDCH Deact (usual chan rel) */
10279 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10280
10281 /* Now activation as SDCCH8 */
10282 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10283
10284 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010285 var RSL_IE_Body chan_ident_ie;
10286 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10287 setverdict(fail, "RSL Channel Identification IE is absent");
10288 mtc.stop;
10289 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010290 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10291
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010292 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10293 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010294
10295 /* Check that the lchan is working */
10296 var octetstring l3 := '00010203040506'O;
10297 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10298
10299 var BSSAP_N_CONNECT_ind rx_c_ind;
10300 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10301 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10302
10303 f_sleep(1.0);
10304 f_shutdown_helper();
10305}
10306
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010307/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10308testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10309 var MSC_ConnHdlr vc_conn;
10310
10311 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10312 f_sleep(1.0);
10313
10314 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10315 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10316 "0,0,operational,unlocked,on,rsl-up;" &
10317 "1,0,operational,unlocked,on,rsl-up;" &
10318 "2,0,operational,unlocked,on,rsl-down;" &
10319 "3,0,inoperational,locked,on,rsl-down;");
10320
10321 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10322 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10323 /* give it a moment to settle the FSM status */
10324 f_sleep(1.0);
10325
10326 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10327 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10328 * of "off"? But that's for a future patch if at all. */
10329 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10330 "0,0,operational,unlocked,on,rsl-up;" &
10331 "1,0,operational,locked,on,rsl-up;" &
10332 "2,0,operational,unlocked,on,rsl-down;" &
10333 "3,0,inoperational,locked,on,rsl-down;");
10334
10335 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10336 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10337 f_sleep(1.0);
10338 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10339 "0,0,operational,unlocked,on,rsl-up;" &
10340 "1,0,operational,locked,on,rsl-up;" &
10341 "2,0,operational,unlocked,on,rsl-down;" &
10342 "3,0,inoperational,locked,on,rsl-down;");
10343
10344 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10345 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10346 f_sleep(1.0);
10347 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10348 "0,0,operational,unlocked,on,rsl-up;" &
10349 "1,0,operational,unlocked,on,rsl-up;" &
10350 "2,0,operational,unlocked,on,rsl-down;" &
10351 "3,0,inoperational,locked,on,rsl-down;");
10352
10353 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10354 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10355 f_sleep(1.0);
10356 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10357 "0,0,operational,unlocked,on,rsl-up;" &
10358 "1,0,operational,unlocked,on,rsl-up;" &
10359 "2,0,operational,unlocked,on,rsl-down;" &
10360 "3,0,inoperational,locked,on,rsl-down;");
10361
10362 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10363 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10364 f_sleep(1.0);
10365 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10366 "0,0,operational,unlocked,on,rsl-up;" &
10367 "1,0,operational,unlocked,on,rsl-up;" &
10368 "2,0,operational,unlocked,on,rsl-down;" &
10369 "3,0,inoperational,locked,on,rsl-down;");
10370
10371 f_shutdown_helper();
10372}
10373
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010374const CounterNameVals counternames_cm_serv_rej := {
10375 { "cm_serv_rej", 0 },
10376 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
10377 { "cm_serv_rej:illegal_ms", 0 },
10378 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
10379 { "cm_serv_rej:imei_not_accepted", 0 },
10380 { "cm_serv_rej:illegal_me", 0 },
10381 { "cm_serv_rej:plmn_not_allowed", 0 },
10382 { "cm_serv_rej:loc_not_allowed", 0 },
10383 { "cm_serv_rej:roaming_not_allowed", 0 },
10384 { "cm_serv_rej:network_failure", 0 },
10385 { "cm_serv_rej:synch_failure", 0 },
10386 { "cm_serv_rej:congestion", 0 },
10387 { "cm_serv_rej:srv_opt_not_supported", 0 },
10388 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
10389 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
10390 { "cm_serv_rej:call_can_not_be_identified", 0 },
10391 { "cm_serv_rej:incorrect_message", 0 },
10392 { "cm_serv_rej:invalid_mandantory_inf", 0 },
10393 { "cm_serv_rej:msg_type_not_implemented", 0 },
10394 { "cm_serv_rej:msg_type_not_compatible", 0 },
10395 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
10396 { "cm_serv_rej:condtional_ie_error", 0 },
10397 { "cm_serv_rej:msg_not_compatible", 0 },
10398 { "cm_serv_rej:protocol_error", 0 },
10399 { "cm_serv_rej:retry_in_new_cell", 0 }
10400};
10401
10402private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
10403{
10404 f_create_chan_and_exp();
10405 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010406 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010407}
10408testcase TC_cm_serv_rej() runs on test_CT {
10409 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10410 var MSC_ConnHdlr vc_conn;
10411
10412 f_init(1, true);
10413 f_sleep(1.0);
10414
10415 f_ctrs_bts_init(1, counternames_cm_serv_rej);
10416
10417 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
10418 vc_conn.done;
10419
10420 f_ctrs_bts_add(0, "cm_serv_rej", 1);
10421 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
10422 f_ctrs_bts_verify();
10423
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010424 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010425 f_shutdown_helper();
10426}
10427
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010428/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10429 * Activ Ack (SYS#5627). */
10430private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10431 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030010432
10433 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10434 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010435
10436 var BSSMAP_FIELD_CodecType codecType;
10437 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
10438
10439 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
10440
10441 /* First establish a signalling lchan */
10442 f_create_chan_and_exp();
10443 f_rslem_dchan_queue_enable();
10444
10445 /* we should now have a COMPL_L3 at the MSC */
10446 var template PDU_BSSAP exp_l3_compl;
10447 exp_l3_compl := tr_BSSMAP_ComplL3()
10448 if (g_pars.aoip == false) {
10449 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
10450 } else {
10451 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
10452 }
10453 timer T := 10.0;
10454 T.start;
10455 alt {
10456 [] BSSAP.receive(exp_l3_compl);
10457 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
10458 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
10459 }
10460 [] T.timeout {
10461 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
10462 }
10463 }
10464
10465 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
10466 activate(as_Media_mgw());
10467
10468 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
10469 f_rslem_register(0, chan_nr);
10470
10471 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
10472 BSSAP.send(ass_cmd);
10473
10474
10475 /* Wait for the Channel Activ for the TCH channel */
10476 var ASP_RSL_Unitdata rx_rsl_ud;
10477 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
10478
10479 /* make the original SDCCH disappear */
10480 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10481
10482 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
10483 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
10484
10485 interleave {
10486 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
10487 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
10488 }
10489
10490 BSSAP.send(ts_BSSMAP_ClearCommand(0));
10491 BSSAP.receive(tr_BSSMAP_ClearComplete);
10492 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10493
10494 var MgcpCommand mgcp;
10495 MGCP.receive(tr_DLCX()) -> value mgcp {
10496 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
10497 };
10498
10499 f_sleep(0.5);
10500}
10501testcase TC_lost_sdcch_during_assignment() runs on test_CT {
10502 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10503 var MSC_ConnHdlr vc_conn;
10504
10505 f_init(1, true);
10506 f_sleep(1.0);
10507
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010508 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
10509 vc_conn.done;
10510
10511 f_shutdown_helper();
10512}
10513
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010514const CounterNameVals counternames_bsc_bts_all_available_allocated := {
10515 { "all_allocated:sdcch", 0 },
10516 { "all_allocated:static_sdcch", 0 },
10517 { "all_allocated:tch", 0 },
10518 { "all_allocated:static_tch", 0 }
10519}
10520
10521private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
10522{
10523 /* Make sure counters settle first */
10524 f_sleep(1.0);
10525
10526 /* Take a baseline of counters */
10527 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
10528
10529 /* Elapse some time so that we see changes in counters, hopefully where expected */
10530 f_sleep(2.0);
10531
10532 /* Get new counters */
10533 var charstring_list all_changed := {};
10534 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
10535 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
10536
10537 /* Compare with expectations */
10538 var charstring_list all_expect_changed := {};
10539 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
10540 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
10541 }
10542 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
10543}
10544
10545testcase TC_ratectr_all_available_allocated() runs on test_CT {
10546 var ASP_RSL_Unitdata rsl_ud;
10547 var integer i;
10548 var integer chreq_total, chreq_nochan;
10549
10550 f_init(1);
10551 f_sleep(1.0);
10552
10553 /* Exhaust all dedicated SDCCH lchans.
10554 /* GSM 44.018 Table 9.1.8.2:
10555 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10556 */
10557 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10558 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10559 }
10560
10561 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
10562 * level.
10563 * All SDCCH are now occupied. */
10564 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10565
10566 /* Also fill up all remaining (TCH) channels */
10567 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
10568 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10569 }
10570
10571 /* All TCH are now also occupied */
10572 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10573 "all_allocated:tch", "all_allocated:static_tch"});
10574
10575 f_shutdown_helper();
10576}
10577
10578testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
10579 var ASP_RSL_Unitdata rsl_ud;
10580 var integer i;
10581 var integer chreq_total, chreq_nochan;
10582
10583 f_init_vty();
10584 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
10585 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10586 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
10587
10588 f_init(1, guard_timeout := 60.0);
10589 f_sleep(1.0);
10590
10591 /* The dyn TS wants to activate PDCH mode, ACK that. */
10592 var RslChannelNr chan_nr;
10593 chan_nr := valueof(t_RslChanNr_PDCH(2));
10594 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10595 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10596
10597 /* Exhaust all dedicated SDCCH lchans.
10598 /* GSM 44.018 Table 9.1.8.2:
10599 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10600 */
10601 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10602 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10603 }
10604
10605 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
10606 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
10607 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
10608
10609 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
10610 * Will release them later, so remember all the DchanTuples. */
10611 var DchanTuples dyn_sddch := {};
10612 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10613
10614 /* Also occupy the seven other SDCCH of the dyn TS */
10615 for (i := 0; i < 7; i := i+1) {
10616 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10617 }
10618
10619 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
10620 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10621
10622 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
10623 for (i := 0; i < 5; i := i+1) {
10624 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10625 }
10626
10627 /* All TCH lchans are now also occupied, both static and dynamic */
10628 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10629 "all_allocated:tch", "all_allocated:static_tch"});
10630
10631 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
10632 * incrementing. */
10633 var BssmapCause cause := 0;
10634 var DchanTuple dt := dyn_sddch[0];
10635 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10636 f_exp_chan_rel_and_clear(dt, 0);
10637
10638 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
10639 * count as occupied, so those still both increment. */
10640 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
10641 "all_allocated:tch", "all_allocated:static_tch"});
10642
10643 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
10644 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
10645 dt := dyn_sddch[i];
10646 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10647 f_exp_chan_rel_and_clear(dt, 0);
10648 }
10649
10650 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
10651 chan_nr := valueof(t_RslChanNr_PDCH(2));
10652 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10653 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10654
10655 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
10656 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
10657
10658 /* clean up config */
10659 f_ts_reset_chcomb(0);
10660
10661 f_shutdown_helper();
10662}
10663
Harald Welte28d943e2017-11-25 15:00:50 +010010664control {
Harald Welte898113b2018-01-31 18:32:21 +010010665 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010666 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010667 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020010668 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
10669 * these in the AoIP test suite. */
10670 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10671 execute( TC_stat_num_msc_connected_1() );
10672 execute( TC_stat_num_msc_connected_2() );
10673 execute( TC_stat_num_msc_connected_3() );
10674 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020010675 execute( TC_stat_num_bts_connected_1() );
10676 execute( TC_stat_num_bts_connected_2() );
10677 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010678 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010679 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010680 execute( TC_ctrl_location() );
10681 }
Harald Welte898113b2018-01-31 18:32:21 +010010682
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010683 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010684 execute( TC_si2quater_2_earfcns() );
10685 execute( TC_si2quater_3_earfcns() );
10686 execute( TC_si2quater_4_earfcns() );
10687 execute( TC_si2quater_5_earfcns() );
10688 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010689 execute( TC_si2quater_12_earfcns() );
10690 execute( TC_si2quater_23_earfcns() );
10691 execute( TC_si2quater_32_earfcns() );
10692 execute( TC_si2quater_33_earfcns() );
10693 execute( TC_si2quater_42_earfcns() );
10694 execute( TC_si2quater_48_earfcns() );
10695 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010696 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010697 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010698
Harald Welte898113b2018-01-31 18:32:21 +010010699 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010700 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010701 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010702 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010703 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010704 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010705 execute( TC_chan_act_ack_est_ind_noreply() );
10706 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010707 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010708 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010709 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010710 execute( TC_chan_rel_rll_rel_ind() );
10711 execute( TC_chan_rel_conn_fail() );
10712 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010713 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10714 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010715 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010716 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010717 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010718 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010719 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010720 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010721
Harald Weltecfe2c962017-12-15 12:09:32 +010010722 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010723
10724 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010725 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010726 execute( TC_assignment_csd() );
10727 execute( TC_assignment_ctm() );
10728 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010729 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10730 execute( TC_assignment_aoip_tla_v6() );
10731 }
Harald Welte235ebf12017-12-15 14:18:16 +010010732 execute( TC_assignment_fr_a5_0() );
10733 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010734 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010735 execute( TC_assignment_fr_a5_1_codec_missing() );
10736 }
Harald Welte235ebf12017-12-15 14:18:16 +010010737 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010738 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010739 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010740 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010741 execute( TC_ciph_mode_a5_0() );
10742 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010743 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010744 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010745 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010746 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010747
Harald Welte60aa5762018-03-21 19:33:13 +010010748 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010749 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010750 execute( TC_assignment_codec_hr() );
10751 execute( TC_assignment_codec_efr() );
10752 execute( TC_assignment_codec_amr_f() );
10753 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010754
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010755 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010756 execute( TC_assignment_codec_amr_f_S1() );
10757 execute( TC_assignment_codec_amr_h_S1() );
10758 execute( TC_assignment_codec_amr_f_S124() );
10759 execute( TC_assignment_codec_amr_h_S124() );
10760 execute( TC_assignment_codec_amr_f_S0() );
10761 execute( TC_assignment_codec_amr_f_S02() );
10762 execute( TC_assignment_codec_amr_f_S024() );
10763 execute( TC_assignment_codec_amr_f_S0247() );
10764 execute( TC_assignment_codec_amr_h_S0() );
10765 execute( TC_assignment_codec_amr_h_S02() );
10766 execute( TC_assignment_codec_amr_h_S024() );
10767 execute( TC_assignment_codec_amr_h_S0247() );
10768 execute( TC_assignment_codec_amr_f_S01234567() );
10769 execute( TC_assignment_codec_amr_f_S0234567() );
10770 execute( TC_assignment_codec_amr_f_zero() );
10771 execute( TC_assignment_codec_amr_f_unsupp() );
10772 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010773 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10774 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010775 execute( TC_assignment_codec_amr_f_start_mode_4() );
10776 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010777 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010778 }
Harald Welte60aa5762018-03-21 19:33:13 +010010779
Philipp Maierac09bfc2019-01-08 13:41:39 +010010780 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10781 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10782 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10783 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10784 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10785 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10786 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10787 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10788 execute( TC_assignment_codec_req_hr_fr() );
10789 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010790 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10791 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10792 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010793
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010794 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010795
Harald Welte898113b2018-01-31 18:32:21 +010010796 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010797 execute( TC_rll_est_ind_inact_lchan() );
10798 execute( TC_rll_est_ind_inval_sapi1() );
10799 execute( TC_rll_est_ind_inval_sapi3() );
10800 execute( TC_rll_est_ind_inval_sacch() );
10801
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010802 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10803 execute( TC_tch_dlci_link_id_sapi() );
10804
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010805 /* SAPI N Reject triggered by RLL establishment failures */
10806 execute( TC_rll_rel_ind_sapi_n_reject() );
10807 execute( TC_rll_err_ind_sapi_n_reject() );
10808 execute( TC_rll_timeout_sapi_n_reject() );
10809
Harald Welte898113b2018-01-31 18:32:21 +010010810 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010811 execute( TC_paging_imsi_nochan() );
10812 execute( TC_paging_tmsi_nochan() );
10813 execute( TC_paging_tmsi_any() );
10814 execute( TC_paging_tmsi_sdcch() );
10815 execute( TC_paging_tmsi_tch_f() );
10816 execute( TC_paging_tmsi_tch_hf() );
10817 execute( TC_paging_imsi_nochan_cgi() );
10818 execute( TC_paging_imsi_nochan_lac_ci() );
10819 execute( TC_paging_imsi_nochan_ci() );
10820 execute( TC_paging_imsi_nochan_lai() );
10821 execute( TC_paging_imsi_nochan_lac() );
10822 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010823 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10824 execute( TC_paging_imsi_nochan_rnc() );
10825 execute( TC_paging_imsi_nochan_lac_rnc() );
10826 execute( TC_paging_imsi_nochan_lacs() );
10827 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010828 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010829 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010830 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010831 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010832 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010833
10834 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010835 execute( TC_rsl_unknown_unit_id() );
10836
10837 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010838
10839 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010840 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010841 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010842 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010843 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010844 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010845 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010846
Harald Welte261af4b2018-02-12 21:20:39 +010010847 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010848 execute( TC_ho_int_a5_0() );
10849 execute( TC_ho_int_a5_1() );
10850 execute( TC_ho_int_a5_3() );
10851 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010852 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010853
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010010854 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010855 execute( TC_ho_out_fail_no_msc_response() );
10856 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010857 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010858
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010859 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010860 execute( TC_ho_into_this_bsc_a5_0() );
10861 execute( TC_ho_into_this_bsc_a5_1() );
10862 execute( TC_ho_into_this_bsc_a5_3() );
10863 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010864 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10865 execute( TC_ho_into_this_bsc_tla_v6() );
10866 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010867 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010868 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010869 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10870 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010871 execute( TC_ho_in_fail_msc_clears() );
10872 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10873 execute( TC_ho_in_fail_no_detect() );
10874 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010875
Neels Hofmeyr91401012019-07-11 00:42:35 +020010876 execute( TC_ho_neighbor_config_1() );
10877 execute( TC_ho_neighbor_config_2() );
10878 execute( TC_ho_neighbor_config_3() );
10879 execute( TC_ho_neighbor_config_4() );
10880 execute( TC_ho_neighbor_config_5() );
10881 execute( TC_ho_neighbor_config_6() );
10882 execute( TC_ho_neighbor_config_7() );
10883
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010884 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010885 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010886 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010887
10888 execute( TC_dyn_pdch_ipa_act_deact() );
10889 execute( TC_dyn_pdch_ipa_act_nack() );
10890 execute( TC_dyn_pdch_osmo_act_deact() );
10891 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010010892 execute( TC_dyn_ts_sdcch8_act_deact() );
10893 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
10894 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
10895 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010896
Stefan Sperling0796a822018-10-05 13:01:39 +020010897 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010898 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010899
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010900 /* Power control related */
10901 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010902 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010903
10904 /* MSC pooling */
10905 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10906 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10907 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10908 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10909 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10910 execute( TC_mscpool_L3Compl_on_1_msc() );
10911 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10912 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10913 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10914 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10915 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10916 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10917 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10918 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10919 execute( TC_mscpool_paging_and_response_imsi() );
10920 execute( TC_mscpool_paging_and_response_tmsi() );
10921 execute( TC_mscpool_no_allow_attach_round_robin() );
10922 execute( TC_mscpool_no_allow_attach_valid_nri() );
10923 }
10924
Harald Welte99f3ca02018-06-14 13:40:29 +020010925 execute( TC_early_conn_fail() );
10926 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010927 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010928
Philipp Maier783681c2020-07-16 16:47:06 +020010929 /* Emergency call handling (deny / allow) */
10930 execute( TC_assignment_emerg_setup_allow() );
10931 execute( TC_assignment_emerg_setup_deny_msc() );
10932 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010933 execute( TC_emerg_premption() );
10934
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010935 /* Frequency hopping parameters handling */
10936 execute( TC_fh_params_chan_activ() );
10937 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010938 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010939 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010940 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010941
10942 if (mp_enable_lcs_tests) {
10943 execute( TC_lcs_loc_req_for_active_ms() );
10944 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10945 execute( TC_lcs_loc_req_for_idle_ms() );
10946 execute( TC_lcs_loc_req_no_subscriber() );
10947 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10948 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10949 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10950 execute( TC_cm_service_during_lcs_loc_req() );
10951 execute( TC_ho_during_lcs_loc_req() );
10952 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010953
10954 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010955
10956 execute( TC_refuse_chan_act_to_vamos() );
10957 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010958
10959 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010960
10961 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010962
10963 execute( TC_imm_ass_post_chan_ack() );
10964 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010965 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010966 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010967 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010968
10969 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010970
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010971 execute( TC_ratectr_all_available_allocated() );
10972 execute( TC_ratectr_all_available_allocated_dyn() );
10973
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010974 execute( TC_cm_serv_rej() );
10975
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010976 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010010977
10978 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
10979 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
10980 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010010981}
10982
10983}