blob: ad8f666b54800f07a3341732f3bf7d4e9d9cbac5 [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 Hofmeyr5e686dc2020-06-30 01:26:53 +0200173/* Set of all System Information received during one RSL port's startup.
174 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
175 * broadcast that SI type. That will be reflected as 'omit' here.
176 */
177type record SystemInformationConfig {
178 SystemInformationType1 si1 optional,
179 SystemInformationType2 si2 optional,
180 SystemInformationType2bis si2bis optional,
181 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200182 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200183 SystemInformationType3 si3 optional,
184 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100185 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200186 SystemInformationType5 si5 optional,
187 SystemInformationType5bis si5bis optional,
188 SystemInformationType5ter si5ter optional,
189 SystemInformationType6 si6 optional
190};
191
192const SystemInformationConfig SystemInformationConfig_omit := {
193 si1 := omit,
194 si2 := omit,
195 si2bis := omit,
196 si2ter := omit,
197 si2quater := omit,
198 si3 := omit,
199 si4 := omit,
200 si13 := omit,
201 si5 := omit,
202 si5bis := omit,
203 si5ter := omit,
204 si6 := omit
205};
206
207/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
208template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
209 template uint3_t meas_bw := 3)
210:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
211 meas_bw_presence := '1'B,
212 meas_bw := meas_bw);
213
214/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200215template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200216 template uint3_t prio := 3,
217 template (present) uint5_t thresh_high := 20,
218 template uint5_t thresh_low := 10,
219 template uint5_t qrxlevmin := 22)
220:= tr_EUTRAN_NeighbourCells(
221 cell_desc_list := cell_desc_list,
222 prio_presence := '1'B,
223 prio := prio,
224 thresh_high := thresh_high,
225 thresh_low_presence := '1'B,
226 thresh_low := thresh_low,
227 qrxlevmin_presence := '1'B,
228 qrxlevmin := qrxlevmin);
229
230template SystemInformationConfig SystemInformationConfig_default := {
231 si1 := {
232 cell_chan_desc := '8FB38000000000000000000000000000'O,
233 rach_control := {
234 max_retrans := RACH_MAX_RETRANS_7,
235 tx_integer := '1001'B,
236 cell_barr_access := false,
237 re_not_allowed := true,
238 acc := '0000010000000000'B
239 },
240 rest_octets := ?
241 },
242 si2 := {
243 bcch_freq_list := '00000000000000000000000000000000'O,
244 ncc_permitted := '11111111'B,
245 rach_control := {
246 max_retrans := RACH_MAX_RETRANS_7,
247 tx_integer := '1001'B,
248 cell_barr_access := false,
249 re_not_allowed := true,
250 acc := '0000010000000000'B
251 }
252 },
253 si2bis := omit,
254 si2ter := {
255 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
256 rest_octets := ?
257 },
258 si2quater := {
259 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
260 },
261 si3 := {
262 cell_id := 0,
263 lai := {
264 mcc_mnc := '001F01'H,
265 lac := 1
266 },
267 ctrl_chan_desc := {
268 msc_r99 := true,
269 att := true,
270 bs_ag_blks_res := 1,
271 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
272 si22ind := false,
273 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
274 spare := '00'B,
275 bs_pa_mfrms := 3,
276 t3212 := 30
277 },
278 cell_options := {
279 dn_ind := false,
280 pwrc := false,
281 dtx := MS_SHALL_USE_UL_DTX,
282 radio_link_tout_div4 := 7
283 },
284 cell_sel_par := {
285 cell_resel_hyst_2dB := 2,
286 ms_txpwr_max_cch := 7,
287 acs := '0'B,
288 neci := true,
289 rxlev_access_min := 0
290 },
291 rach_control := {
292 max_retrans := RACH_MAX_RETRANS_7,
293 tx_integer := '1001'B,
294 cell_barr_access := false,
295 re_not_allowed := true,
296 acc := '0000010000000000'B
297 },
298 rest_octets := {
299 sel_params := {
300 presence := '0'B,
301 params := omit
302 },
303 pwr_offset := {
304 presence := '0'B,
305 offset := omit
306 },
307 si_2ter_ind := '1'B,
308 early_cm_ind := '0'B,
309 sched_where := {
310 presence := '0'B,
311 where := omit
312 },
313 gprs_ind := {
314 presence := '1'B,
315 ind := {
316 ra_colour := 0,
317 si13_pos := '0'B
318 }
319 },
320 umts_early_cm_ind := '1'B,
321 si2_quater_ind := {
322 presence := '1'B,
323 ind := '0'B
324 },
325 iu_mode_ind := omit,
326 si21_ind := {
327 presence := '0'B,
328 pos := omit
329 }
330 }
331 },
332 si4 := {
333 lai := {
334 mcc_mnc := '001F01'H,
335 lac := 1
336 },
337 cell_sel_par := {
338 cell_resel_hyst_2dB := 2,
339 ms_txpwr_max_cch := 7,
340 acs := '0'B,
341 neci := true,
342 rxlev_access_min := 0
343 },
344 rach_control := {
345 max_retrans := RACH_MAX_RETRANS_7,
346 tx_integer := '1001'B,
347 cell_barr_access := false,
348 re_not_allowed := true,
349 acc := '0000010000000000'B
350 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200351 cbch_chan_desc := {
352 iei := '64'O,
353 v := {
354 chan_nr := {
355 u := {
356 sdcch4 := {
357 tag := '001'B,
358 sub_chan := 2
359 }
360 },
361 tn := 0
362 },
363 tsc := 2,
364 h := false,
365 arfcn := 871,
366 maio_hsn := omit
367 }
368 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200369 cbch_mobile_alloc := omit,
370 rest_octets := {
371 sel_params := {
372 presence := '0'B,
373 params := omit
374 },
375 pwr_offset := {
376 presence := '0'B,
377 offset := omit
378 },
379 gprs_ind := {
380 presence := '1'B,
381 ind := {
382 ra_colour := 0,
383 si13_pos := '0'B
384 }
385 },
386 s_presence := '0'B,
387 s := omit
388 }
389 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100390 si13 := {
391 rest_octets := {
392 presence := '1'B,
393 bcch_change_mark := ?,
394 si_change_field := '0000'B,
395 presence2 := '0'B,
396 si13_change_mark := omit,
397 gprs_ma := omit,
398 zero := '0'B, /* PBCCH not present in cell */
399 rac := 0,
400 spgc_ccch_sup := '0'B,
401 priority_access_thr := '110'B,
402 network_control_order := '00'B,
403 gprs_cell_opts := {
404 nmo := '01'B,
405 t3168 := '011'B,
406 t3192 := '010'B,
407 drx_timer_max := '011'B,
408 access_burst_type := '0'B,
409 control_ack_type := '1'B,
410 bs_cv_max := 15,
411 pan_presence := '1'B,
412 pan_dec := 1,
413 pan_inc := 1,
414 pan_max := '111'B,
415 ext_info_presence := ?,
416 ext_info_length := *,
417 ext_info := *
418 },
419 gprs_pwr_ctrl_params := {
420 alpha := 0,
421 t_avg_w := '10000'B,
422 t_avg_t := '10000'B,
423 pc_meas_chan := '0'B,
424 n_avg_i := '1000'B
425 }
426 }
427 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200428 si5 := {
429 bcch_freq_list := '10000000000000000000000000000000'O
430 },
431 si5bis := omit,
432 si5ter := {
433 extd_bcch_freq_list := '9E050020000000000000000000000000'O
434 },
435 si6 := {
436 cell_id := 0,
437 lai := {
438 mcc_mnc := '001F01'H,
439 lac := 1
440 },
441 cell_options := {
442 dtx_ext := '1'B,
443 pwrc := false,
444 dtx := '01'B,
445 radio_link_timeout := '0111'B
446 },
447 ncc_permitted := '11111111'B,
448 rest_octets := ?
449 }
450 };
451
452
453/* List of all the System Information received on all RSL ports */
454type record of SystemInformationConfig SystemInformationConfig_list;
455
456function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
457{
458 var RSL_IE_Body sysinfo_type_ie;
459 var RSL_IE_SysinfoType si_type;
460 var octetstring data;
461
462 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
463 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
464 mtc.stop;
465 }
466 si_type := sysinfo_type_ie.sysinfo_type;
467
468 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
469 var RSL_IE_Body bcch_ie;
470 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
471 data := bcch_ie.other.payload;
472 }
473 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
474 var RSL_IE_Body l3_ie;
475 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
476 data := l3_ie.l3_info.payload;
477 }
478 } else {
479 setverdict(fail, "Don't understand this System Information message");
480 mtc.stop;
481 }
482
483 var boolean handled := false;
484
485 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
486 handled := true;
487
488 if (si_type == RSL_SYSTEM_INFO_1) {
489 if (not isbound(data)) {
490 si.si1 := omit;
491 } else {
492 si.si1 := dec_SystemInformation(data).payload.si1;
493 }
494 } else if (si_type == RSL_SYSTEM_INFO_2) {
495 if (not isbound(data)) {
496 si.si2 := omit;
497 } else {
498 si.si2 := dec_SystemInformation(data).payload.si2;
499 }
500 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
501 if (not isbound(data)) {
502 si.si2bis := omit;
503 } else {
504 si.si2bis := dec_SystemInformation(data).payload.si2bis;
505 }
506 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
507 if (not isbound(data)) {
508 si.si2ter := omit;
509 } else {
510 si.si2ter := dec_SystemInformation(data).payload.si2ter;
511 }
512 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
513 if (not isbound(data)) {
514 si.si2quater := {};
515 } else {
516 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
517 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
518 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
519 }
520 } else if (si_type == RSL_SYSTEM_INFO_3) {
521 if (not isbound(data)) {
522 si.si3 := omit;
523 } else {
524 si.si3 := dec_SystemInformation(data).payload.si3;
525 }
526 } else if (si_type == RSL_SYSTEM_INFO_4) {
527 if (not isbound(data)) {
528 si.si4 := omit;
529 } else {
530 si.si4 := dec_SystemInformation(data).payload.si4;
531 }
532 } else if (si_type == RSL_SYSTEM_INFO_13) {
533 if (not isbound(data)) {
534 si.si13 := omit;
535 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100536 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200537 }
538 } else {
539 handled := false;
540 }
541 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
542 handled := true;
543
544 if (si_type == RSL_SYSTEM_INFO_5) {
545 if (not isbound(data)) {
546 si.si5 := omit;
547 } else {
548 si.si5 := dec_SystemInformation(data).payload.si5;
549 }
550 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
551 if (not isbound(data)) {
552 si.si5bis := omit;
553 } else {
554 si.si5bis := dec_SystemInformation(data).payload.si5bis;
555 }
556 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
557 if (not isbound(data)) {
558 si.si5ter := omit;
559 } else {
560 si.si5ter := dec_SystemInformation(data).payload.si5ter;
561 }
562 } else if (si_type == RSL_SYSTEM_INFO_6) {
563 if (not isbound(data)) {
564 si.si6 := omit;
565 } else {
566 si.si6 := dec_SystemInformation(data).payload.si6;
567 }
568 } else {
569 handled := false;
570 }
571 }
572
573 if (not handled) {
574 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
575 }
576}
577
Harald Weltea4ca4462018-02-09 00:17:14 +0100578type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100579 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100580 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100581 /* RSL common Channel Port (for RSL_Emulation) */
582 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100583 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100584 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100585 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200586 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
587 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100588
Daniel Willmann191e0d92018-01-17 12:44:35 +0100589 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100590 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100591
Daniel Willmannebdecc02020-08-12 15:30:17 +0200592 /* StatsD */
593 var StatsD_Checker_CT vc_STATSD;
594
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200595 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200596 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100597 /* for old legacy-tests only */
598 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200599 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100600
Harald Welte21b46bd2017-12-17 19:46:32 +0100601 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100602 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100603
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200604 /* Osmux is enabled through VTY */
605 var boolean g_osmux_enabled := false;
606
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100607 /*Configure T(tias) over VTY, seconds */
608 var integer g_bsc_sccp_timer_ias := 7 * 60;
609 /*Configure T(tiar) over VTY, seconds */
610 var integer g_bsc_sccp_timer_iar := 15 * 60;
611
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200612 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100613 timer T_guard := 30.0;
614
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200615 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000616 var CounterNameValsList g_ctr_bsc;
617 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200618
619 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
620 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100621}
622
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200623type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100624modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100625 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100626 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100627 /* port number to which to establish the IPA OML connections */
628 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100629 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100630 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100631 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100632 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200633 /* port number to which to listen for STATSD metrics */
634 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100635 /* IP address at which the test binds */
636 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100637
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200638 RAN_Configurations mp_bssap_cfg := {
639 {
640 transport := BSSAP_TRANSPORT_AoIP,
641 sccp_service_type := "mtp3_itu",
642 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
643 own_pc := 185, /* 0.23.1 first MSC emulation */
644 own_ssn := 254,
645 peer_pc := 187, /* 0.23.3 osmo-bsc */
646 peer_ssn := 254,
647 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200648 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200649 },
650 {
651 transport := BSSAP_TRANSPORT_AoIP,
652 sccp_service_type := "mtp3_itu",
653 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
654 own_pc := 2, /* 0.0.2 second MSC emulation */
655 own_ssn := 254,
656 peer_pc := 187, /* 0.23.3 osmo-bsc */
657 peer_ssn := 254,
658 sio := '83'O,
659 rctx := 2
660 },
661 {
662 transport := BSSAP_TRANSPORT_AoIP,
663 sccp_service_type := "mtp3_itu",
664 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
665 own_pc := 3, /* 0.0.3 third MSC emulation */
666 own_ssn := 254,
667 peer_pc := 187, /* 0.23.3 osmo-bsc */
668 peer_ssn := 254,
669 sio := '83'O,
670 rctx := 3
671 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100672 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200673
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200674 /* Must match per BTS config in osmo-bsc.cfg */
675 phys_chan_configs phys_chan_config := {
676 "CCCH+SDCCH4+CBCH",
677 "TCH/F",
678 "TCH/F",
679 "TCH/F",
680 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600681 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200682 "PDCH",
683 "PDCH"
684 };
685
Harald Welte47cd0e32020-08-21 12:39:11 +0200686 BSSAP_LE_Configuration mp_bssap_le_cfg := {
687 sccp_service_type := "mtp3_itu",
688 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200689 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200690 own_ssn := 252, /* SMLC side SSN */
691 peer_pc := 187, /* 0.23.3 osmo-bsc */
692 peer_ssn := 250, /* BSC side SSN */
693 sio := '83'O,
694 rctx := 6
695 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200696 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200697
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +0200698 /* Whether to enable dyn TS SDCCH8 tests. Can be dropped completely and enable
699 unconditionally once new version of osmo-bsc is released (current
700 version: 1.7.0) */
701 boolean mp_enable_dyn_sdcch8_test := true;
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100702 /* Value set in osmo-bsc.cfg "ms max power" */
703 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100704}
705
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200706friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200707
708 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200709 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200710 pars.aoip := true;
711 } else {
712 pars.aoip := false;
713 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100714 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200715 pars.mscpool.bssap_idx := bssap_idx;
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200716 pars.expect_tsc := BTS_TSC[0];
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200717
Philipp Maier48604732018-10-09 15:00:37 +0200718 return pars;
719}
720
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200721/* Convenience functions for rate counters using g_ctr_msc. */
722
723private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
724 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
725 log("initial msc rate counters: ", g_ctr_msc);
726}
727
728private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200729 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200730}
731
732/* f_ctrs_msc_init();
733 * f_do_thing(on_msc := 0);
734 * f_do_thing(on_msc := 0);
735 * f_do_other(on_msc := 1);
736 * f_ctrs_msc_add(0, "thing", 2);
737 * f_ctrs_msc_add(1, "other");
738 * f_ctrs_msc_verify();
739 */
740private function f_ctrs_msc_verify() runs on test_CT {
741 log("verifying msc rate counters: ", g_ctr_msc);
742 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
743}
744
745/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
746 * f_ctrs_msc_init();
747 * f_do_thing(on_msc := 0);
748 * f_do_thing(on_msc := 0);
749 * f_do_thing(on_msc := 0);
750 * f_ctrs_msc_expect(0, "thing", 3);
751 */
752private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
753 f_ctrs_msc_add(msc_nr, countername, val);
754 f_ctrs_msc_verify();
755}
756
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000757/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
758
759private function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
760 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
761 log("initial bts rate counters: ", g_ctr_bts);
762 f_ctrs_bsc_init(counternames);
763}
764
765private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
766 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
767 f_ctrs_bsc_add(countername, val);
768}
769
770/* f_ctrs_bsc_and_bts_init();
771 * f_do_thing(on_bts := 0);
772 * f_do_thing(on_bts := 0);
773 * f_do_other(on_bts := 1);
774 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
775 * f_ctrs_bsc_and_bts_add(1, "other");
776 * f_ctrs_bsc_and_bts_verify();
777 */
778private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
779 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
780 f_ctrs_bsc_verify();
781}
782
783/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
784 * f_ctrs_bsc_and_bts_init();
785 * f_do_thing(on_bts := 0);
786 * f_do_thing(on_bts := 0);
787 * f_do_thing(on_bts := 0);
788 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
789 */
790private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
791 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
792 f_ctrs_bsc_and_bts_verify();
793}
794
795
796/* Convenience functions for rate counters using g_ctr_bsc. */
797
798private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
799 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
800 log("initial bsc rate counters: ", g_ctr_bsc);
801}
802
803private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
804 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
805}
806
807/* f_ctrs_bsc_init();
808 * f_do_thing();
809 * f_do_thing();
810 * f_do_other();
811 * f_ctrs_bsc_add("thing", 2);
812 * f_ctrs_bsc_add("other");
813 * f_ctrs_bsc_verify();
814 */
815private function f_ctrs_bsc_verify() runs on test_CT {
816 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
817}
818
819/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
820 * f_ctrs_bsc_init();
821 * f_do_thing();
822 * f_ctrs_bsc_expect("thing", 1);
823 */
824private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
825 f_ctrs_bsc_add(countername, val);
826 f_ctrs_bsc_verify();
827}
828
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200829
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200830friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200831 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100832 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200833 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100834}
835
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200836private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100837 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200838 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100839 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200840 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
841 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100842 T.start;
843 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200844 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
845 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200846 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100847 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200848 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200849 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100850 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200851 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200852 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100853 repeat;
854 }
855 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200856 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200857 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200858 /* If we received a RESET after ours was sent, it
859 may be a race condition where the other peer beacame
860 available after we sent it, but we are in a desired
861 state anyway, so go forward. */
862 if (not reset_received) {
863 setverdict(fail);
864 }
865 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100866 }
Harald Welte28d943e2017-11-25 15:00:50 +0100867}
868
Harald Welteae026692017-12-09 01:03:01 +0100869type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100870 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100871 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100872 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100873 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100874 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100875 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100876 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100877 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100878}
879
Harald Welte21b46bd2017-12-17 19:46:32 +0100880/*! Start the IPA/RSL related bits for one IPA_Client.
881 * \param clnt IPA_Client for which to establish
882 * \param bsc_host IP address / hostname of the BSC
883 * \param bsc_port TCP port number of the BSC
884 * \param i number identifying this BTS
885 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100886function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
887 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100888runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100889 timer T := 10.0;
890
Harald Welte96c94412017-12-09 03:12:45 +0100891 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100892 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
893 clnt.ccm_pars := c_IPA_default_ccm_pars;
894 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
895 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100896 if (handler_mode) {
897 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100898 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100899 }
Harald Welteae026692017-12-09 01:03:01 +0100900
901 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100902 if (handler_mode) {
903 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
904 } else {
905 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
906 }
Harald Welteae026692017-12-09 01:03:01 +0100907
Harald Welte5d1a2202017-12-13 19:51:29 +0100908 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100909 if (handler_mode) {
910 clnt.vc_RSL.start(RSL_Emulation.main());
911 return;
912 }
Harald Welteae026692017-12-09 01:03:01 +0100913
914 /* wait for IPA RSL link to connect and send ID ACK */
915 T.start;
916 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700917 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100918 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700919 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100920 }
Harald Welte60e823a2017-12-10 14:10:59 +0100921 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100922 [] IPA_RSL[i].receive { repeat }
923 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100924 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200925 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100926 }
927 }
928}
929
Harald Welte12055472018-03-17 20:10:08 +0100930function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
931 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
932 return;
933 }
934 clnt.vc_IPA.stop;
935 if (isbound(clnt.vc_RSL)) {
936 clnt.vc_RSL.stop;
937 }
938}
939
Harald Welte21b46bd2017-12-17 19:46:32 +0100940/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100941function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
942 timer T := secs_max;
943 T.start;
944 while (true) {
945 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
946 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100947 /* the 'degraded' state exists from OML connection time, and we have to wait
948 * until all MO's are initialized */
949 T.start(1.0);
950 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100951 return;
952 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100953 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100954 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100955 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200956 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100957 }
958 }
959}
960
Harald Welte21b46bd2017-12-17 19:46:32 +0100961/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100962altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100963 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100964 [] T_guard.timeout {
965 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200966 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100967 }
Harald Welte60e823a2017-12-10 14:10:59 +0100968 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200969 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100970 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200971 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100972 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100973 }
Harald Welte28d943e2017-11-25 15:00:50 +0100974}
975
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100976altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200977 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100978 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +0200979 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100980 }
981}
982
Daniel Willmann191e0d92018-01-17 12:44:35 +0100983function f_init_mgcp(charstring id) runs on test_CT {
984 id := id & "-MGCP";
985
986 var MGCPOps ops := {
987 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
988 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
989 };
990 var MGCP_conn_parameters mgcp_pars := {
991 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +0100992 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +0100993 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200994 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +0200995 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
996 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200997 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +0100998 };
999
1000 vc_MGCP := MGCP_Emulation_CT.create(id);
1001 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1002}
1003
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001004/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1005 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1006 * OsmuxCID IE.
1007 */
1008private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1009 f_vty_enter_cfg_msc(BSCVTY, 0);
1010 if (allow) {
1011 f_vty_transceive(BSCVTY, "osmux on");
1012 } else {
1013 f_vty_transceive(BSCVTY, "osmux off");
1014 }
1015 f_vty_transceive(BSCVTY, "exit");
1016 f_vty_transceive(BSCVTY, "exit");
1017 g_osmux_enabled := allow;
1018}
1019
Max2253c0b2018-11-06 19:28:05 +01001020function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001021 if (BSCVTY.checkstate("Mapped")) {
1022 /* skip initialization if already executed once */
1023 return;
1024 }
Harald Weltebc03c762018-02-12 18:09:38 +01001025 map(self:BSCVTY, system:BSCVTY);
1026 f_vty_set_prompts(BSCVTY);
1027 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001028 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1029 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001030}
1031
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001032friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001033{
1034 // log on TTCN3 log output
1035 log(log_msg);
1036 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001037 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001038}
1039
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001040private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1041{
1042 if (rsl_idx >= lengthof(g_system_information)) {
1043 g_system_information[rsl_idx] := SystemInformationConfig_omit
1044 }
1045 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1046}
1047
1048altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1049 var ASP_RSL_Unitdata rx_rsl_ud;
1050
1051 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1052 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1053 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1054 repeat;
1055 }
1056 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1057 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1058 repeat;
1059 }
1060 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1061 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1062 repeat;
1063 }
1064 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1065 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1066 repeat;
1067 }
1068
1069 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1070 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1071 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1072 repeat;
1073 }
1074 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1075 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1076 repeat;
1077 }
1078 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1079 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1080 repeat;
1081 }
1082 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1083 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1084 repeat;
1085 }
1086}
1087
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001088/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1089private type record of boolean my_BooleanList;
1090
1091private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1092{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001093 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1094
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001095 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001096 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1097 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1098 * stepping into that config node. */
1099 log("msc ", msc_nr, " is not configured, skipping");
1100 continue;
1101 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001102 f_vty_enter_cfg_msc(pt, msc_nr);
1103 if (allow_attach_list[msc_nr]) {
1104 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1105 f_vty_transceive(pt, "allow-attach", strict := false);
1106 } else {
1107 f_vty_transceive(pt, "no allow-attach", strict := false);
1108 }
1109 f_vty_transceive(pt, "exit");
1110 f_vty_transceive(pt, "exit");
1111 }
1112}
1113
Harald Welte21b46bd2017-12-17 19:46:32 +01001114/* global initialization function
1115 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001116 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1117 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1118 */
1119function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001120 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001121 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001122
Harald Welteae026692017-12-09 01:03:01 +01001123 if (g_initialized) {
1124 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001125 }
Harald Welteae026692017-12-09 01:03:01 +01001126 g_initialized := true;
1127
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001128 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001129 activate(as_Tguard());
1130
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001131 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001132 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001133
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001134 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001135 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1136
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001137 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1138 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1139 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1140 }
1141
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001142 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001143 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001144 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1145 * MSC-side BSSAP emulation */
1146 if (handler_mode) {
1147 var RanOps ranops := MSC_RanOps;
1148 ranops.use_osmux := g_osmux_enabled;
1149 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1150 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1151 f_ran_adapter_start(g_bssap[bssap_idx]);
1152 } else {
1153 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1154 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1155 f_ran_adapter_start(g_bssap[bssap_idx]);
1156 f_legacy_bssap_reset();
1157 }
Harald Welte67089ee2018-01-17 22:19:03 +01001158 }
Harald Welted5833a82018-05-27 16:52:56 +02001159
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001160 if (mp_enable_lcs_tests) {
1161 if (handler_mode) {
1162 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1163 } else {
1164 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1165 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1166 }
1167 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001168 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001169
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001170 /* start the test with exactly all enabled MSCs allowed to attach */
1171 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1172
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001173 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001174
Daniel Willmann191e0d92018-01-17 12:44:35 +01001175 f_init_mgcp("VirtMSC");
1176
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001177 for (var integer i := 0; i < nr_bts; i := i+1) {
1178 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001179 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001180}
Harald Welte696ddb62017-12-08 14:01:43 +01001181
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001182function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1183runs on test_CT {
1184 /* wait until osmo-bts-omldummy has respawned */
1185 f_wait_oml(bts_idx, "degraded", 5.0);
1186
1187 /* start RSL connection */
1188 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1189 /* wait until BSC tells us "connected" */
1190 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001191}
1192
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001193function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1194 template SystemInformationConfig expect_si)
1195runs on test_CT {
1196 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1197
1198 f_init_bts(bts_idx, handler_mode);
1199
1200 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1201 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1202 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1203 */
1204 f_sleep(5.0);
1205 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1206
1207 deactivate(sysinfo);
1208
1209 if (match(g_system_information[bts_idx], expect_si)) {
1210 setverdict(pass);
1211 } else {
1212 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1213 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1214 setverdict(fail, "received SI does not match expectations");
1215 return;
1216 }
1217}
1218
Maxd4e56962018-10-31 19:08:25 +01001219/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001220function 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 +01001221runs on test_CT return RSL_Message {
1222 var ASP_RSL_Unitdata rx_rsl_ud;
1223 timer T := t_secs;
1224
1225 T.start;
1226 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001227 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001228 T.stop;
1229 }
1230 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001231 [] T.timeout {
1232 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001233 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001234 }
Harald Welteae026692017-12-09 01:03:01 +01001235 }
1236 return rx_rsl_ud.rsl;
1237}
1238
Harald Welte21b46bd2017-12-17 19:46:32 +01001239/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001240function 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 +01001241runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001242 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001243}
1244
1245
Harald Welte4003d112017-12-09 22:35:39 +01001246/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001247testcase TC_chan_act_noreply() runs on test_CT {
1248 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001249 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001250
Harald Welte89d42e82017-12-17 16:42:41 +01001251 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001252
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001253 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001254 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001255 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001256}
1257
Harald Welte4003d112017-12-09 22:35:39 +01001258/* verify if the "chreq:total" counter increments as expected */
1259testcase TC_chan_act_counter() runs on test_CT {
1260 var BSSAP_N_UNITDATA_ind ud_ind;
1261 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001262 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001263
Harald Welte89d42e82017-12-17 16:42:41 +01001264 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001265
1266 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001267 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001268 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001269 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1270
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001271 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001272}
1273
Harald Welteae026692017-12-09 01:03:01 +01001274/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001275private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001276 var RSL_Message rx_rsl;
1277
Harald Welteae026692017-12-09 01:03:01 +01001278 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001279 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001280
1281 /* expect BSC to disable the channel again if there's no RLL EST IND */
1282 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1283
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001284 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001285}
1286
Philipp Maier9c60a622020-07-09 15:08:46 +02001287/* Normal variant */
1288testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001289 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001290 f_TC_chan_act_ack_noest();
1291}
1292
1293/* Emergency call variant */
1294testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1295 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001296 f_init(1);
1297 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001298 f_TC_chan_act_ack_noest(ra := 'A5'O);
1299}
1300
Philipp Maier606f07d2020-08-12 17:21:58 +02001301/* Emergency call variant, but emergency calls are not allowed */
1302testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1303 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1304
1305 var RSL_Message rx_rsl;
1306 var GsmRrMessage rr;
1307
1308 f_init(1);
1309 f_vty_allow_emerg_bts(false, 0);
1310
1311 IPA_RSL[0].clear;
1312 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1313
1314 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1315 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1316 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1317 setverdict(pass);
1318 } else {
1319 setverdict(fail, "immediate assignment not rejected");
1320 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001321
1322 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001323}
1324
Harald Welteae026692017-12-09 01:03:01 +01001325/* Test behavior if MSC never answers to CR */
1326testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001327 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1328 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001329 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001330 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001331
Harald Welte89d42e82017-12-17 16:42:41 +01001332 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001333
1334 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001335 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001336
1337 var octetstring l3 := '00010203040506'O
1338 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1339
1340 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1341
1342 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001343 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001344 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001345 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001346}
1347
1348/* Test behavior if MSC answers with CREF to CR */
1349testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1350 var BSSAP_N_CONNECT_ind rx_c_ind;
1351 var RSL_Message rx_rsl;
1352
Harald Welte89d42e82017-12-17 16:42:41 +01001353 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001354
1355 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001356 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001357
1358 var octetstring l3 := '00010203040506'O
1359 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1360
1361 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1362 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1363
1364 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001365 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001366 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001367}
1368
Harald Welte618ef642017-12-14 14:58:20 +01001369/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1370testcase TC_chan_act_nack() runs on test_CT {
1371 var RSL_Message rx_rsl;
1372 var integer chact_nack;
1373
Harald Welte89d42e82017-12-17 16:42:41 +01001374 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001375
1376 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1377
1378 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1379 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1380 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1381
1382 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1383
1384 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1385 f_sleep(0.5);
1386
1387 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1388
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001389 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001390}
1391
Harald Welte799c97b2017-12-14 17:50:30 +01001392/* Test for channel exhaustion due to RACH overload */
1393testcase TC_chan_exhaustion() runs on test_CT {
1394 var ASP_RSL_Unitdata rsl_ud;
1395 var integer i;
1396 var integer chreq_total, chreq_nochan;
1397
Harald Welte89d42e82017-12-17 16:42:41 +01001398 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001399
1400 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1401 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1402
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001403 /* GSM 04.08 Table 9.9a:
1404 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1405 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001406 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 +01001407 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001408 }
1409
1410 IPA_RSL[0].clear;
1411
Harald Weltedd8cbf32018-01-28 12:07:52 +01001412 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001413 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001414
1415 /* now expect additional channel activations to fail */
1416 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1417
1418 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001419 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001420 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1421 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001422 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001423 var GsmRrMessage rr;
1424 /* match on IMM ASS REJ */
1425 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1426 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1427 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001428 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001429 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1430 chreq_nochan+1);
1431 setverdict(pass);
1432 } else {
1433 repeat;
1434 }
1435 }
1436 [] IPA_RSL[0].receive { repeat; }
1437 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001438 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001439}
1440
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001441/* Test channel deactivation due to silence from MS */
1442testcase TC_chan_deact_silence() runs on test_CT {
1443 var RslChannelNr chan_nr;
1444
1445 f_init(1);
1446
1447 /* Request for a dedicated channel */
1448 chan_nr := f_chreq_act_ack('23'O);
1449
1450 /* Wait some time until the channel is released */
1451 f_sleep(2.0);
1452
1453 /* Expect CHANnel RELease */
1454 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001455 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001456 log("Received CHANnel RELease");
1457 setverdict(pass);
1458 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001459 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001460 /* See OS#3709, OsmoBSC should not send Immediate
1461 * Assignment Reject since a dedicated channel was
1462 * already allocated, and Immediate Assignment was
1463 * already sent. */
1464 setverdict(fail, "Unexpected Immediate Assignment!");
1465 }
1466 [] IPA_RSL[0].receive {
1467 setverdict(fail, "Unexpected RSL message!");
1468 }
1469 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001470 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001471}
1472
Harald Weltecfe2c962017-12-15 12:09:32 +01001473/***********************************************************************
1474 * Assignment Testing
1475 ***********************************************************************/
1476
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001477/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1478 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001479testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001480 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001481
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001482 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1483 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001484 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001485 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001486}
1487
Harald Welte16a4adf2017-12-14 18:54:01 +01001488/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001489testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001490 var BSSAP_N_CONNECT_ind rx_c_ind;
1491 var RSL_Message rx_rsl;
1492 var DchanTuple dt;
1493
Harald Welte89d42e82017-12-17 16:42:41 +01001494 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001495
1496 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001497 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001498 /* send assignment without AoIP IEs */
1499 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1500 } else {
1501 /* Send assignmetn without CIC in IPA case */
1502 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1503 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1504 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1505 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001506 alt {
1507 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1508 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1509 }
Harald Welte235ebf12017-12-15 14:18:16 +01001510 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001511 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1512 setverdict(pass);
1513 }
1514 [] BSSAP.receive { repeat; }
1515 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001516 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001517}
1518
Harald Welteed848512018-05-24 22:27:58 +02001519/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001520function 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 +02001521 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001522 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001523 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001524 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001525 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001526 if (osmux_enabled) {
1527 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1528 } else {
1529 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1530 }
Harald Welteed848512018-05-24 22:27:58 +02001531 } else {
1532 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001533 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001534 }
1535 return ass_cmd;
1536}
1537
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001538function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001539 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1540 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001541 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001542
1543 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1544 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1545 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1546 var template BSSMAP_IE_KC128 kc128 := omit;
1547 if (ispresent(enc)) {
1548 var TestHdlrEncrParams v_enc := valueof(enc);
1549 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1550 chosenEncryptionAlgorithm := valueof(
1551 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001552 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001553 if (ispresent(v_enc.enc_kc128)) {
1554 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1555 }
1556 }
1557
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001558 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001559 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001560 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001561 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1562 encryptionInformation := encryptionInformation,
1563 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1564 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001565 } else {
1566 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001567 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1568 encryptionInformation := encryptionInformation,
1569 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1570 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001571 }
1572 return ho_req;
1573}
1574
Harald Welteed848512018-05-24 22:27:58 +02001575/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001576function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001577 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001578 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001579 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001580 if (expect_osmux) {
1581 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1582 } else {
1583 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1584 }
Harald Welteed848512018-05-24 22:27:58 +02001585 } else {
1586 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001587 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001588 }
1589 return exp_compl;
1590}
1591
Harald Welte235ebf12017-12-15 14:18:16 +01001592/* Run everything required up to sending a caller-specified assignment command and expect response */
1593function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1594runs on test_CT {
1595 var BSSAP_N_CONNECT_ind rx_c_ind;
1596 var RSL_Message rx_rsl;
1597 var DchanTuple dt;
1598
Harald Welte89d42e82017-12-17 16:42:41 +01001599 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001600
1601 dt := f_est_dchan('23'O, 23, '00000000'O);
1602 /* send assignment without AoIP IEs */
1603 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1604 alt {
1605 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1606 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1607 setverdict(pass);
1608 } else {
1609 setverdict(fail, fail_text);
1610 }
1611 }
1612 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1613 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1614 setverdict(pass);
1615 } else {
1616 setverdict(fail, fail_text);
1617 }
1618 }
1619 [] BSSAP.receive { repeat; }
1620 }
1621}
1622testcase TC_assignment_csd() runs on test_CT {
1623 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001624 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001625 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1626 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1627 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001628 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001629}
1630
1631testcase TC_assignment_ctm() runs on test_CT {
1632 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001633 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001634 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1635 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1636 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001637 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001638}
1639
Harald Welte4003d112017-12-09 22:35:39 +01001640type record DchanTuple {
1641 integer sccp_conn_id,
1642 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001643}
1644
Harald Welted6939652017-12-13 21:02:46 +01001645/* Send CHAN RQD and wait for allocation; acknowledge it */
1646private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1647runs on test_CT return RslChannelNr {
1648 var RSL_Message rx_rsl;
1649 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1650 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1651 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1652 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001653 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001654 return chan_nr;
1655}
1656
Harald Welte4003d112017-12-09 22:35:39 +01001657/* helper function to establish a dedicated channel via BTS and MSC */
1658function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1659runs on test_CT return DchanTuple {
1660 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001661 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001662
Harald Welte4003d112017-12-09 22:35:39 +01001663 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001664 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001665
1666 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1667
1668 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1669 dt.sccp_conn_id := rx_c_ind.connectionId;
1670 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1671
1672 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001673}
1674
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001675/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1676function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1677runs on test_CT return DchanTuple {
1678 var BSSAP_N_CONNECT_ind rx_c_ind;
1679 var DchanTuple dt;
1680
1681 /* Send CHAN RQD */
1682 var RSL_Message rx_rsl;
1683 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1684
1685 /* The dyn TS first deactivates PDCH */
1686 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1687 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1688 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1689
1690 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1691 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1692
1693 /* Now activates the signalling channel */
1694 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1695 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1696
1697 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1698
1699 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1700 dt.sccp_conn_id := rx_c_ind.connectionId;
1701 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1702
1703 return dt;
1704}
1705
Harald Welte641fcbe2018-06-14 10:58:35 +02001706/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1707private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1708 var RSL_Message rx_rsl;
1709 /* expect BSC to disable the channel */
1710 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1711 /* respond with CHAN REL ACK */
1712 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1713
1714 /* expect Clear Complete from BSC */
1715 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1716
1717 /* MSC disconnects as instructed. */
1718 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1719}
1720
Harald Welte4003d112017-12-09 22:35:39 +01001721/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1722testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001723 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001724 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001725
Harald Welte89d42e82017-12-17 16:42:41 +01001726 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001727
Harald Welte4003d112017-12-09 22:35:39 +01001728 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1729
1730 /* simulate RLL REL IND */
1731 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1732
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001733 /* expect Clear Request on MSC side */
1734 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1735
1736 /* Instruct BSC to clear channel */
1737 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1738 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1739
Harald Welte4003d112017-12-09 22:35:39 +01001740 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001741 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001742
1743 /* wait for SCCP emulation to do its job */
1744 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001745
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001746 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001747}
1748
1749/* Test behavior of channel release after CONN FAIL IND from BTS */
1750testcase TC_chan_rel_conn_fail() runs on test_CT {
1751 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001752 var DchanTuple dt;
1753
Harald Welte89d42e82017-12-17 16:42:41 +01001754 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001755
1756 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1757
1758 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001759 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 +01001760 /* TODO: different cause values? */
1761
Harald Welte4003d112017-12-09 22:35:39 +01001762 /* expect Clear Request from BSC */
1763 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1764
1765 /* Instruct BSC to clear channel */
1766 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1767 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1768
Harald Welte6ff76ea2018-01-28 13:08:01 +01001769 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001770 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001771
1772 /* wait for SCCP emulation to do its job */
1773 f_sleep(1.0);
1774
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001775 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001776}
1777
Harald Welte99f3ca02018-06-14 13:40:29 +02001778/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1779/* See also https://www.osmocom.org/issues/3182 */
1780testcase TC_early_conn_fail() runs on test_CT {
1781 var RSL_Message rx_rsl;
1782 var DchanTuple dt;
1783
1784 f_init(1);
1785
1786 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001787 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001788
1789 /* BTS->BSC: simulate CONN FAIL IND */
1790 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1791
1792 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1793 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1794
1795 /* BTS<-BSC: respond with CHAN REL ACK */
1796 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1797
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001798 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001799}
1800
1801/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1802/* See also https://www.osmocom.org/issues/3182 */
1803testcase TC_late_conn_fail() runs on test_CT {
1804 var RSL_Message rx_rsl;
1805 var DchanTuple dt;
1806
1807 f_init(1);
1808
1809 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1810
1811 /* BSC<-MSC: Instruct BSC to clear connection */
1812 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1813
1814 /* BTS->BSC: expect BSC to deactivate SACCH */
1815 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1816
1817 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1818 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1819
1820 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1821 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1822 /* BTS->BSC: respond with CHAN REL ACK */
1823 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1824
1825 /* BSC->MSC: expect Clear Complete from BSC */
1826 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1827
1828 /* BSC<-MSC: MSC disconnects as requested. */
1829 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1830
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001831 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001832}
1833
Oliver Smithaf03bef2021-08-24 15:34:51 +02001834private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1835 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1836 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1837
1838 f_statsd_reset();
1839
1840 /* Establish SDCCH */
1841 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1842 f_establish_fully(ass_cmd, exp_fail);
1843
1844 /* Expect stats to be 0 */
1845 var StatsDExpects expect := {
1846 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1847 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1848 };
1849 f_statsd_expect(expect);
1850
1851 /* Simulate CONN FAIL IND on SDCCH */
1852 RSL.send(ts_ASP_RSL_UD(
1853 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1854 IPAC_PROTO_RSL_TRX0));
1855
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001856 f_sleep(1.0);
1857
Oliver Smithaf03bef2021-08-24 15:34:51 +02001858 /* Expect stats to be 1 */
1859 expect := {
1860 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1861 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1862 };
1863 f_statsd_expect(expect);
1864}
1865testcase TC_stats_conn_fail() runs on test_CT {
1866 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1867 var MSC_ConnHdlr vc_conn;
1868
1869 f_init(1, true);
1870 f_sleep(1.0);
1871
1872 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1873 vc_conn.done;
1874
1875 f_shutdown_helper();
1876}
1877
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001878function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001879 boolean expect_deact_sacch := true,
1880 boolean expect_rr_chan_rel := true,
1881 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001882 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001883 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001884 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001885 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001886
1887 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001888 var boolean got_deact_sacch := false;
1889 var boolean got_rr_chan_rel := false;
1890 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001891 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001892 var RSL_IE_Body l3_ie;
1893 var PDU_ML3_NW_MS l3;
1894 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001895 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1896 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001897 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001898 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001899 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001900 repeat;
1901 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001902 [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 +01001903 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001904
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001905 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1906 setverdict(fail, "cannot find L3");
1907 mtc.stop;
1908 }
1909 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1910
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001911 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001912 var CellSelIndValue cells := dec_CellSelIndValue(
1913 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1914
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001915 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1916 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001917 setverdict(pass);
1918 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001919 log("EXPECTED CELLS: ", expect_cells);
1920 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001921 }
1922 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001923
1924 if (not istemplatekind(expect_rr_cause, "omit")) {
1925 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1926 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1927 if (match(got_cause, expect_rr_cause)) {
1928 setverdict(pass);
1929 } else {
1930 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1931 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1932 }
1933 }
Harald Welte99787102019-02-04 10:41:36 +01001934 repeat;
1935 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001936 [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 +01001937 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001938
1939 if (not istemplatekind(expect_rr_cause, "omit")) {
1940 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1941 setverdict(fail, "cannot find L3");
1942 mtc.stop;
1943 }
1944 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1945
1946 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1947 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1948 if (match(got_cause, expect_rr_cause)) {
1949 setverdict(pass);
1950 } else {
1951 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1952 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1953 }
1954 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001955 repeat;
1956 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001957 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001958 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001959 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001960 if (handle_rll_rel) {
1961 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1962 }
Harald Welte91d54a52018-01-28 15:35:07 +01001963 repeat;
1964 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001965 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001966 /* respond with CHAN REL ACK */
1967 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1968 }
1969 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001970 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001971 repeat;
1972 }
1973 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001974
1975 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
1976 " got_rll_rel_req=", got_rll_rel_req);
1977
1978 if (expect_deact_sacch != got_deact_sacch) {
1979 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
1980 }
1981 if (expect_rr_chan_rel != got_rr_chan_rel) {
1982 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
1983 }
1984 if (expect_rll_rel_req != got_rll_rel_req) {
1985 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
1986 }
Harald Welte91d54a52018-01-28 15:35:07 +01001987}
1988
Harald Welte4003d112017-12-09 22:35:39 +01001989/* Test behavior of channel release after hard Clear Command from MSC */
1990testcase TC_chan_rel_hard_clear() runs on test_CT {
1991 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001992 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01001993
Harald Welte89d42e82017-12-17 16:42:41 +01001994 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001995
1996 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1997
1998 /* Instruct BSC to clear channel */
1999 var BssmapCause cause := 0;
2000 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2001
2002 /* expect Clear Complete from BSC on A */
2003 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2004 /* release the SCCP connection */
2005 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2006 }
2007
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002008 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002009 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002010}
2011
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002012function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2013 var BSSAP_N_DATA_ind rx_di;
2014 var DchanTuple dt;
2015
2016 f_init(1);
2017
2018 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2019 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2020 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2021 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2022
2023 /* Instruct BSC to clear channel */
2024 var BssmapCause cause := 0;
2025 if (tx_csfb_ind) {
2026 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2027 } else {
2028 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2029 }
2030
2031 /* expect Clear Complete from BSC on A */
2032 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2033 /* release the SCCP connection */
2034 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2035 }
2036
2037 /* 1 neighbor is added by default in osmo-bts.cfg and
2038 SystemInformationConfig_default, use that: */
2039 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2040
2041 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2042 f_shutdown_helper();
2043}
2044
2045/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2046 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2047 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2048 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2049 Indicator or not shouldn't matter at all. */
2050testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2051 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2052}
2053
2054/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2055 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2056 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2057 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2058testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2059 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2060}
2061
2062/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2063 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2064 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2065 CSFB Indicator should not be used anymore, and hence, there should be no
2066 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2067 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002068testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2069 var BSSAP_N_DATA_ind rx_di;
2070 var DchanTuple dt;
2071
2072 f_init(1);
2073
2074 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2075
2076 /* Instruct BSC to clear channel */
2077 var BssmapCause cause := 0;
2078 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2079
2080 /* expect Clear Complete from BSC on A */
2081 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2082 /* release the SCCP connection */
2083 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2084 }
2085
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002086 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002087 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002088}
2089
Harald Welted8c36cd2017-12-09 23:05:31 +01002090/* Test behavior of channel release after hard RLSD from MSC */
2091testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002092 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002093
Harald Welte89d42e82017-12-17 16:42:41 +01002094 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002095
2096 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2097
2098 /* release the SCCP connection */
2099 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2100
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002101 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002102 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002103}
2104
Harald Welte550daf92018-06-11 19:22:13 +02002105/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2106testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2107 var DchanTuple dt;
2108
2109 f_init(1);
2110
2111 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2112
2113 /* release the SCCP connection */
2114 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2115
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002116 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002117 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002118}
2119
Harald Welte85804d42017-12-10 14:11:58 +01002120/* Test behavior of channel release after BSSMAP RESET from MSC */
2121testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002122 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002123
Harald Welte89d42e82017-12-17 16:42:41 +01002124 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002125
2126 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2127
2128 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2129 IPA_RSL[0].clear;
2130
2131 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002132 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 +01002133 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002134 [] 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 +01002135 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2136 }
2137
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002138 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002139 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002140}
2141
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002142/* Verify T(iar) triggers and releases the channel */
2143testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2144 var DchanTuple dt;
2145
2146 /* Set T(iar) in BSC low enough that it will trigger before other side
2147 has time to keep alive with a T(ias). Keep recommended ratio of
2148 T(iar) >= T(ias)*2 */
2149 g_bsc_sccp_timer_ias := 2;
2150 g_bsc_sccp_timer_iar := 5;
2151
2152 f_init(1);
2153
2154 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2155 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002156 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002157}
2158
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002159private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2160runs on test_CT
2161{
2162 var DchanTuple dt;
2163
2164 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2165 var BssmapCause cause := 0;
2166 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2167 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2168 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2169 }
2170
2171 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 +02002172}
2173
2174/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2175testcase TC_chan_rel_rr_cause() runs on test_CT {
2176 f_init(1);
2177
2178 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2179 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2180 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2181 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2182 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2183 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002184
2185 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002186}
2187
Harald Welte5cd20ed2017-12-13 21:03:20 +01002188/* Test behavior if RSL EST IND for non-active channel */
2189testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2190 timer T := 2.0;
2191
Harald Welte89d42e82017-12-17 16:42:41 +01002192 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002193
2194 var octetstring l3 := '00010203040506'O;
2195 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2196 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2197
2198 T.start;
2199 alt {
2200 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2201 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2202 }
2203 [] BSSAP.receive {}
2204 [] IPA_RSL[0].receive {}
2205 [] T.timeout {}
2206 }
2207
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002208 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002209}
2210
2211/* Test behavior if RSL EST IND for invalid SAPI */
2212testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2213 var RslChannelNr chan_nr;
2214
Harald Welte89d42e82017-12-17 16:42:41 +01002215 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002216
2217 chan_nr := f_chreq_act_ack()
2218
2219 var octetstring l3 := '00010203040506'O;
2220 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2221
2222 timer T := 2.0;
2223 T.start;
2224 alt {
2225 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2226 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2227 }
2228 [] BSSAP.receive { repeat; }
2229 [] IPA_RSL[0].receive { repeat; }
2230 [] T.timeout {}
2231 }
2232
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002233 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002234}
2235
2236/* Test behavior if RSL EST IND for invalid SAPI */
2237testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2238 timer T := 2.0;
2239
Harald Welte89d42e82017-12-17 16:42:41 +01002240 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002241
2242 var RslChannelNr chan_nr := f_chreq_act_ack();
2243
2244 var octetstring l3 := '00010203040506'O;
2245 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2246
2247 T.start;
2248 alt {
2249 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2250 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2251 }
2252 [] BSSAP.receive { repeat; }
2253 [] IPA_RSL[0].receive { repeat; }
2254 [] T.timeout {}
2255 }
2256
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002257 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002258}
2259
2260/* Test behavior if RSL EST IND for invalid SACCH */
2261testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2262 timer T := 2.0;
2263
Harald Welte89d42e82017-12-17 16:42:41 +01002264 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002265
2266 var RslChannelNr chan_nr := f_chreq_act_ack();
2267
2268 var octetstring l3 := '00010203040506'O;
2269 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2270
2271 T.start;
2272 alt {
2273 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2274 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2275 }
2276 [] BSSAP.receive { repeat; }
2277 [] IPA_RSL[0].receive { repeat; }
2278 [] T.timeout {}
2279 }
2280
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002281 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002282}
2283
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002284/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2285private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2286 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2287 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2288
2289 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2290 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2291
2292 f_establish_fully(ass_cmd, exp_compl);
2293
2294 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2295 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2296 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2297 BSSAP.receive(PDU_BSSAP:{
2298 discriminator := '1'B,
2299 spare := '0000000'B,
2300 dlci := 'C3'O,
2301 lengthIndicator := ?,
2302 pdu := { dtap := '0904'O }
2303 });
2304
2305 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2306 for (var integer i := 0; i < 32; i := i + 1) {
2307 var octetstring l3 := '09'O & f_rnd_octstring(14);
2308 var template (value) RslLinkId link_id;
2309 var template (value) OCT1 dlci;
2310
2311 if (i mod 2 == 0) {
2312 /* SAPI0 on FACCH or SDCCH */
2313 link_id := ts_RslLinkID_DCCH(0);
2314 dlci := '80'O;
2315 } else {
2316 /* SAPI3 on SACCH */
2317 link_id := ts_RslLinkID_SACCH(3);
2318 dlci := 'C3'O;
2319 }
2320
2321 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002322 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002323 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002324 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002325 }
2326}
2327testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2328 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2329 var MSC_ConnHdlr vc_conn;
2330
2331 f_init(1, true);
2332 f_sleep(1.0);
2333
2334 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2335 vc_conn.done;
2336
2337 f_shutdown_helper();
2338}
2339
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002340private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2341 template myBSSMAP_Cause cause := ?,
2342 float T_val := 2.0)
2343runs on test_CT {
2344 var BSSAP_N_DATA_ind rx_di;
2345 timer T;
2346
2347 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2348 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2349
2350 T.start(T_val);
2351 alt {
2352 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2353 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2354 if (not match(rx_cause, tr_cause)) {
2355 setverdict(fail, "Rx unexpected Cause IE: ",
2356 rx_cause, " vs expected ", tr_cause);
2357 }
2358 setverdict(pass);
2359 }
2360 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2361 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2362 }
2363 [] T.timeout {
2364 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2365 }
2366 }
2367}
2368
2369/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2370testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2371 var octetstring rnd_data := f_rnd_octstring(16);
2372 var RSL_Message rx_rsl;
2373 var DchanTuple dt;
2374
2375 f_init(1);
2376
2377 /* MS establishes a SAPI=0 link on DCCH */
2378 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2379
2380 /* MSC sends some data on (not yet established) SAPI=3 link */
2381 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2382 /* BSC attempts to establish a SAPI=3 link on DCCH */
2383 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2384
2385 /* MS sends unexpected RELease INDication on SAPI=3 */
2386 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2387 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2388 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2389
2390 /* Clean up the connection */
2391 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2392 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2393
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002394 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002395}
2396
2397/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2398testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2399 var octetstring rnd_data := f_rnd_octstring(16);
2400 var RSL_Message rx_rsl;
2401 var DchanTuple dt;
2402
2403 f_init(1);
2404
2405 /* MS establishes a SAPI=0 link on DCCH */
2406 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2407
2408 /* MSC sends some data on (not yet established) SAPI=3 link */
2409 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2410 /* BSC attempts to establish a SAPI=3 link on DCCH */
2411 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2412
2413 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2414 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2415 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2416 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2417
2418 /* Clean up the connection */
2419 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2420 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2421
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002422 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002423}
2424
2425/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2426testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2427 var octetstring rnd_data := f_rnd_octstring(16);
2428 var RSL_Message rx_rsl;
2429 var DchanTuple dt;
2430
2431 f_init(1);
2432
2433 /* MS establishes a SAPI=0 link on DCCH */
2434 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2435
2436 /* MSC sends some data on (not yet established) SAPI=3 link */
2437 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2438 /* BSC attempts to establish a SAPI=3 link on DCCH */
2439 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2440
2441 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2442 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2443
2444 /* Clean up the connection */
2445 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2446 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2447
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002448 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002449}
2450
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002451testcase TC_si_default() runs on test_CT {
2452 f_init(0);
2453 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002454 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002455}
Harald Welte4003d112017-12-09 22:35:39 +01002456
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002457/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2458 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2459private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2460{
2461 select (earfcn_index) {
2462 case (0) {
2463 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2464 return 111;
2465 }
2466 case (1) {
2467 return 1;
2468 }
2469 case (2) {
2470 return 0;
2471 }
2472 case (3) {
2473 return 65535;
2474 }
2475 case else {
2476 return 23 * (earfcn_index - 3);
2477 }
2478 }
2479}
2480
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002481function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2482 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002483
2484 f_init(0);
2485
2486 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2487 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002488 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2489 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002490 }
2491
2492 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2493
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002494 if (not istemplatekind(expect_cells, "omit")) {
2495 /* Also check that RR Channel Release contains these EARFCNs.
2496 * (copied code from TC_chan_rel_hard_clear_csfb) */
2497 var BSSAP_N_DATA_ind rx_di;
2498 var DchanTuple dt;
2499
2500 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002501 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2502 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2503 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002504
2505 /* Instruct BSC to clear channel */
2506 var BssmapCause cause := 0;
2507 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2508
2509 /* expect Clear Complete from BSC on A */
2510 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2511 /* release the SCCP connection */
2512 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2513 }
2514
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002515 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 +02002516 }
2517
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002518 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002519 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 +02002520 }
2521}
2522
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002523private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2524{
2525 var template SI2quaterRestOctetsList si2quater := {};
2526 var integer si2quater_count := (count + 2) / 3;
2527
2528 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002529 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002530 var integer index := i / 3;
2531 var integer earfcn_index := i mod 3;
2532 if (index >= lengthof(si2quater)) {
2533 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2534 }
2535 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);
2536 }
2537
2538 return si2quater;
2539}
2540
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002541private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2542{
2543 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2544
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002545 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002546 for (var integer i := 0; i < count; i := i + 1) {
2547 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002548 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002549 }
2550
2551 return tr_CellSelIndValue_EUTRAN(cells);
2552}
2553
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002554private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2555{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002556 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002557 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002558 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2559 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002560}
2561
2562testcase TC_si2quater_2_earfcns() runs on test_CT {
2563 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002564 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002565}
2566
2567testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002568 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002569 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002570}
2571
2572testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002573 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002574 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002575}
2576
2577testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002578 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002579 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002580}
2581
2582testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002583 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002584 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002585}
2586
2587testcase TC_si2quater_12_earfcns() runs on test_CT {
2588 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002589 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002590}
2591
2592testcase TC_si2quater_23_earfcns() runs on test_CT {
2593 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002594 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002595}
2596
2597testcase TC_si2quater_32_earfcns() runs on test_CT {
2598 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002599 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002600}
2601
2602testcase TC_si2quater_33_earfcns() runs on test_CT {
2603 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002604 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002605}
2606
2607testcase TC_si2quater_42_earfcns() runs on test_CT {
2608 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002609 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002610}
2611
2612testcase TC_si2quater_48_earfcns() runs on test_CT {
2613 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002614 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002615}
2616
2617/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2618 * 48 EARFCNs. */
2619testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002620 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002621 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2622 f_init(0);
2623
2624 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002625 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2626 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002627 }
2628
2629 /* The 49th EARFCN no longer fits, expect VTY error */
2630 f_vty_enter_cfg_bts(BSCVTY, 0);
2631 var charstring vty_error;
2632 vty_error := f_vty_transceive_ret(BSCVTY,
2633 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2634 f_vty_transceive(BSCVTY, "end");
2635
2636 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2637 log("Got expected VTY error: ", vty_error);
2638 setverdict(pass);
2639 } else {
2640 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2641 }
2642
2643 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2644
2645 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002646 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 +02002647 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002648 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002649}
2650
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002651private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2652{
2653 var uint8_t count := 0;
2654 for (var integer i := 5; i < 16; i := i + 1) {
2655 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2656 count := count + 1;
2657 }
2658 }
2659 return count;
2660}
2661
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002662private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2663{
2664 var ASP_RSL_Unitdata rx_rsl_ud;
2665 var SystemInformationType1 last_si1;
2666
2667 timer T := 30.0;
2668 T.start;
2669 alt {
2670 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2671 tr_RSL_BCCH_INFO,
2672 tr_RSL_NO_SACCH_FILL,
2673 tr_RSL_SACCH_FILL))
2674 ) -> value rx_rsl_ud {
2675 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2676 if (g_system_information[rsl_idx].si1 == omit) {
2677 repeat;
2678 }
2679 last_si1 := g_system_information[rsl_idx].si1;
2680 g_system_information[rsl_idx].si1 := omit;
2681 T.stop;
2682 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002683 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002684 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2685 }
2686 return last_si1;
2687}
2688
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002689/* verify ACC rotate feature */
2690testcase TC_si_acc_rotate() runs on test_CT {
2691 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002692 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002693 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002694 var uint8_t count;
2695 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2696
2697 f_init(0, guard_timeout := 60.0);
2698
2699 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2700 "access-control-class-rotate 3",
2701 "access-control-class-rotate-quantum 1"});
2702
2703 /* Init and get first sysinfo */
2704 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2705
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002706 for (var integer i:= 0; i < 20; i := i + 1) {
2707 last_si1 := f_recv_next_si1(0);
2708 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002709 count := f_acc09_count_allowed(acc);
2710 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2711
2712 if (count != 3) {
2713 log("RSL: EXPECTED SI ACC len=3");
2714 setverdict(fail, "received SI does not match expectations");
2715 break;
2716 }
2717
2718 for (var integer j := 0; j < 10; j := j + 1) {
2719 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2720 times_allowed[j] := times_allowed[j] + 1;
2721 }
2722 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002723 }
2724
2725 for (var integer j := 0; j < 10; j := j + 1) {
2726 log("ACC", j, " allowed ", times_allowed[j], " times" );
2727 if (j != 5 and times_allowed[j] < 3) {
2728 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2729 } else if (j == 5 and times_allowed[j] > 0) {
2730 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2731 }
2732 }
2733
2734 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2735 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002736 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002737}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002738
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002739/* verify ACC startup ramp+rotate feature */
2740testcase TC_si_acc_ramp_rotate() runs on test_CT {
2741 var template SystemInformationConfig sic := SystemInformationConfig_default;
2742 var SystemInformationType1 last_si1;
2743 var AccessControlClass acc;
2744 var ASP_RSL_Unitdata rx_rsl_ud;
2745 var uint8_t count;
2746 var uint8_t prev_count;
2747 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2748
2749 f_init(0, guard_timeout := 80.0);
2750
2751 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2752 "access-control-class-rotate 0",
2753 "access-control-class-rotate-quantum 1",
2754 "access-control-class-ramping",
2755 "access-control-class-ramping-step-interval 5",
2756 "access-control-class-ramping-step-size 5"});
2757
2758 /* Init and get first sysinfo */
2759 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2760 last_si1 := g_system_information[0].si1;
2761 acc := last_si1.rach_control.acc;
2762 count := f_acc09_count_allowed(acc);
2763 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2764 while (count > 0) {
2765 last_si1 := f_recv_next_si1(0);
2766 acc := last_si1.rach_control.acc;
2767 count := f_acc09_count_allowed(acc);
2768 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2769 }
2770
2771 /* Increase adm subset size, we should see ramping start up */
2772 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2773 prev_count := 0;
2774 while (true) {
2775 last_si1 := f_recv_next_si1(0);
2776 acc := last_si1.rach_control.acc;
2777 count := f_acc09_count_allowed(acc);
2778 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2779
2780 if (prev_count > count) {
2781 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2782 break;
2783 }
2784
2785 if (count == 9) {
2786 break; /* Maximum reached (10 - 1 perm barred), done here */
2787 }
2788
2789 prev_count := count;
2790 }
2791
2792 setverdict(pass);
2793
2794 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2795 "rach access-control-class 4 allowed",
2796 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002797 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002798}
2799
Harald Welte4003d112017-12-09 22:35:39 +01002800testcase TC_ctrl_msc_connection_status() runs on test_CT {
2801 var charstring ctrl_resp;
2802
Harald Welte89d42e82017-12-17 16:42:41 +01002803 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002804
2805 /* See https://osmocom.org/issues/2729 */
2806 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002807 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002808}
2809
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002810testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2811 var charstring ctrl_resp;
2812
2813 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002814
2815 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002816 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002817}
2818
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002819/* Verify correct stats on the number of configured and connected MSCs */
2820private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2821 g_pars := f_gen_test_hdlr_pars();
2822 var StatsDExpects expect := {
2823 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2824 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2825 };
2826 f_statsd_expect(expect);
2827}
2828
2829private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2830{
2831 var MSC_ConnHdlr vc_conn;
2832
2833 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2834 f_sleep(1.0);
2835 vc_conn := f_start_handler(tc_fn);
2836 vc_conn.done;
2837
2838 /* Also verify stat exposed on CTRL interface */
2839 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2840 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2841
2842 f_shutdown_helper();
2843}
2844
2845/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2846private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2847 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2848}
2849testcase TC_stat_num_msc_connected_1() runs on test_CT {
2850 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2851}
2852
2853/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2854private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2855 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2856}
2857testcase TC_stat_num_msc_connected_2() runs on test_CT {
2858 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2859}
2860
2861/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2862private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2863 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2864}
2865testcase TC_stat_num_msc_connected_3() runs on test_CT {
2866 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2867}
2868
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002869/* Verify correct stats on the number of configured and connected MSCs */
2870private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
2871 g_pars := f_gen_test_hdlr_pars();
2872 var StatsDExpects expect := {
2873 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
2874 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2875 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
2876 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2877 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
2878 };
2879 f_statsd_expect(expect);
2880}
2881
2882private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
2883 var MSC_ConnHdlr vc_conn;
2884
2885 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
2886 f_sleep(1.0);
2887 vc_conn := f_start_handler(tc_fn);
2888 vc_conn.done;
2889
2890 /* Also verify stat exposed on CTRL interface */
2891 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
2892 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
2893 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
2894 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
2895
Neels Hofmeyra41ae302021-09-06 22:06:02 +02002896 /* Verify rf_states exposed on CTRL interface */
2897 var charstring expect_net_rf_states := "";
2898 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
2899 var charstring expect_bts_rf_states := int2str(i) & ",0,";
2900 if (i < NUM_BTS) {
2901 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
2902 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
2903 } else {
2904 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
2905 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
2906 }
2907 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
2908 expect_bts_rf_states := expect_bts_rf_states & "on,";
2909 if (i < nr_bts) {
2910 /* For BTS where RSL is connected, the RSL state will be "up" */
2911 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
2912 } else {
2913 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
2914 }
2915
2916 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
2917 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
2918 }
2919 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
2920
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002921 f_shutdown_helper();
2922}
2923
2924/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
2925private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
2926 f_tc_stat_num_bts_connected_msc_connhdlr(1);
2927}
2928testcase TC_stat_num_bts_connected_1() runs on test_CT {
2929 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
2930}
2931
2932/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
2933private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
2934 f_tc_stat_num_bts_connected_msc_connhdlr(2);
2935}
2936testcase TC_stat_num_bts_connected_2() runs on test_CT {
2937 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
2938}
2939
2940/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
2941private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
2942 f_tc_stat_num_bts_connected_msc_connhdlr(3);
2943}
2944testcase TC_stat_num_bts_connected_3() runs on test_CT {
2945 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
2946}
2947
Harald Welte4003d112017-12-09 22:35:39 +01002948testcase TC_ctrl() runs on test_CT {
2949 var charstring ctrl_resp;
2950
Harald Welte89d42e82017-12-17 16:42:41 +01002951 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002952
2953 /* all below values must match the osmo-bsc.cfg config file used */
2954
Harald Welte6a129692018-03-17 17:30:14 +01002955 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2956 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002957 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002958
2959 var integer bts_nr := 0;
2960 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2961 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2962 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2963 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2964 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2965 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2966 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2967
2968 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2969 f_sleep(2.0);
2970 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2971 setverdict(fail, "oml-uptime not incrementing as expected");
2972 }
2973 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2974
2975 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2976
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002977 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002978}
2979
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002980/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2981 "location-state" over the SCCPlite IPA conn */
2982testcase TC_ctrl_location() runs on test_CT {
2983 var MSC_ConnHdlr vc_conn;
2984 var integer bts_nr := 0;
2985
2986 f_init(1, true);
2987 f_sleep(1.0);
2988
2989 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2990 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2991 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2992
2993 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2994 f_sleep(2.0);
2995
2996 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2997 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2998 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
2999
3000 /* should match the one from config */
3001 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3002
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003003 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003004}
3005
Harald Welte6f521d82017-12-11 19:52:02 +01003006
3007/***********************************************************************
3008 * Paging Testing
3009 ***********************************************************************/
3010
3011type record Cell_Identity {
3012 GsmMcc mcc,
3013 GsmMnc mnc,
3014 GsmLac lac,
3015 GsmCellId ci
3016};
Harald Welte24135bd2018-03-17 19:27:53 +01003017private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003018private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003019
Harald Welte5d1a2202017-12-13 19:51:29 +01003020type set of integer BtsIdList;
3021
3022private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3023 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3024 if (bts_id == bts_ids[j]) {
3025 return true;
3026 }
3027 }
3028 return false;
3029}
Harald Welte6f521d82017-12-11 19:52:02 +01003030
3031/* core paging test helper function; used by most paging test cases */
3032private function f_pageing_helper(hexstring imsi,
3033 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003034 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003035 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003036 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003037{
3038 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003039 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003040 var RSL_Message rx_rsl;
3041 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003042 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003043
3044 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003045
3046 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003047 for (i := 0; i < NUM_BTS; i := i + 1) {
3048 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003049 }
Harald Welte6f521d82017-12-11 19:52:02 +01003050
3051 if (isvalue(rsl_chneed)) {
3052 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3053 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3054 } else {
3055 bssmap_chneed := omit;
3056 }
3057
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003058 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3059 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003060
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003061 if (not istemplatekind(tmsi, "omit")) {
3062 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003063 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003064 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003065 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003066
Harald Welte5d1a2202017-12-13 19:51:29 +01003067 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003068 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003069 /* check channel type, paging group */
3070 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3071 setverdict(fail, "Paging for wrong paging group");
3072 }
3073 if (ispresent(rsl_chneed) and
3074 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3075 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3076 }
Harald Welte6f521d82017-12-11 19:52:02 +01003077 }
Harald Welte2fccd982018-01-31 15:48:19 +01003078 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003079 /* do a quick check on all not-included BTSs if they received paging */
3080 for (i := 0; i < NUM_BTS; i := i + 1) {
3081 timer T := 0.1;
3082 if (f_bts_in_list(i, bts_ids)) {
3083 continue;
3084 }
3085 T.start;
3086 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003087 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003088 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3089 }
3090 [] IPA_RSL[i].receive { repeat; }
3091 [] T.timeout { }
3092 }
Harald Welte6f521d82017-12-11 19:52:02 +01003093 }
3094
3095 setverdict(pass);
3096}
3097
Harald Welte5d1a2202017-12-13 19:51:29 +01003098const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003099const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003100const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3101const BtsIdList c_BtsId_LAC2 := { 2 };
3102
Harald Welte6f521d82017-12-11 19:52:02 +01003103/* PAGING by IMSI + TMSI */
3104testcase TC_paging_imsi_nochan() runs on test_CT {
3105 var BSSMAP_FIELD_CellIdentificationList cid_list;
3106 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003107 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003108 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003109}
3110
3111/* PAGING by IMSI + TMSI */
3112testcase TC_paging_tmsi_nochan() runs on test_CT {
3113 var BSSMAP_FIELD_CellIdentificationList cid_list;
3114 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003115 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003116 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003117}
3118
3119/* Paging with different "channel needed' values */
3120testcase TC_paging_tmsi_any() runs on test_CT {
3121 var BSSMAP_FIELD_CellIdentificationList cid_list;
3122 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003123 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003124 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003125}
3126testcase TC_paging_tmsi_sdcch() runs on test_CT {
3127 var BSSMAP_FIELD_CellIdentificationList cid_list;
3128 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003129 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003130 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003131}
3132testcase TC_paging_tmsi_tch_f() runs on test_CT {
3133 var BSSMAP_FIELD_CellIdentificationList cid_list;
3134 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003135 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003136 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003137}
3138testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3139 var BSSMAP_FIELD_CellIdentificationList cid_list;
3140 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003141 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003142 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003143}
3144
3145/* Paging by CGI */
3146testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3147 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3148 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003149 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003150 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003151}
3152
3153/* Paging by LAC+CI */
3154testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3155 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3156 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003157 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003158 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003159}
3160
3161/* Paging by CI */
3162testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3163 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3164 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003165 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003166 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003167}
3168
3169/* Paging by LAI */
3170testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3171 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3172 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003173 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003174 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003175}
3176
3177/* Paging by LAC */
3178testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3179 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3180 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003181 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003182 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003183}
3184
3185/* Paging by "all in BSS" */
3186testcase TC_paging_imsi_nochan_all() runs on test_CT {
3187 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3188 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003189 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003190 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003191}
3192
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003193/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003194testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3195 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3196 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 +01003197 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003198 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003199}
Harald Welte6f521d82017-12-11 19:52:02 +01003200
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003201/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003202testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3203 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3204 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003205 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003206 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003207}
3208
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003209/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003210testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3211 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3212 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003213 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003214 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003215}
3216
Harald Welte6f521d82017-12-11 19:52:02 +01003217/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003218testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3219 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3220 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3221 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003222 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003223}
3224
3225/* Paging on empty list: Verify none of them page */
3226testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3227 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3228 cid_list := { cIl_LAC := { } };
3229 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003230 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003231}
3232
Stefan Sperling049a86e2018-03-20 15:51:00 +01003233/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3234testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3235 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3236 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3237 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3238 f_shutdown_helper();
3239}
3240
Harald Welte6f521d82017-12-11 19:52:02 +01003241/* Verify paging retransmission interval + count */
3242/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003243/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003244
Harald Weltee65d40e2017-12-13 00:09:06 +01003245/* Verify PCH load */
3246testcase TC_paging_imsi_load() runs on test_CT {
3247 var BSSMAP_FIELD_CellIdentificationList cid_list;
3248 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003249 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003250 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003251 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003252
3253 /* tell BSC there is no paging space anymore */
3254 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003255 f_sleep(0.2);
3256 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003257
3258 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3259 * there would be 8 retransmissions during 4 seconds */
3260 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003261 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003262 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003263 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003264 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003265 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003266 }
Harald Welte2caa1062018-03-17 18:19:05 +01003267 [] T_retrans.timeout {
3268 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3269 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3270 T_retrans.start;
3271 repeat;
3272 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003273 [] T.timeout {
3274 setverdict(pass);
3275 }
3276 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003277
3278 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003279}
3280
Harald Welte235ebf12017-12-15 14:18:16 +01003281/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003282testcase TC_paging_counter() runs on test_CT {
3283 var BSSMAP_FIELD_CellIdentificationList cid_list;
3284 timer T := 4.0;
3285 var integer i;
3286 var integer paging_attempted_bsc;
3287 var integer paging_attempted_bts[NUM_BTS];
3288 var integer paging_expired_bts[NUM_BTS];
3289 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3290
3291 f_init();
3292
3293 /* read counters before paging */
3294 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3295 for (i := 0; i < NUM_BTS; i := i+1) {
3296 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3297 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3298 }
3299
3300 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3301
3302 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3303 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3304 for (i := 0; i < NUM_BTS; i := i+1) {
3305 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3306 paging_attempted_bts[i]+1);
3307 }
3308
3309 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3310 f_sleep(12.0);
3311 for (i := 0; i < NUM_BTS; i := i+1) {
3312 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3313 paging_expired_bts[i]+1);
3314 }
Harald Welte1ff69992017-12-14 12:31:17 +01003315
Philipp Maier282ca4b2018-02-27 17:17:00 +01003316 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003317}
3318
3319
Harald Welte10985002017-12-12 09:29:15 +01003320/* Verify paging stops after A-RESET */
3321testcase TC_paging_imsi_a_reset() runs on test_CT {
3322 var BSSMAP_FIELD_CellIdentificationList cid_list;
3323 timer T := 3.0;
3324 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003325 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003326
3327 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003328 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 +01003329 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003330 [] 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 +01003331 [] BSSAP.receive { repeat; }
3332 }
3333
Daniel Willmanncbef3982018-07-30 09:22:40 +02003334 /* Wait to avoid a possible race condition if a paging message is
3335 * received right before the reset ACK. */
3336 f_sleep(0.2);
3337
Harald Welte10985002017-12-12 09:29:15 +01003338 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003339 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3340 IPA_RSL[i].clear;
3341 }
Harald Welte10985002017-12-12 09:29:15 +01003342
3343 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3344 T.start;
3345 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003346 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003347 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003348 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003349 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003350 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003351 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003352 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003353 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003354 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003355 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003356 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003357 }
Harald Welte10985002017-12-12 09:29:15 +01003358 [] T.timeout {
3359 setverdict(pass);
3360 }
3361 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003362
3363 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003364}
Harald Welteae026692017-12-09 01:03:01 +01003365
Philipp Maierf45824a2019-08-14 14:44:10 +02003366/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3367 * paging response we can not know which MSC is in charge, so we will blindly
3368 * pick the first configured MSC. This behavior is required in order to make
3369 * MT-CSFB calls working because in those cases the BSC can not know that the
3370 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3371 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003372 */
3373testcase TC_paging_resp_unsol() runs on test_CT {
3374
3375 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003376 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003377
3378 var BSSAP_N_CONNECT_ind rx_c_ind;
3379 var DchanTuple dt;
3380 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003381 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003382
3383 /* Send CHAN RQD and wait for allocation; acknowledge it */
3384 dt.rsl_chan_nr := f_chreq_act_ack();
3385
3386 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3387 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3388
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003389
Philipp Maierf45824a2019-08-14 14:44:10 +02003390 /* Expevct a CR with a matching Paging response on the A-Interface */
3391 T.start;
3392 alt {
3393 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3394 setverdict(pass);
3395 }
3396 [] BSSAP.receive {
3397 setverdict(fail, "Received unexpected message on A-Interface!");
3398 }
3399 [] T.timeout {
3400 setverdict(fail, "Received nothing on A-Interface!");
3401 }
3402 }
3403
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003404 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003405}
3406
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003407/* Test RSL link drop causes counter increment */
3408testcase TC_rsl_drop_counter() runs on test_CT {
3409 var integer rsl_fail;
3410
Harald Welte89d42e82017-12-17 16:42:41 +01003411 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003412
3413 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3414
3415 bts[0].rsl.vc_IPA.stop;
3416
3417 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3418
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003419 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003420}
3421
3422/* TODO: Test OML link drop causes counter increment */
3423
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003424/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3425function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3426 timer T := 10.0;
3427
3428 bts[0].rsl.id := "IPA-0-RSL";
3429 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3430 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3431 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003432 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003433
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003434 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003435
3436 f_init_mgcp("VirtMSC");
3437
3438 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3439 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3440 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3441 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3442
3443 /* wait for IPA OML link to connect and then disconnect */
3444 T.start;
3445 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003446 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003447 T.stop;
3448 return true;
3449 }
3450 [] IPA_RSL[0].receive { repeat }
3451 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003452 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003453 }
3454 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003455 return false;
3456}
3457
3458/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3459testcase TC_rsl_unknown_unit_id() runs on test_CT {
3460 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3461 setverdict(pass);
3462 } else {
3463 setverdict(fail, "Timeout RSL waiting for connection to close");
3464 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003465 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003466}
3467
3468
3469/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3470testcase TC_oml_unknown_unit_id() runs on test_CT {
3471 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3472 setverdict(pass);
3473 } else {
3474 setverdict(fail, "Timeout OML waiting for connection to close");
3475 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003476 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003477}
3478
3479
Harald Weltec1a2fff2017-12-17 11:06:19 +01003480/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003481 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003482 ***********************************************************************/
3483
Harald Welte6811d102019-04-14 22:23:14 +02003484import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003485import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003486import from RSL_Emulation all;
3487import from MSC_ConnectionHandler all;
3488
3489type function void_fn(charstring id) runs on MSC_ConnHdlr;
3490
Harald Welte336820c2018-05-31 20:34:52 +02003491/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003492private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3493 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003494 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003495 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003496 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003497 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003498 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3499 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3500 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003501 if (isvalue(bts[2])) {
3502 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3503 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3504 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003505 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003506 if (mp_enable_lcs_tests) {
3507 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3508 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3509 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003510 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003511 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003512 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003513}
3514
Neels Hofmeyrda436782021-07-20 22:09:06 +02003515function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003516runs on test_CT return MSC_ConnHdlr {
3517 var charstring id := testcasename();
3518 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003519 var integer bssap_idx := 0;
3520 if (isvalue(pars)) {
3521 bssap_idx := valueof(pars).mscpool.bssap_idx;
3522 }
Harald Welte336820c2018-05-31 20:34:52 +02003523 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003524 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003525 return vc_conn;
3526}
3527
3528function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3529runs on test_CT return MSC_ConnHdlr {
3530 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003531 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003532 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003533 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003534 return vc_conn;
3535}
3536
Neels Hofmeyrda436782021-07-20 22:09:06 +02003537function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3538runs on test_CT return MSC_ConnHdlr {
3539 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3540}
3541
Harald Weltea0630032018-03-20 21:09:55 +01003542/* first function inside ConnHdlr component; sets g_pars + starts function */
3543private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3544runs on MSC_ConnHdlr {
3545 if (isvalue(pars)) {
3546 g_pars := valueof(pars);
3547 }
3548 fn.apply(id);
3549}
3550
Oliver Smith26a3db72021-07-09 13:51:29 +02003551private function f_vty_encryption_a5(charstring options) runs on test_CT {
3552 f_vty_transceive(BSCVTY, "configure terminal");
3553 f_vty_transceive(BSCVTY, "network");
3554 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3555 f_vty_transceive(BSCVTY, "exit");
3556 f_vty_transceive(BSCVTY, "exit");
3557}
3558
3559private function f_vty_encryption_a5_reset() runs on test_CT {
3560 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3561 f_vty_encryption_a5("0 1 3");
3562}
3563
Harald Welte3c86ea02018-05-10 22:28:05 +02003564/* Establish signalling channel (non-assignment case) followed by cipher mode */
3565private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003566 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3567 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003568 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003569 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3570 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3571 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3572 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003573
Philipp Maier23000732018-05-18 11:25:37 +02003574 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003575}
3576testcase TC_ciph_mode_a5_0() runs on test_CT {
3577 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003578 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003579 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3580
3581 f_init(1, true);
3582 f_sleep(1.0);
3583 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3584 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003585 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003586}
3587testcase TC_ciph_mode_a5_1() runs on test_CT {
3588 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003589 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003590 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3591
3592 f_init(1, true);
3593 f_sleep(1.0);
3594 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3595 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003596 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003597}
Oliver Smith50b98122021-07-09 15:00:28 +02003598/* OS#4975: verify that A5/2 is preferred over A5/0 */
3599testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3600 var MSC_ConnHdlr vc_conn;
3601 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3602
3603 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3604 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3605
3606 f_init(1, true);
3607 f_vty_encryption_a5("0 1 2 3");
3608 f_sleep(1.0);
3609 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3610 vc_conn.done;
3611 f_vty_encryption_a5_reset();
3612 f_shutdown_helper();
3613}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003614/* OS#4975: verify that A5/1 is preferred over A5/2 */
3615testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3616 var MSC_ConnHdlr vc_conn;
3617 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3618
3619 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3620 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3621
3622 f_init(1, true);
3623 f_vty_encryption_a5("1 2");
3624 f_sleep(1.0);
3625 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3626 vc_conn.done;
3627 f_vty_encryption_a5_reset();
3628 f_shutdown_helper();
3629}
Harald Welte3c86ea02018-05-10 22:28:05 +02003630testcase TC_ciph_mode_a5_3() runs on test_CT {
3631 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003632 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003633 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3634
3635 f_init(1, true);
3636 f_sleep(1.0);
3637 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3638 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003639 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003640}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003641/* Establish a Signalling channel with A5/4 encryption. */
3642testcase TC_ciph_mode_a5_4() runs on test_CT {
3643 var MSC_ConnHdlr vc_conn;
3644 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3645 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003646
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003647 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003648 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003649 f_sleep(1.0);
3650 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3651 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003652 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003653 f_shutdown_helper();
3654}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003655/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3656private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3657 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3658 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3659 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3660 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3661
3662 f_establish_fully(ass_cmd, exp_compl);
3663}
3664testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3665 var MSC_ConnHdlr vc_conn;
3666 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3667
3668 f_init(1, true);
3669 f_sleep(1.0);
3670 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3671 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003672 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003673}
3674
Harald Welte3c86ea02018-05-10 22:28:05 +02003675
3676/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003677private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003678 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3679 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003680
Harald Welte552620d2017-12-16 23:21:36 +01003681 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3682 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003683
Harald Weltea0630032018-03-20 21:09:55 +01003684 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003685}
Harald Welte552620d2017-12-16 23:21:36 +01003686testcase TC_assignment_fr_a5_0() runs on test_CT {
3687 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003688 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003689 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003690
Harald Welte89d42e82017-12-17 16:42:41 +01003691 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003692 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003693 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003694 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003695 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003696}
Harald Welte552620d2017-12-16 23:21:36 +01003697testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003698 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003699 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003700 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003701
Harald Welte89d42e82017-12-17 16:42:41 +01003702 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003703 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003704 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3705 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003706 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003707}
3708testcase TC_assignment_fr_a5_3() runs on test_CT {
3709 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003710 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003711 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003712
Harald Welte651fcdc2018-05-10 20:23:16 +02003713 f_init(1, true);
3714 f_sleep(1.0);
3715 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003716 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003717 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003718}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003719/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3720testcase TC_assignment_fr_a5_4() runs on test_CT {
3721 var MSC_ConnHdlr vc_conn;
3722 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3723 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3724
3725 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003726 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003727 f_sleep(1.0);
3728 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3729 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003730 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003731 f_shutdown_helper();
3732}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003733
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003734/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3735testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3736 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3737 var MSC_ConnHdlr vc_conn;
3738
3739 f_init(1, true);
3740 f_sleep(1.0);
3741
3742 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3743 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3744 vc_conn.done;
3745 f_shutdown_helper();
3746}
3747
Harald Welte552620d2017-12-16 23:21:36 +01003748/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3749private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003750 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003751 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003752 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003753
3754 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003755 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3756
Harald Weltea0630032018-03-20 21:09:55 +01003757 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003758}
Harald Welte552620d2017-12-16 23:21:36 +01003759testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3760 var MSC_ConnHdlr vc_conn;
3761
Harald Welte89d42e82017-12-17 16:42:41 +01003762 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003763 f_sleep(1.0);
3764
Harald Welte8863fa12018-05-10 20:15:27 +02003765 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003766 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003767 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003768}
3769
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003770private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3771 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3772 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003773
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003774 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3775 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3776
3777 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3778
3779 var BSSMAP_FIELD_CodecType codecType;
3780 timer T := 10.0;
3781
3782 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3783 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3784
3785 f_create_chan_and_exp();
3786 /* we should now have a COMPL_L3 at the MSC */
3787
3788 var template PDU_BSSAP exp_l3_compl;
3789 exp_l3_compl := tr_BSSMAP_ComplL3()
3790 if (g_pars.aoip == false) {
3791 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3792 } else {
3793 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3794 }
3795 T.start;
3796 alt {
3797 [] BSSAP.receive(exp_l3_compl);
3798 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3799 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3800 }
3801 [] T.timeout {
3802 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3803 }
3804 }
3805
3806 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003807 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003808}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003809testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3810 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003811 var MSC_ConnHdlr vc_conn;
3812
Harald Welte89d42e82017-12-17 16:42:41 +01003813 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003814 f_sleep(1.0);
3815
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003816 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003817 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003818 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003819 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003820}
3821
3822
Harald Welte4532e0a2017-12-23 02:05:44 +01003823private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003824 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003825 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003826 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003827 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003828
3829 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003830 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003831
3832 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003833 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3834 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003835 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3836 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3837 };
3838 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003839}
3840
3841testcase TC_assignment_sign() runs on test_CT {
3842 var MSC_ConnHdlr vc_conn;
3843
3844 f_init(1, true);
3845 f_sleep(1.0);
3846
Harald Welte8863fa12018-05-10 20:15:27 +02003847 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003848 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003849 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003850}
3851
Harald Welte60aa5762018-03-21 19:33:13 +01003852/***********************************************************************
3853 * Codec (list) testing
3854 ***********************************************************************/
3855
3856/* check if the given rsl_mode is compatible with the a_elem */
3857private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3858return boolean {
3859 select (a_elem.codecType) {
3860 case (GSM_FR) {
3861 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3862 return true;
3863 }
3864 }
3865 case (GSM_HR) {
3866 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3867 return true;
3868 }
3869 }
3870 case (GSM_EFR) {
3871 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3872 return true;
3873 }
3874 }
3875 case (FR_AMR) {
3876 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3877 return true;
3878 }
3879 }
3880 case (HR_AMR) {
3881 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3882 return true;
3883 }
3884 }
3885 case else { }
3886 }
3887 return false;
3888}
3889
3890/* check if the given rsl_mode is compatible with the a_list */
3891private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3892return boolean {
3893 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3894 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3895 return true;
3896 }
3897 }
3898 return false;
3899}
3900
3901/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003902function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003903return BSSMAP_IE_ChannelType {
3904 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3905 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3906 select (a_elem.codecType) {
3907 case (GSM_FR) {
3908 ret.channelRateAndType := ChRate_TCHF;
3909 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3910 }
3911 case (GSM_HR) {
3912 ret.channelRateAndType := ChRate_TCHH;
3913 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3914 }
3915 case (GSM_EFR) {
3916 ret.channelRateAndType := ChRate_TCHF;
3917 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3918 }
3919 case (FR_AMR) {
3920 ret.channelRateAndType := ChRate_TCHF;
3921 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3922 }
3923 case (HR_AMR) {
3924 ret.channelRateAndType := ChRate_TCHH;
3925 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3926 }
3927 case else {
3928 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003929 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003930 }
3931 }
3932 return ret;
3933}
3934
Harald Weltea63b9102018-03-22 20:36:16 +01003935private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3936return template RSL_IE_Body {
3937 var template RSL_IE_Body mode_ie := {
3938 chan_mode := {
3939 len := ?,
3940 reserved := ?,
3941 dtx_d := ?,
3942 dtx_u := ?,
3943 spd_ind := RSL_SPDI_SPEECH,
3944 ch_rate_type := -,
3945 coding_alg_rate := -
3946 }
3947 }
3948
3949 select (a_elem.codecType) {
3950 case (GSM_FR) {
3951 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3952 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3953 }
3954 case (GSM_HR) {
3955 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3956 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3957 }
3958 case (GSM_EFR) {
3959 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3960 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3961 }
3962 case (FR_AMR) {
3963 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3964 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3965 }
3966 case (HR_AMR) {
3967 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3968 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3969 }
3970 }
3971 return mode_ie;
3972}
3973
Harald Welte60aa5762018-03-21 19:33:13 +01003974type record CodecListTest {
3975 BSSMAP_IE_SpeechCodecList codec_list,
3976 charstring id
3977}
3978type record of CodecListTest CodecListTests
3979
3980private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003981 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3982 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003983
3984 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003985 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003986 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3987 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3988 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003989 if (isvalue(g_pars.expect_mr_s0_s7)) {
3990 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3991 g_pars.expect_mr_s0_s7;
3992 }
Harald Welte79f3f542018-05-25 20:02:37 +02003993 }
Harald Welte60aa5762018-03-21 19:33:13 +01003994 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3995 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003996 log("expecting ASS COMPL like this: ", exp_compl);
3997
3998 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01003999
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004000 if (not g_pars.expect_channel_mode_modify) {
4001 /* Verify that the RSL-side activation actually matches our expectations */
4002 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004003
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004004 var RSL_IE_Body mode_ie;
4005 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4006 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004007 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004008 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004009 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4010 if (not match(mode_ie, t_mode_ie)) {
4011 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4012 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004013 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004014
4015 var RSL_IE_Body mr_conf;
4016 if (g_pars.expect_mr_conf_ie != omit) {
4017 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4018 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4019 mtc.stop;
4020 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004021 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004022
4023 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4024 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4025 g_pars.expect_mr_conf_ie);
4026 }
4027 } else {
4028 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4029 log("found RSL MR CONFIG IE: ", mr_conf);
4030 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4031 mtc.stop;
4032 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004033 }
4034 }
Harald Welte60aa5762018-03-21 19:33:13 +01004035}
4036
Philipp Maierd0e64b02019-03-13 14:15:23 +01004037private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4038
4039 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4040 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4041
4042 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004043 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004044 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4045 }
4046 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4047 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4048 log("expecting ASS FAIL like this: ", exp_fail);
4049
4050 f_establish_fully(ass_cmd, exp_fail);
4051}
4052
Harald Welte60aa5762018-03-21 19:33:13 +01004053testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004054 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004055 var MSC_ConnHdlr vc_conn;
4056
4057 f_init(1, true);
4058 f_sleep(1.0);
4059
4060 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004061 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004062 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004063 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004064}
4065
4066testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004067 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004068 var MSC_ConnHdlr vc_conn;
4069
4070 f_init(1, true);
4071 f_sleep(1.0);
4072
4073 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004074 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004075 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004076 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004077}
4078
4079testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004080 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004081 var MSC_ConnHdlr vc_conn;
4082
4083 f_init(1, true);
4084 f_sleep(1.0);
4085
4086 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004087 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004088 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004089 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004090}
4091
Philipp Maierd0e64b02019-03-13 14:15:23 +01004092/* Allow 5,90k only (current default config) */
4093private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004094 f_vty_cfg_msc(BSCVTY, 0, {
4095 "amr-config 12_2k forbidden",
4096 "amr-config 10_2k forbidden",
4097 "amr-config 7_95k forbidden",
4098 "amr-config 7_40k forbidden",
4099 "amr-config 6_70k forbidden",
4100 "amr-config 5_90k allowed",
4101 "amr-config 5_15k forbidden",
4102 "amr-config 4_75k forbidden"
4103 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004104}
4105
4106/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4107 * ("Config-NB-Code = 1") */
4108private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004109 f_vty_cfg_msc(BSCVTY, 0, {
4110 "amr-config 12_2k allowed",
4111 "amr-config 10_2k forbidden",
4112 "amr-config 7_95k forbidden",
4113 "amr-config 7_40k allowed",
4114 "amr-config 6_70k forbidden",
4115 "amr-config 5_90k allowed",
4116 "amr-config 5_15k forbidden",
4117 "amr-config 4_75k allowed"
4118 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004119}
4120
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004121private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4122 var charstring tch;
4123 if (fr) {
4124 tch := "tch-f";
4125 } else {
4126 tch := "tch-h";
4127 }
4128 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4129}
4130
4131/* Set the AMR start-mode for this TCH back to the default configuration. */
4132private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4133 f_vty_amr_start_mode_set(fr, "auto");
4134}
4135
Harald Welte60aa5762018-03-21 19:33:13 +01004136testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004137 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004138 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004139
4140 /* Note: This setups the codec configuration. The parameter payload in
4141 * mr_conf must be consistant with the parameter codecElements in pars
4142 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004143 var RSL_IE_Body mr_conf := {
4144 other := {
4145 len := 2,
4146 payload := '2804'O
4147 }
4148 };
Harald Welte60aa5762018-03-21 19:33:13 +01004149
Philipp Maier7695a0d2018-09-27 17:52:14 +02004150 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004151 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004152 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4153 pars.expect_mr_conf_ie := mr_conf;
4154
Harald Welte60aa5762018-03-21 19:33:13 +01004155 f_init(1, true);
4156 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004157 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004158
Harald Welte8863fa12018-05-10 20:15:27 +02004159 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004160 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004161
4162 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004163 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004164}
4165
4166testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004167 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004168 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004169
4170 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004171 var RSL_IE_Body mr_conf := {
4172 other := {
4173 len := 2,
4174 payload := '2804'O
4175 }
4176 };
Harald Welte60aa5762018-03-21 19:33:13 +01004177
Philipp Maier7695a0d2018-09-27 17:52:14 +02004178 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004179 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004180 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4181 pars.expect_mr_conf_ie := mr_conf;
4182
Harald Welte60aa5762018-03-21 19:33:13 +01004183 f_init(1, true);
4184 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004185 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004186
Harald Welte8863fa12018-05-10 20:15:27 +02004187 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004188 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004189
4190 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004191 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004192}
4193
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004194/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4195testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4196 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4197 var MSC_ConnHdlr vc_conn;
4198
4199 f_init(1, true);
4200 f_sleep(1.0);
4201
4202 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4203 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4204 * expecting a Channel Mode Modify if the channel type is compatible. */
4205 f_disable_all_sdcch();
4206 f_disable_all_tch_h();
4207
4208 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4209 pars.expect_channel_mode_modify := true;
4210 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4211 vc_conn.done;
4212
4213 f_enable_all_sdcch();
4214 f_enable_all_tch();
4215 f_shutdown_helper();
4216}
4217
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004218/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4219testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4220 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4221 var MSC_ConnHdlr vc_conn;
4222
4223 var RSL_IE_Body mr_conf := {
4224 other := {
4225 len := 2,
4226 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4227 }
4228 };
4229
4230 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4231 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4232 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4233 pars.expect_mr_conf_ie := mr_conf;
4234
4235 f_init(1, true);
4236 f_sleep(1.0);
4237
4238 /* First set nonzero start mode bits */
4239 f_vty_amr_start_mode_set(true, "4");
4240 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4241 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4242 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4243 f_vty_amr_start_mode_set(true, "auto");
4244
4245 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4246 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004247
4248 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4249 f_vty_amr_start_mode_set(true, "1");
4250 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004251 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004252}
4253
Neels Hofmeyr21863562020-11-26 00:34:33 +00004254function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4255 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004256runs on test_CT {
4257
4258 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4259 var MSC_ConnHdlr vc_conn;
4260
4261 /* See note above */
4262 var RSL_IE_Body mr_conf := {
4263 other := {
4264 len := lengthof(mrconf),
4265 payload := mrconf
4266 }
4267 };
4268
4269 if (fr) {
4270 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4271 } else {
4272 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4273 }
4274 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4275 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4276 pars.expect_mr_conf_ie := mr_conf;
4277 pars.expect_mr_s0_s7 := exp_s8_s0;
4278
4279 f_init(1, true);
4280 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004281 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004282 f_sleep(1.0);
4283
4284 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4285 vc_conn.done;
4286 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004287 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004288}
4289
4290function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4291runs on test_CT {
4292
4293 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4294 var MSC_ConnHdlr vc_conn;
4295
4296 if (fr) {
4297 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4298 } else {
4299 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4300 }
4301 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4302 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4303
4304 f_init(1, true);
4305 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004306 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004307 f_sleep(1.0);
4308
4309 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4310 vc_conn.done;
4311 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004312 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004313}
4314
4315
4316/* Set S1, we expect an AMR multirate configuration IE with all four rates
4317 * set. */
4318testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004319 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004320 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004321}
4322
4323/* Set S1, we expect an AMR multirate configuration IE with the lower three
4324 * rates set. */
4325testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004326 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004327 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004328}
4329
4330/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4331 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4332testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004333 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004334 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004335}
4336
4337/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4338 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4339testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004340 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004341 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004342}
4343
4344/* The following block of tests selects more and more rates until all four
4345 * possible rates are in the active set (full rate) */
4346testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004347 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004348 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004349}
4350
4351testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004352 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004353 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004354}
4355
4356testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004357 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004358 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004359}
4360
4361testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004362 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004363 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004364}
4365
4366/* The following block of tests selects more and more rates until all three
4367 * possible rates are in the active set (half rate) */
4368testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004369 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004370 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004371}
4372
4373testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004374 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004375 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004376}
4377
4378testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004379 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004380 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004381}
4382
4383/* The following block tests what happens when the MSC does offer rate
4384 * configurations that are not supported by the BSC. Normally such situations
4385 * should not happen because the MSC gets informed by the BSC in advance via
4386 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4387 * to offer rates that are not applicable anyway. */
4388
4389testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004390 /* Try to include 12,2k in into the active set even though the channel
4391 * is half rate only. The BSC is expected to remove the 12,0k */
4392 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004393 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004394}
4395
4396testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004397 /* See what happens when all rates are selected at once. Since then
4398 * Also S1 is selected, this setting will be prefered and we should
4399 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4400 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004401 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004402}
4403
4404testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004405 /* Same as above, but with S1 missing, the MSC is then expected to
4406 * select the currently supported rates, which are also 12.2k, 7,40k,
4407 * 5,90k, and 4,75k, into the active set. */
4408 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'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_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004413 /* Try to select no rates at all */
4414 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004415 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004416}
4417
4418testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004419 /* Try to select only unsupported rates */
4420 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004421 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004422}
4423
4424testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004425 /* Try to select 12,2k for half rate */
4426 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004427 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004428}
4429
Neels Hofmeyr21863562020-11-26 00:34:33 +00004430testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4431 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4432 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004433 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004434}
4435
4436testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4437 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4438 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004439 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004440}
4441
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004442testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004443 /* "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 +00004444 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4445 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004446 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004447}
4448
4449testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004450 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4451 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004452 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004453 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004454}
4455
Philipp Maierac09bfc2019-01-08 13:41:39 +01004456private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004457 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4458 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4459 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4460 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004461}
4462
4463private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004464 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4465 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004466}
4467
4468private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004469 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4470 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4471 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4472 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4473 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4474 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004475}
4476
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004477private function f_disable_all_sdcch() runs on test_CT {
4478 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4479 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4480 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4481 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4482}
4483
4484private function f_enable_all_sdcch() runs on test_CT {
4485 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4486 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4487 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4488 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4489}
4490
Philipp Maierac09bfc2019-01-08 13:41:39 +01004491/* Allow HR only */
4492private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4493 g_pars := f_gen_test_hdlr_pars();
4494 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4495 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4496 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4497 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4498 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4499 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4500 f_establish_fully(ass_cmd, exp_compl);
4501}
4502
4503/* Allow FR only */
4504private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4505 g_pars := f_gen_test_hdlr_pars();
4506 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4507 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4508 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4509 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4510 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4511 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4512 f_establish_fully(ass_cmd, exp_compl);
4513}
4514
4515/* Allow HR only (expect assignment failure) */
4516private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4517 g_pars := f_gen_test_hdlr_pars();
4518 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4519 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4520 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4521 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4522 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4523 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4524 f_establish_fully(ass_cmd, exp_fail);
4525}
4526
4527/* Allow FR only (expect assignment failure) */
4528private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4529 g_pars := f_gen_test_hdlr_pars();
4530 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4531 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4532 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4533 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4534 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4535 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4536 f_establish_fully(ass_cmd, exp_fail);
4537}
4538
4539/* Allow FR and HR, but prefer FR */
4540private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4541 g_pars := f_gen_test_hdlr_pars();
4542 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4543 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4544 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4545 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4546 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4547 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4548 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4549 f_establish_fully(ass_cmd, exp_compl);
4550}
4551
4552/* Allow FR and HR, but prefer HR */
4553private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4554 g_pars := f_gen_test_hdlr_pars();
4555 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4556 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4557 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4558 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4559 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4560 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4561 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4562 f_establish_fully(ass_cmd, exp_compl);
4563}
4564
4565/* Allow FR and HR, but prefer FR */
4566private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4567 g_pars := f_gen_test_hdlr_pars();
4568 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4569 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4570 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4571 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4572 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4573 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4574 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4575 f_establish_fully(ass_cmd, exp_compl);
4576}
4577
4578/* Allow FR and HR, but prefer HR */
4579private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4580 g_pars := f_gen_test_hdlr_pars();
4581 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4582 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4583 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4584 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4585 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4586 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4587 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4588 f_establish_fully(ass_cmd, exp_compl);
4589}
4590
4591/* Request a HR channel while all FR channels are exhausted, this is expected
4592 * to work without conflicts */
4593testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4594 var MSC_ConnHdlr vc_conn;
4595 f_init(1, true);
4596 f_sleep(1.0);
4597 f_enable_all_tch();
4598 f_disable_all_tch_f();
4599 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4600 vc_conn.done;
4601 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004602 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004603}
4604
4605/* Request a FR channel while all FR channels are exhausted, this is expected
4606 * to fail. */
4607testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4608 var MSC_ConnHdlr vc_conn;
4609 f_init(1, true);
4610 f_sleep(1.0);
4611 f_enable_all_tch();
4612 f_disable_all_tch_f();
4613 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4614 vc_conn.done;
4615 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004616 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004617}
4618
4619/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4620 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4621testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4622 var MSC_ConnHdlr vc_conn;
4623 f_init(1, true);
4624 f_sleep(1.0);
4625 f_enable_all_tch();
4626 f_disable_all_tch_f();
4627 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4628 vc_conn.done;
4629 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004630 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004631}
4632
4633/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4634 * are exhausted, this is expected to work without conflicts. */
4635testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4636 var MSC_ConnHdlr vc_conn;
4637 f_init(1, true);
4638 f_sleep(1.0);
4639 f_enable_all_tch();
4640 f_disable_all_tch_f();
4641 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4642 vc_conn.done;
4643 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004644 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004645}
4646
4647/* Request a FR channel while all HR channels are exhausted, this is expected
4648 * to work without conflicts */
4649testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4650 var MSC_ConnHdlr vc_conn;
4651 f_init(1, true);
4652 f_sleep(1.0);
4653 f_enable_all_tch();
4654 f_disable_all_tch_h();
4655 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4656 vc_conn.done;
4657 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004658 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004659}
4660
4661/* Request a HR channel while all HR channels are exhausted, this is expected
4662 * to fail. */
4663testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4664 var MSC_ConnHdlr vc_conn;
4665 f_init(1, true);
4666 f_sleep(1.0);
4667 f_enable_all_tch();
4668 f_disable_all_tch_h();
4669 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4670 vc_conn.done;
4671 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004672 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004673}
4674
4675/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4676 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4677testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4678 var MSC_ConnHdlr vc_conn;
4679 f_init(1, true);
4680 f_sleep(1.0);
4681 f_enable_all_tch();
4682 f_disable_all_tch_h();
4683 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4684 vc_conn.done;
4685 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004686 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004687}
4688
4689/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4690 * are exhausted, this is expected to work without conflicts. */
4691testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4692 var MSC_ConnHdlr vc_conn;
4693 f_init(1, true);
4694 f_sleep(1.0);
4695 f_enable_all_tch();
4696 f_disable_all_tch_h();
4697 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4698 vc_conn.done;
4699 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004700 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004701}
4702
4703/* Allow FR and HR, but prefer HR */
4704private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4705 g_pars := f_gen_test_hdlr_pars();
4706 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4707 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4708 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4709 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4710 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4711 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4712 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4713 f_establish_fully(ass_cmd, exp_compl);
4714}
4715
4716/* Allow FR and HR, but prefer FR */
4717private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4718 g_pars := f_gen_test_hdlr_pars();
4719 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4720 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4721 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4722 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4723 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4724 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4725 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4726 f_establish_fully(ass_cmd, exp_compl);
4727}
4728
4729/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4730 * HR, which is the prefered type, is selected. */
4731testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4732 var MSC_ConnHdlr vc_conn;
4733 f_init(1, true);
4734 f_sleep(1.0);
4735 f_enable_all_tch();
4736 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4737 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004738 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004739}
4740
4741/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4742 * FR, which is the prefered type, is selected. */
4743testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4744 var MSC_ConnHdlr vc_conn;
4745 f_init(1, true);
4746 f_sleep(1.0);
4747 f_enable_all_tch();
4748 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4749 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004750 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004751}
4752
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004753/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4754private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4755 g_pars := f_gen_test_hdlr_pars();
4756 g_pars.ra := '02'O; /* RA containing reason=LU */
4757
4758 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4759 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4760 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4761 var template uint3_t tsc := ?;
4762
4763 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4764 f_create_bssmap_exp(l3_enc);
4765 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4766 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4767
4768 /* we should now have a COMPL_L3 at the MSC */
4769 timer T := 10.0;
4770 T.start;
4771 alt {
4772 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4773 [] T.timeout {
4774 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4775 }
4776 }
4777}
4778testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4779 var MSC_ConnHdlr vc_conn;
4780 f_init(1, true);
4781 f_sleep(1.0);
4782 f_disable_all_sdcch();
4783 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4784 vc_conn.done;
4785 f_enable_all_sdcch();
4786 f_shutdown_helper();
4787}
4788
4789/* Request a signalling channel with all SDCCH exhausted, it is
4790 expected that no TCH will be selected for signalling and assigment will fail
4791 because it's dictated by VTY config */
4792testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4793 var RSL_Message rsl_unused, rsl_msg;
4794 var GsmRrMessage rr;
4795 f_init(1, false);
4796 f_sleep(1.0);
4797 f_vty_allow_tch_for_signalling(false, 0);
4798 f_disable_all_sdcch();
4799
4800 /* RA containing reason=LU */
4801 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4802 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4803 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4804 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4805 setverdict(fail, "Expected reject");
4806 }
4807
4808 f_vty_allow_tch_for_signalling(true, 0);
4809 f_enable_all_sdcch();
4810 f_shutdown_helper();
4811}
4812
4813/* Request a voice channel with all SDCCH exhausted, it is
4814 * expected that TCH channel will be allocated since the VTY option is only
4815 * aimed at signalling requests */
4816private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4817 g_pars := f_gen_test_hdlr_pars();
4818 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4819
4820 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4821 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4822 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4823 var template uint3_t tsc := ?;
4824
4825 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4826 f_create_bssmap_exp(l3_enc);
4827 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4828 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4829
4830 /* we should now have a COMPL_L3 at the MSC */
4831 timer T := 10.0;
4832 T.start;
4833 alt {
4834 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4835 [] T.timeout {
4836 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4837 }
4838 }
4839}
4840testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4841 var MSC_ConnHdlr vc_conn;
4842 f_init(1, true);
4843 f_sleep(1.0);
4844 f_vty_allow_tch_for_signalling(false, 0);
4845 f_disable_all_sdcch();
4846
4847 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4848 vc_conn.done;
4849
4850 f_vty_allow_tch_for_signalling(true, 0);
4851 f_enable_all_sdcch();
4852 f_shutdown_helper();
4853}
4854
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004855testcase TC_assignment_osmux() runs on test_CT {
4856 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4857 var MSC_ConnHdlr vc_conn;
4858
4859 /* See note above */
4860 var RSL_IE_Body mr_conf := {
4861 other := {
4862 len := 2,
4863 payload := '2804'O
4864 }
4865 };
4866
4867 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4868 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4869 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4870 pars.expect_mr_conf_ie := mr_conf;
4871 pars.use_osmux := true;
4872
4873 f_init(1, true, true);
4874 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004875 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004876
4877 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4878 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004879
4880 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004881 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004882}
4883
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004884/* test the procedure of the MSC requesting a Classmark Update:
4885 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4886 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004887private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004888 g_pars := f_gen_test_hdlr_pars();
4889
Harald Weltea0630032018-03-20 21:09:55 +01004890 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004891 /* we should now have a COMPL_L3 at the MSC */
4892 BSSAP.receive(tr_BSSMAP_ComplL3);
4893
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004894 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4895 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4896
Harald Welte898113b2018-01-31 18:32:21 +01004897 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4898 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4899 setverdict(pass);
4900}
4901testcase TC_classmark() runs on test_CT {
4902 var MSC_ConnHdlr vc_conn;
4903 f_init(1, true);
4904 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004905 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004906 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004907 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004908}
4909
Harald Welteeddf0e92020-06-21 19:42:15 +02004910/* Send a CommonID from the simulated MSC and verify that the information is used to
4911 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4912private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4913 g_pars := f_gen_test_hdlr_pars();
4914 f_MscConnHdlr_init_vty();
4915
4916 f_create_chan_and_exp();
4917 /* we should now have a COMPL_L3 at the MSC */
4918 BSSAP.receive(tr_BSSMAP_ComplL3);
4919
4920 /* Send CommonID */
4921 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4922
4923 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4924 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4925 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4926
4927 setverdict(pass);
4928}
4929testcase TC_common_id() runs on test_CT {
4930 var MSC_ConnHdlr vc_conn;
4931 f_init(1, true);
4932 f_sleep(1.0);
4933 vc_conn := f_start_handler(refers(f_tc_common_id));
4934 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004935 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004936}
4937
Harald Weltee3bd6582018-01-31 22:51:25 +01004938private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004939 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004940 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004941 /* we should now have a COMPL_L3 at the MSC */
4942 BSSAP.receive(tr_BSSMAP_ComplL3);
4943
Harald Weltee3bd6582018-01-31 22:51:25 +01004944 /* send the single message we want to send */
4945 f_rsl_send_l3(l3);
4946}
4947
4948private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4949 timer T := sec;
4950 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004951 T.start;
4952 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004953 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4954 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004955 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004956 }
4957 [] T.timeout {
4958 setverdict(pass);
4959 }
4960 }
4961}
4962
Harald Weltee3bd6582018-01-31 22:51:25 +01004963/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4964private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4965 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4966 f_bssap_expect_nothing();
4967}
Harald Welte898113b2018-01-31 18:32:21 +01004968testcase TC_unsol_ass_fail() runs on test_CT {
4969 var MSC_ConnHdlr vc_conn;
4970 f_init(1, true);
4971 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004972 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004973 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004974 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004975}
Harald Welte552620d2017-12-16 23:21:36 +01004976
Harald Welteea99a002018-01-31 20:46:43 +01004977
4978/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4979private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004980 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4981 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004982}
4983testcase TC_unsol_ass_compl() runs on test_CT {
4984 var MSC_ConnHdlr vc_conn;
4985 f_init(1, true);
4986 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004987 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004988 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004989 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004990}
4991
4992
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004993/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4994private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004995 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4996 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004997}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004998testcase TC_unsol_ho_fail() runs on test_CT {
4999 var MSC_ConnHdlr vc_conn;
5000 f_init(1, true);
5001 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005002 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005003 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005004 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005005}
5006
5007
Harald Weltee3bd6582018-01-31 22:51:25 +01005008/* short message from MS should be ignored */
5009private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005010 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005011 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005012 /* we should now have a COMPL_L3 at the MSC */
5013 BSSAP.receive(tr_BSSMAP_ComplL3);
5014
5015 /* send short message */
5016 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5017 f_bssap_expect_nothing();
5018}
5019testcase TC_err_82_short_msg() runs on test_CT {
5020 var MSC_ConnHdlr vc_conn;
5021 f_init(1, true);
5022 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005023 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005024 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005025 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005026}
5027
5028
Harald Weltee9e02e42018-01-31 23:36:25 +01005029/* 24.008 8.4 Unknown message must trigger RR STATUS */
5030private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5031 f_est_single_l3(ts_RRM_UL_REL('00'O));
5032 timer T := 3.0
5033 alt {
5034 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5035 setverdict(pass);
5036 }
5037 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005038 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005039 }
5040}
5041testcase TC_err_84_unknown_msg() runs on test_CT {
5042 var MSC_ConnHdlr vc_conn;
5043 f_init(1, true);
5044 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005045 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005046 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005047 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005048}
5049
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005050/***********************************************************************
5051 * Handover
5052 ***********************************************************************/
5053
Harald Welte94e0c342018-04-07 11:33:23 +02005054/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5055private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5056runs on test_CT {
5057 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5058 " timeslot "&int2str(ts_nr)&" ";
5059 f_vty_transceive(BSCVTY, cmd & suffix);
5060}
5061
Harald Welte261af4b2018-02-12 21:20:39 +01005062/* 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 +07005063private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5064 uint8_t bts_nr, uint8_t trx_nr,
5065 in RslChannelNr chan_nr)
5066{
Harald Welte261af4b2018-02-12 21:20:39 +01005067 /* FIXME: resolve those from component-global state */
5068 var integer ts_nr := chan_nr.tn;
5069 var integer ss_nr;
5070 if (ischosen(chan_nr.u.ch0)) {
5071 ss_nr := 0;
5072 } else if (ischosen(chan_nr.u.lm)) {
5073 ss_nr := chan_nr.u.lm.sub_chan;
5074 } else if (ischosen(chan_nr.u.sdcch4)) {
5075 ss_nr := chan_nr.u.sdcch4.sub_chan;
5076 } else if (ischosen(chan_nr.u.sdcch8)) {
5077 ss_nr := chan_nr.u.sdcch8.sub_chan;
5078 } else {
5079 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005080 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005081 }
5082
5083 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5084 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005085 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005086}
5087
Neels Hofmeyr91401012019-07-11 00:42:35 +02005088/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5089 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5090 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5091 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5092 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005093private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5094 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5095{
5096 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005097}
5098
5099/* intra-BSC hand-over between BTS0 and BTS1 */
5100private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005101 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5102 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005103
5104 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5105 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5106
Harald Weltea0630032018-03-20 21:09:55 +01005107 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005108 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005109
5110 var HandoverState hs := {
5111 rr_ho_cmpl_seen := false,
5112 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005113 old_chan_nr := -,
5114 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005115 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005116 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005117 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005118 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5119 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005120
5121 /* From the MGW perspective, a handover is is characterized by
5122 * performing one MDCX operation with the MGW. So we expect to see
5123 * one more MDCX during handover. */
5124 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5125
Harald Welte261af4b2018-02-12 21:20:39 +01005126 alt {
5127 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005128 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005129
Philipp Maier4dae0652018-11-12 12:03:26 +01005130 /* Since this is an internal handover we expect the BSC to inform the
5131 * MSC about the event */
5132 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5133
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005134 /* Check the amount of MGCP transactions is still consistant with the
5135 * test expectation */
5136 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005137
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005138 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5139
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005140 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5141 * 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 +02005142 f_verify_encr_info(chan_act);
5143
5144 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005145
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005146 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005147}
5148
5149testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005150 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005151 var MSC_ConnHdlr vc_conn;
5152 f_init(2, true);
5153 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005154
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005155 pars.expect_tsc := BTS_TSC[0];
5156
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005157 f_ctrs_bsc_and_bts_init();
5158
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005159 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005160 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005161
5162 /* from f_establish_fully() */
5163 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5164 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5165 /* from handover */
5166 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5167 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5168 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5169 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5170 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005171 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005172}
Harald Weltee9e02e42018-01-31 23:36:25 +01005173
Oliver Smith7eabd312021-07-12 14:18:56 +02005174function 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 +02005175 var MSC_ConnHdlr vc_conn;
5176 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5177 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5178
5179 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005180 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005181 f_sleep(1.0);
5182
5183 f_ctrs_bsc_and_bts_init();
5184
5185 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5186 vc_conn.done;
5187
5188 /* from f_establish_fully() */
5189 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5190 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5191 /* from handover */
5192 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5193 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5194 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5195 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5196 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005197 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005198 f_shutdown_helper();
5199}
5200
5201testcase TC_ho_int_a5_0() runs on test_CT {
5202 f_tc_ho_int_a5('01'O);
5203}
5204
5205testcase TC_ho_int_a5_1() runs on test_CT {
5206 f_tc_ho_int_a5('02'O);
5207}
5208
5209testcase TC_ho_int_a5_3() runs on test_CT {
5210 f_tc_ho_int_a5('08'O);
5211}
5212
5213testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005214 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005215}
5216
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005217/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5218private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5219 g_pars := f_gen_test_hdlr_pars();
5220 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5221 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005222
5223 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5224 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5225
5226 f_establish_fully(ass_cmd, exp_compl);
5227 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5228
5229 var HandoverState hs := {
5230 rr_ho_cmpl_seen := false,
5231 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005232 old_chan_nr := -,
5233 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005234 };
5235 /* issue hand-over command on VTY */
5236 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5237 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5238 f_rslem_suspend(RSL1_PROC);
5239
5240 /* From the MGW perspective, a handover is is characterized by
5241 * performing one MDCX operation with the MGW. So we expect to see
5242 * one more MDCX during handover. */
5243 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5244
5245 var RSL_Message rsl;
5246 var PDU_ML3_NW_MS l3;
5247 var RslChannelNr new_chan_nr;
5248 var GsmArfcn arfcn;
5249 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5250 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5251 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5252 setverdict(fail, "Expected handoverCommand");
5253 mtc.stop;
5254 }
5255 }
5256 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5257 new_chan_nr, arfcn);
5258
5259 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5260
5261 /* resume processing of RSL DChan messages, which was temporarily suspended
5262 * before performing a hand-over */
5263 f_rslem_resume(RSL1_PROC);
5264 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5265
5266 f_sleep(1.0);
5267
5268 /* Handover fails because no HANDO DET appears on the new lchan,
5269 * and the old lchan reports a Radio Link Failure. */
5270 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5271
5272 var PDU_BSSAP rx_clear_request;
5273 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5274 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5275 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5276
5277 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5278
5279 var MgcpCommand mgcp;
5280 interleave {
5281 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5282 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005283 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005284 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005285 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005286 }
5287 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005288 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005289 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005290 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005291 }
5292 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5293 }
5294
5295 f_sleep(0.5);
5296 setverdict(pass);
5297}
5298testcase TC_ho_int_radio_link_failure() runs on test_CT {
5299 var MSC_ConnHdlr vc_conn;
5300 f_init(2, true);
5301 f_sleep(1.0);
5302
5303 f_ctrs_bsc_and_bts_init();
5304
5305 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5306 vc_conn.done;
5307
5308 /* from f_establish_fully() */
5309 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5310 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5311 /* from handover */
5312 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5313 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5314 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5315 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
5316 f_ctrs_bsc_and_bts_verify();
5317 f_shutdown_helper();
5318}
5319
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005320/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005321private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005322 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005323 var template MgcpResponse mgcp_resp;
5324 var MGCP_RecvFrom mrf;
5325 var template MgcpMessage msg_resp;
5326 var template MgcpMessage msg_dlcx := {
5327 command := tr_DLCX()
5328 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005329
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005330 if (g_pars.aoip) {
5331 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005332 log("Got first DLCX: ", mgcp);
5333 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005334 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005335
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005336 MGCP.receive(tr_DLCX()) -> value mgcp {
5337 log("Got second DLCX: ", mgcp);
5338 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5339 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005340 } else {
5341 /* For SCCPLite, BSC doesn't handle the MSC-side */
5342 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5343 log("Got first DLCX: ", mrf.msg.command);
5344 msg_resp := {
5345 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5346 }
5347 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5348 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005349 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005350}
5351
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005352private 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 +01005353
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005354 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005355 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5356
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005357 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005358
5359 f_sleep(0.5);
5360 /* The MSC negotiates Handover Request and Handover Request Ack with
5361 * the other BSS and comes back with a BSSMAP Handover Command
5362 * containing an RR Handover Command coming from the target BSS... */
5363
5364 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5365 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5366 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5367 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5368 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5369
5370 /* expect the Handover Command to go out on RR */
5371 var RSL_Message rsl_ho_cmd
5372 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5373 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5374 var RSL_IE_Body rsl_ho_cmd_l3;
5375 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5376 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5377 setverdict(fail);
5378 } else {
5379 log("Found L3 Info: ", rsl_ho_cmd_l3);
5380 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5381 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5382 setverdict(fail);
5383 } else {
5384 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5385 setverdict(pass);
5386 }
5387 }
5388
5389 /* When the other BSS has reported a completed handover, this side is
5390 * torn down. */
5391
5392 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5393 var BssmapCause cause := enum2int(cause_val);
5394 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5395
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005396 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005397
5398 interleave {
5399 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5400 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5401 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005402 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005403 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005404 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005405}
5406
5407private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5408 g_pars := f_gen_test_hdlr_pars();
5409 var PDU_BSSAP ass_req := f_gen_ass_req();
5410 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5411 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5412 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5413 f_establish_fully(ass_req, exp_compl);
5414
5415 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005416}
5417testcase TC_ho_out_of_this_bsc() runs on test_CT {
5418 var MSC_ConnHdlr vc_conn;
5419
5420 f_init(1, true);
5421 f_sleep(1.0);
5422
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005423 f_ctrs_bsc_and_bts_init();
5424
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005425 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5426 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005427
5428 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5429 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5430 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5431 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5432 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5433 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5434 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005435 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005436}
5437
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005438private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5439 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005440 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005441 octetstring l3 := '0123456789'O)
5442runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005443 /* The old lchan and conn should still be active. See that arbitrary L3
5444 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005445 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005446 var template PDU_BSSAP exp_data := {
5447 discriminator := '1'B,
5448 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005449 dlci := dlci,
5450 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005451 pdu := {
5452 dtap := l3
5453 }
5454 };
5455 BSSAP.receive(exp_data);
5456 setverdict(pass);
5457}
5458
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005459private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5460 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005461 template (value) OCT1 dlci := '00'O,
5462 octetstring l3 := '0123456789'O)
5463runs on MSC_ConnHdlr {
5464 BSSAP.send(PDU_BSSAP:{
5465 discriminator := '1'B,
5466 spare := '0000000'B,
5467 dlci := dlci,
5468 lengthIndicator := lengthof(l3),
5469 pdu := {
5470 dtap := l3
5471 }
5472 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005473 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005474 setverdict(pass);
5475}
5476
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005477/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5478 * simply never sends a BSSMAP Handover Command. */
5479private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005480 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005481
5482 var PDU_BSSAP ass_req := f_gen_ass_req();
5483 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5484 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5485 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5486 f_establish_fully(ass_req, exp_compl);
5487
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005488 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005489 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5490
5491 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5492
5493 /* osmo-bsc should time out 10 seconds after the handover started.
5494 * Let's give it a bit extra. */
5495 f_sleep(15.0);
5496
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005497 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005498 f_sleep(1.0);
5499}
5500testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5501 var MSC_ConnHdlr vc_conn;
5502
5503 f_init(1, true);
5504 f_sleep(1.0);
5505
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005506 f_ctrs_bsc_and_bts_init();
5507
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005508 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5509 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005510
5511 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5512 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5513 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5514 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5515 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5516 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5517 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005518 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005519}
5520
5521/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5522 * RR Handover Failure. */
5523private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005524 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005525
5526 var PDU_BSSAP ass_req := f_gen_ass_req();
5527 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5528 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5529 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5530 f_establish_fully(ass_req, exp_compl);
5531
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005532 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005533 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5534
5535 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5536
5537 f_sleep(0.5);
5538 /* The MSC negotiates Handover Request and Handover Request Ack with
5539 * the other BSS and comes back with a BSSMAP Handover Command
5540 * containing an RR Handover Command coming from the target BSS... */
5541
5542 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5543 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5544 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5545 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5546 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5547
5548 /* expect the Handover Command to go out on RR */
5549 var RSL_Message rsl_ho_cmd
5550 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5551 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5552 var RSL_IE_Body rsl_ho_cmd_l3;
5553 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5554 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5555 setverdict(fail);
5556 } else {
5557 log("Found L3 Info: ", rsl_ho_cmd_l3);
5558 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5559 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5560 setverdict(fail);
5561 } else {
5562 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5563 setverdict(pass);
5564 }
5565 }
5566
5567 f_sleep(0.2);
5568 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5569
5570 /* Should tell the MSC about the failure */
5571 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5572
5573 f_sleep(1.0);
5574
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005575 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005576 f_sleep(1.0);
5577
5578 setverdict(pass);
5579 f_sleep(1.0);
5580}
5581testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5582 var MSC_ConnHdlr vc_conn;
5583
5584 f_init(1, true);
5585 f_sleep(1.0);
5586
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005587 f_ctrs_bsc_and_bts_init();
5588
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005589 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5590 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005591
5592 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5593 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5594 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5595 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5596 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5597 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5598 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005599 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005600}
5601
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005602/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5603 * (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 +02005604 * and the lchan is released. */
5605private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005606 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005607
5608 var PDU_BSSAP ass_req := f_gen_ass_req();
5609 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5610 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5611 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5612 f_establish_fully(ass_req, exp_compl);
5613
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005614 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005615 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5616
5617 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5618
5619 f_sleep(0.5);
5620 /* The MSC negotiates Handover Request and Handover Request Ack with
5621 * the other BSS and comes back with a BSSMAP Handover Command
5622 * containing an RR Handover Command coming from the target BSS... */
5623
5624 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5625 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5626 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5627 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5628 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5629
5630 /* expect the Handover Command to go out on RR */
5631 var RSL_Message rsl_ho_cmd
5632 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5633 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5634 var RSL_IE_Body rsl_ho_cmd_l3;
5635 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5636 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5637 setverdict(fail);
5638 } else {
5639 log("Found L3 Info: ", rsl_ho_cmd_l3);
5640 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5641 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5642 setverdict(fail);
5643 } else {
5644 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5645 setverdict(pass);
5646 }
5647 }
5648
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005649 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5650 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5651 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005652
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005653 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005654 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5655 log("Got BSSMAP Clear Request");
5656 /* Instruct BSC to clear channel */
5657 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5658 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5659
5660 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005661 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005662 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5663 log("Got Deact SACCH");
5664 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005665 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005666 log("Got RR Release");
5667 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005668 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005669 log("Got RF Chan Rel");
5670 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005671 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005672 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005673 }
5674
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005675 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005676 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005677
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005678 setverdict(pass);
5679 f_sleep(1.0);
5680}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005681testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005682 var MSC_ConnHdlr vc_conn;
5683
5684 f_init(1, true);
5685 f_sleep(1.0);
5686
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005687 f_ctrs_bsc_and_bts_init();
5688
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005689 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005690 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005691
5692 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5693 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5694 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5695 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5696 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5697 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5698 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005699 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005700}
5701
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005702private 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 +01005703 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5704 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5705 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5706 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5707 * before we get started. */
5708 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5709 f_rslem_register(0, new_chan_nr);
5710 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005711 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005712 f_sleep(1.0);
5713
5714 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5715 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5716 activate(as_Media());
5717
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005718 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005719 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005720 oldToNewBSSIEs := oldToNewBSSIEs,
5721 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005722 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005723
5724 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5725
5726 var PDU_BSSAP rx_bssap;
5727 var octetstring ho_command_str;
5728
5729 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005730
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005731 /* we're sure that the channel activation is done now, verify the parameters in it */
5732 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
5733 f_verify_encr_info(chan_act);
5734 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005735
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005736 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5737 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5738 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5739 log("L3 Info in HO Request Ack is ", ho_command);
5740
5741 var GsmArfcn arfcn;
5742 var RslChannelNr actual_new_chan_nr;
5743 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5744 actual_new_chan_nr, arfcn);
5745
5746 if (actual_new_chan_nr != new_chan_nr) {
5747 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5748 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5749 setverdict(fail);
5750 return;
5751 }
5752 log("Handover Command chan_nr is", actual_new_chan_nr);
5753
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005754 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
5755 if (not match(got_tsc, expect_target_tsc)) {
5756 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
5757 expect_target_tsc, " got ", got_tsc);
5758 mtc.stop;
5759 } else {
5760 log("handoverCommand: verified TSC = ", got_tsc);
5761 }
5762
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005763 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5764 * tells the MS to handover to the new lchan. Here comes the new MS on
5765 * the new lchan with a Handover RACH: */
5766
5767 /* send handover detect */
5768
5769 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5770
5771 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5772
5773 /* send handover complete over the new channel */
5774
5775 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5776 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5777 enc_PDU_ML3_MS_NW(l3_tx)));
5778
5779 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005780 setverdict(pass);
5781}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005782
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005783private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005784 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005785 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5786 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5787 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005788 }
5789 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005790 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005791 } else {
5792 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005793 }
5794 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005795 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005796 setverdict(pass);
5797}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005798function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005799 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005800
5801 f_init(1, true);
5802 f_sleep(1.0);
5803
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005804 f_ctrs_bsc_and_bts_init();
5805
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005806 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5807 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005808
5809 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5810 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005811
5812 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5813 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5814 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5815 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5816 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005817}
5818
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005819testcase TC_ho_into_this_bsc() runs on test_CT {
5820 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5821 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005822 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005823}
5824
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005825function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5826 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5827 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5828 f_tc_ho_into_this_bsc_main(pars);
5829 f_shutdown_helper();
5830}
5831
5832testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5833 f_tc_ho_into_this_bsc_a5('01'O);
5834}
5835
5836testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5837 f_tc_ho_into_this_bsc_a5('02'O);
5838}
5839
5840testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5841 f_tc_ho_into_this_bsc_a5('08'O);
5842}
5843
5844testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5845 f_tc_ho_into_this_bsc_a5('10'O);
5846}
5847
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005848testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5849 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5850 pars.host_aoip_tla := "::6";
5851 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005852 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005853}
5854
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005855/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005856 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005857 channel is later released (RR CHannel Release), should trigger inclusion of
5858 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5859 neighbors. */
5860testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5861 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5862 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005863 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005864 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005865
5866 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5867 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5868 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005869 f_shutdown_helper();
5870}
5871
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005872/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5873 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5874 list when the channel is released. */
5875testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5876 f_init_vty();
5877 f_vty_allow_srvcc_fast_return(true, 0)
5878
5879 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5880 pars.last_used_eutran_plmn := '323454'O;
5881 pars.exp_fast_return := false;
5882 f_tc_ho_into_this_bsc_main(pars);
5883 f_vty_allow_srvcc_fast_return(false, 0);
5884 f_shutdown_helper();
5885}
5886
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005887private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5888 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5889 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5890 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5891 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5892 setverdict(pass);
5893}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005894
5895private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5896 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005897 var MSC_ConnHdlr vc_conn;
5898 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5899
5900 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005901 if (disable_fast_return) {
5902 f_vty_allow_srvcc_fast_return(true, 0);
5903 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005904 f_sleep(1.0);
5905
5906 f_ctrs_bsc_and_bts_init();
5907
5908 pars.last_used_eutran_plmn := '323454'O;
5909 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5910 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5911
5912 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5913 vc_conn.done;
5914
5915 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5916 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5917 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5918 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5919 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5920 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005921
5922 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5923 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005924 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005925
5926 if (disable_fast_return) {
5927 f_vty_allow_srvcc_fast_return(false, 0);
5928 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005929 f_shutdown_helper();
5930}
5931
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005932/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5933 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5934 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5935 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5936testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5937 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5938}
5939/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5940 * independently of fast-reture allowed/forbidden in local BTS */
5941testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5942 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5943}
5944
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005945private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5946 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5947 f_rslem_register(0, new_chan_nr);
5948 g_chan_nr := new_chan_nr;
5949 f_sleep(1.0);
5950
5951 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5952 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5953 activate(as_Media());
5954
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005955 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005956 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005957 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005958
5959 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5960
5961 var PDU_BSSAP rx_bssap;
5962 var octetstring ho_command_str;
5963
5964 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5965
5966 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5967 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5968 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5969 log("L3 Info in HO Request Ack is ", ho_command);
5970
5971 var GsmArfcn arfcn;
5972 var RslChannelNr actual_new_chan_nr;
5973 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5974 actual_new_chan_nr, arfcn);
5975
5976 if (actual_new_chan_nr != new_chan_nr) {
5977 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5978 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5979 setverdict(fail);
5980 return;
5981 }
5982 log("Handover Command chan_nr is", actual_new_chan_nr);
5983
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005984 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5985 f_sleep(1.0);
5986
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005987 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5988 * tells the MS to handover to the new lchan. In this case, the MS
5989 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5990 * Handover Failure to the MSC. The procedure according to 3GPP TS
5991 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5992 * BSSMAP Clear Command: */
5993
5994 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5995 var BssmapCause cause := enum2int(cause_val);
5996 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5997
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005998 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005999 BSSAP.receive(tr_BSSMAP_ClearComplete);
6000
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006001 setverdict(pass);
6002 f_sleep(1.0);
6003
6004 setverdict(pass);
6005}
6006testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6007 var MSC_ConnHdlr vc_conn;
6008 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6009
6010 f_init(1, true);
6011 f_sleep(1.0);
6012
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006013 f_ctrs_bsc_and_bts_init();
6014
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006015 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6016 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006017
6018 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6019 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006020
6021 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6022 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6023 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6024 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6025 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006026 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006027}
6028
6029private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6030 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6031 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6032 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6033 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6034 * before we get started. */
6035 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6036 f_rslem_register(0, new_chan_nr);
6037 g_chan_nr := new_chan_nr;
6038 f_sleep(1.0);
6039
6040 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6041 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6042 activate(as_Media());
6043
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006044 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006045 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006046 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006047
6048 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6049
6050 var PDU_BSSAP rx_bssap;
6051 var octetstring ho_command_str;
6052
6053 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6054
6055 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6056 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6057 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6058 log("L3 Info in HO Request Ack is ", ho_command);
6059
6060 var GsmArfcn arfcn;
6061 var RslChannelNr actual_new_chan_nr;
6062 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6063 actual_new_chan_nr, arfcn);
6064
6065 if (actual_new_chan_nr != new_chan_nr) {
6066 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6067 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6068 setverdict(fail);
6069 return;
6070 }
6071 log("Handover Command chan_nr is", actual_new_chan_nr);
6072
6073 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6074 * tells the MS to handover to the new lchan. Here comes the new MS on
6075 * the new lchan with a Handover RACH: */
6076
6077 /* send handover detect */
6078
6079 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6080
6081 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6082
6083 /* The MSC chooses to clear the connection now, maybe we got the
6084 * Handover RACH on the new cell but the MS still signaled Handover
6085 * Failure to the old BSS? */
6086
6087 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6088 var BssmapCause cause := enum2int(cause_val);
6089 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6090
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006091 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006092 BSSAP.receive(tr_BSSMAP_ClearComplete);
6093
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006094 f_sleep(1.0);
6095}
6096testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6097 var MSC_ConnHdlr vc_conn;
6098 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6099
6100 f_init(1, true);
6101 f_sleep(1.0);
6102
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006103 f_ctrs_bsc_and_bts_init();
6104
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006105 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6106 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006107
6108 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6109 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006110
6111 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6112 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6113 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6114 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6115 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006116 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006117}
6118
6119/* The new BSS's lchan times out before the MSC decides that handover failed. */
6120private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6121 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6122 f_rslem_register(0, new_chan_nr);
6123 g_chan_nr := new_chan_nr;
6124 f_sleep(1.0);
6125
6126 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6127 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6128 activate(as_Media());
6129
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006130 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006131 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006132 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006133
6134 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6135
6136 var PDU_BSSAP rx_bssap;
6137 var octetstring ho_command_str;
6138
6139 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6140
6141 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6142 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6143 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6144 log("L3 Info in HO Request Ack is ", ho_command);
6145
6146 var GsmArfcn arfcn;
6147 var RslChannelNr actual_new_chan_nr;
6148 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6149 actual_new_chan_nr, arfcn);
6150
6151 if (actual_new_chan_nr != new_chan_nr) {
6152 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6153 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6154 setverdict(fail);
6155 return;
6156 }
6157 log("Handover Command chan_nr is", actual_new_chan_nr);
6158
6159 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6160 * tells the MS to handover to the new lchan. But the MS never shows up
6161 * on the new lchan. */
6162
6163 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6164
6165 /* Did osmo-bsc also send a Clear Request? */
6166 timer T := 0.5;
6167 T.start;
6168 alt {
6169 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6170 [] T.timeout { }
6171 }
6172
6173 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6174 * asked for it, this is a Handover Failure after all). */
6175
6176 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6177 var BssmapCause cause := enum2int(cause_val);
6178 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6179
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006180 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006181 BSSAP.receive(tr_BSSMAP_ClearComplete);
6182
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006183 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006184}
6185testcase TC_ho_in_fail_no_detect() runs on test_CT {
6186 var MSC_ConnHdlr vc_conn;
6187 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6188
6189 f_init(1, true);
6190 f_sleep(1.0);
6191
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006192 f_ctrs_bsc_and_bts_init();
6193
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006194 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6195 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006196
6197 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6198 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006199
6200 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6201 f_ctrs_bsc_and_bts_add(0, "handover:error");
6202 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6203 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6204 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006205 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006206}
6207
6208/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6209private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6210 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6211 f_rslem_register(0, new_chan_nr);
6212 g_chan_nr := new_chan_nr;
6213 f_sleep(1.0);
6214
6215 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6216 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6217 activate(as_Media());
6218
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006219 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006220 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006221 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006222
6223 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6224
6225 var PDU_BSSAP rx_bssap;
6226 var octetstring ho_command_str;
6227
6228 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6229
6230 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6231 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6232 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6233 log("L3 Info in HO Request Ack is ", ho_command);
6234
6235 var GsmArfcn arfcn;
6236 var RslChannelNr actual_new_chan_nr;
6237 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6238 actual_new_chan_nr, arfcn);
6239
6240 if (actual_new_chan_nr != new_chan_nr) {
6241 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6242 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6243 setverdict(fail);
6244 return;
6245 }
6246 log("Handover Command chan_nr is", actual_new_chan_nr);
6247
6248 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6249 * tells the MS to handover to the new lchan. But the MS never shows up
6250 * on the new lchan. */
6251
6252 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6253
6254 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006255 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006256
6257 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006258 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6259 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6260 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006261 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006262 BSSAP.receive(tr_BSSMAP_ClearComplete);
6263
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006264 f_sleep(1.0);
6265}
6266testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6267 var MSC_ConnHdlr vc_conn;
6268 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6269
6270 f_init(1, true);
6271 f_sleep(1.0);
6272
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006273 f_ctrs_bsc_and_bts_init();
6274
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006275 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6276 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006277
6278 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6279 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006280
6281 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6282 f_ctrs_bsc_and_bts_add(0, "handover:error");
6283 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6284 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6285 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006286 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006287}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006288
Neels Hofmeyr91401012019-07-11 00:42:35 +02006289type record of charstring Commands;
6290
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006291private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006292{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006293 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006294 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006295 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006296 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006297 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006298}
6299
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006300private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6301{
6302 f_vty_enter_cfg_cs7_inst(pt, 0);
6303 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6304 f_vty_transceive(pt, cmds[i]);
6305 }
6306 f_vty_transceive(pt, "end");
6307}
6308
Neels Hofmeyr91401012019-07-11 00:42:35 +02006309private function f_probe_for_handover(charstring log_label,
6310 charstring log_descr,
6311 charstring handover_vty_cmd,
6312 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006313 boolean is_inter_bsc_handover := false,
6314 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006315runs on MSC_ConnHdlr
6316{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006317 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6318 * lchans to be established on bts 1 or bts 2. */
6319 f_rslem_suspend(RSL1_PROC);
6320 f_rslem_suspend(RSL2_PROC);
6321
Neels Hofmeyr91401012019-07-11 00:42:35 +02006322 var RSL_Message rsl;
6323
6324 var charstring log_msg := " (expecting handover)"
6325 if (not expect_handover) {
6326 log_msg := " (expecting NO handover)";
6327 }
6328 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6329 f_vty_transceive(BSCVTY, handover_vty_cmd);
6330
Neels Hofmeyr91401012019-07-11 00:42:35 +02006331 timer T := 2.0;
6332 T.start;
6333
6334 alt {
6335 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6336 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6337 log("Rx L3 from net: ", l3);
6338 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6339 var RslChannelNr new_chan_nr;
6340 var GsmArfcn arfcn;
6341 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6342 new_chan_nr, arfcn);
6343 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6344 log(l3.msgs.rrm.handoverCommand);
6345
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006346 /* Verify correct TSC in handoverCommand */
6347 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6348 if (not match(got_tsc, expect_target_tsc)) {
6349 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6350 expect_target_tsc, " got ", got_tsc);
6351 mtc.stop;
6352 } else {
6353 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6354 expect_target_tsc, ")");
6355 }
6356
Neels Hofmeyr91401012019-07-11 00:42:35 +02006357 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6358 * matter on which BTS it really is, we're not going to follow through an entire handover
6359 * anyway. */
6360 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6361 f_rslem_resume(RSL1_PROC);
6362 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6363 f_rslem_resume(RSL2_PROC);
6364
6365 if (expect_handover and not is_inter_bsc_handover) {
6366 setverdict(pass);
6367 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6368 } else {
6369 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6370 & log_label & ": " & log_descr);
6371 }
6372
6373 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6374 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6375 * Handover Failure. */
6376 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6377
6378 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6379 f_sleep(0.5);
6380 RSL1.clear;
6381 RSL2.clear;
6382 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6383 break;
6384 } else {
6385 repeat;
6386 }
6387 }
6388 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6389 if (expect_handover and is_inter_bsc_handover) {
6390 setverdict(pass);
6391 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6392 } else {
6393 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6394 & log_label & ": " & log_descr);
6395 }
6396
6397 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6398
6399 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6400 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6401 * setting a short timeout and waiting is the only way. */
6402 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6403 f_sleep(1.5);
6404 log("f_probe_for_handover(" & log_label & "): ...done");
6405
6406 break;
6407 }
6408 [] T.timeout {
6409 if (expect_handover) {
6410 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6411 & log_label & ": " & log_descr);
6412 } else {
6413 setverdict(pass);
6414 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6415 }
6416 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6417 break;
6418 }
6419 }
6420
6421 f_rslem_resume(RSL1_PROC);
6422 f_rslem_resume(RSL2_PROC);
6423 f_sleep(3.0);
6424 RSL.clear;
6425
6426 log("f_probe_for_handover(" & log_label & "): done clearing");
6427}
6428
6429/* Test the effect of various neighbor configuration scenarios:
6430 *
6431 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6432 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6433 */
6434private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6435 g_pars := f_gen_test_hdlr_pars();
6436 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6437 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006438
6439 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6440 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6441
6442 /* Establish lchan at bts 0 */
6443 f_establish_fully(ass_cmd, exp_compl);
6444
6445 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6446 f_vty_enter_cfg_network(BSCVTY);
6447 f_vty_transceive(BSCVTY, "timer T7 1");
6448 f_vty_transceive(BSCVTY, "end");
6449}
6450
6451private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6452 f_tc_ho_neighbor_config_start();
6453
6454 /*
6455 * bts 0 ARFCN 871 BSIC 10
6456 * bts 1 ARFCN 871 BSIC 11
6457 * bts 2 ARFCN 871 BSIC 12
6458 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6459 */
6460
6461 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006462 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006463 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6464 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006465 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006466
6467 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6468 "handover any to arfcn 13 bsic 39",
6469 false);
6470
6471 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6472 "handover any to arfcn 871 bsic 12",
6473 false);
6474
6475 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6476 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006477 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006478}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006479testcase TC_ho_neighbor_config_1() runs on test_CT {
6480 var MSC_ConnHdlr vc_conn;
6481 f_init(3, true, guard_timeout := 60.0);
6482 f_sleep(1.0);
6483 f_ctrs_bsc_and_bts_init();
6484 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6485 vc_conn.done;
6486
6487 /* f_tc_ho_neighbor_config_start() */
6488 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6489 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6490
6491 /* 1.a */
6492 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6493 * handover quickly by sending a Handover Failure message. */
6494 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6495 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6496 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6497 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6498
6499 /* 1.b */
6500 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6501 f_ctrs_bsc_and_bts_add(0, "handover:error");
6502
6503 /* 1.c */
6504 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6505 f_ctrs_bsc_and_bts_add(0, "handover:error");
6506
6507 /* 1.d */
6508 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6509 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6510 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6511 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6512
6513 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006514 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006515}
6516
Neels Hofmeyr91401012019-07-11 00:42:35 +02006517private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6518 f_tc_ho_neighbor_config_start();
6519
6520 /*
6521 * bts 0 ARFCN 871 BSIC 10
6522 * bts 1 ARFCN 871 BSIC 11
6523 * bts 2 ARFCN 871 BSIC 12
6524 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6525 */
6526
6527 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006528 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006529 f_sleep(0.5);
6530
6531 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6532 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006533 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006534
6535 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6536 "handover any to arfcn 871 bsic 12",
6537 false);
6538}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006539testcase TC_ho_neighbor_config_2() runs on test_CT {
6540 var MSC_ConnHdlr vc_conn;
6541 f_init(3, true, guard_timeout := 50.0);
6542 f_sleep(1.0);
6543 f_ctrs_bsc_and_bts_init();
6544 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6545 vc_conn.done;
6546
6547 /* f_tc_ho_neighbor_config_start() */
6548 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6549 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6550
6551 /* 2.a */
6552 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6553 * handover quickly by sending a Handover Failure message. */
6554 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6555 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6556 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6557 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6558
6559 /* 2.b */
6560 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6561 f_ctrs_bsc_and_bts_add(0, "handover:error");
6562
6563 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006564 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006565}
6566
Neels Hofmeyr91401012019-07-11 00:42:35 +02006567private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6568 f_tc_ho_neighbor_config_start();
6569
6570 /*
6571 * bts 0 ARFCN 871 BSIC 10
6572 * bts 1 ARFCN 871 BSIC 11
6573 * bts 2 ARFCN 871 BSIC 12
6574 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6575 */
6576
6577 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006578 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006579 f_sleep(0.5);
6580
6581 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6582 "handover any to arfcn 871 bsic 11",
6583 false);
6584 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",
6585 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006586 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006587}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006588testcase TC_ho_neighbor_config_3() runs on test_CT {
6589 var MSC_ConnHdlr vc_conn;
6590 f_init(3, true, guard_timeout := 50.0);
6591 f_sleep(1.0);
6592 f_ctrs_bsc_and_bts_init();
6593 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6594 vc_conn.done;
6595
6596 /* f_tc_ho_neighbor_config_start() */
6597 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6598 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6599
6600 /* 3.a */
6601 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6602 f_ctrs_bsc_and_bts_add(0, "handover:error");
6603
6604 /* 3.b */
6605 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6606 * handover quickly by sending a Handover Failure message. */
6607 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6608 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6609 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6610 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6611
6612 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006613 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006614}
6615
Neels Hofmeyr91401012019-07-11 00:42:35 +02006616private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6617 f_tc_ho_neighbor_config_start();
6618
6619 /*
6620 * bts 0 ARFCN 871 BSIC 10
6621 * bts 1 ARFCN 871 BSIC 11
6622 * bts 2 ARFCN 871 BSIC 12
6623 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6624 */
6625
6626 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006627 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006628 f_sleep(0.5);
6629
6630 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6631 "handover any to arfcn 871 bsic 11",
6632 false);
6633 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6634 "handover any to arfcn 871 bsic 12",
6635 false);
6636 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6637 "handover any to arfcn 123 bsic 45",
6638 true, true);
6639}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006640testcase TC_ho_neighbor_config_4() runs on test_CT {
6641 var MSC_ConnHdlr vc_conn;
6642 f_init(3, true, guard_timeout := 50.0);
6643 f_sleep(1.0);
6644 f_ctrs_bsc_and_bts_init();
6645 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6646 vc_conn.done;
6647
6648 /* f_tc_ho_neighbor_config_start() */
6649 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6650 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6651
6652 /* 4.a */
6653 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6654 f_ctrs_bsc_and_bts_add(0, "handover:error");
6655
6656 /* 4.b */
6657 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6658 f_ctrs_bsc_and_bts_add(0, "handover:error");
6659
6660 /* 4.c */
6661 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6662 * handover quickly by timing out after the Handover Required message */
6663 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6664 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6665 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6666 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6667
6668 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006669 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006670}
6671
Neels Hofmeyr91401012019-07-11 00:42:35 +02006672private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6673 f_tc_ho_neighbor_config_start();
6674
6675 /*
6676 * bts 0 ARFCN 871 BSIC 10
6677 * bts 1 ARFCN 871 BSIC 11
6678 * bts 2 ARFCN 871 BSIC 12
6679 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6680 */
6681
6682 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 +02006683 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006684 f_sleep(0.5);
6685
6686 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6687 "handover any to arfcn 871 bsic 12",
6688 true, true);
6689}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006690testcase TC_ho_neighbor_config_5() runs on test_CT {
6691 var MSC_ConnHdlr vc_conn;
6692 f_init(3, true);
6693 f_sleep(1.0);
6694 f_ctrs_bsc_and_bts_init();
6695 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6696 vc_conn.done;
6697
6698 /* f_tc_ho_neighbor_config_start() */
6699 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6700 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6701
6702 /* 5 */
6703 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6704 * handover quickly by timing out after the Handover Required message */
6705 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6706 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6707 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6708 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6709
6710 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006711 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006712}
6713
Neels Hofmeyr91401012019-07-11 00:42:35 +02006714private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6715 f_tc_ho_neighbor_config_start();
6716
6717 /*
6718 * bts 0 ARFCN 871 BSIC 10
6719 * bts 1 ARFCN 871 BSIC 11
6720 * bts 2 ARFCN 871 BSIC 12
6721 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6722 */
6723
6724 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6725 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006726 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006727 f_sleep(0.5);
6728
6729 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6730 "handover any to arfcn 871 bsic 12",
6731 false);
6732}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006733testcase TC_ho_neighbor_config_6() runs on test_CT {
6734 var MSC_ConnHdlr vc_conn;
6735 f_init(3, true);
6736 f_sleep(1.0);
6737 f_ctrs_bsc_and_bts_init();
6738 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6739 vc_conn.done;
6740
6741 /* f_tc_ho_neighbor_config_start() */
6742 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6743 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6744
6745 /* 6.a */
6746 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6747 * handover quickly by timing out after the Handover Required message */
6748 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6749 f_ctrs_bsc_and_bts_add(0, "handover:error");
6750
6751 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006752 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006753}
6754
Neels Hofmeyr91401012019-07-11 00:42:35 +02006755private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6756 f_tc_ho_neighbor_config_start();
6757
6758 /*
6759 * bts 0 ARFCN 871 BSIC 10
6760 * bts 1 ARFCN 871 BSIC 11
6761 * bts 2 ARFCN 871 BSIC 12
6762 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6763 */
6764
6765 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6766 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006767 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006768 f_sleep(0.5);
6769
6770 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6771 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006772 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006773 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6774 "handover any to arfcn 123 bsic 45",
6775 true, true);
6776}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006777testcase TC_ho_neighbor_config_7() runs on test_CT {
6778 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006779 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006780 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006781 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006782 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6783 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006784
6785 /* f_tc_ho_neighbor_config_start() */
6786 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6787 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6788
6789 /* 7.a */
6790 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6791 * handover quickly by sending a Handover Failure message. */
6792 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6793 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6794 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6795 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6796
6797 /* 7.b */
6798 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6799 * handover quickly by timing out after the Handover Required message */
6800 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6801 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6802 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6803 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6804
6805 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006806 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006807}
6808
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006809/* OS#3041: Open and close N connections in a normal fashion, and expect no
6810 * BSSMAP Reset just because of that. */
6811testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6812 var default d;
6813 var integer i;
6814 var DchanTuple dt;
6815
6816 f_init();
6817
6818 /* Wait for initial BSSMAP Reset to pass */
6819 f_sleep(4.0);
6820
6821 d := activate(no_bssmap_reset());
6822
6823 /* Setup up a number of connections and RLSD them again from the MSC
6824 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6825 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006826 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006827 /* Since we're doing a lot of runs, give each one a fresh
6828 * T_guard from the top. */
6829 T_guard.start;
6830
6831 /* Setup a BSSAP connection and clear it right away. This is
6832 * the MSC telling the BSC about a planned release, it's not an
6833 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006834 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006835
6836 /* MSC disconnects (RLSD). */
6837 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6838 }
6839
6840 /* In the buggy behavior, a timeout of 2 seconds happens between above
6841 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6842 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6843 f_sleep(4.0);
6844
6845 deactivate(d);
6846 f_shutdown_helper();
6847}
Harald Welte552620d2017-12-16 23:21:36 +01006848
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006849/* OS#3041: Open and close N connections in a normal fashion, and expect no
6850 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6851 * the MSC. */
6852testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6853 var default d;
6854 var integer i;
6855 var DchanTuple dt;
6856 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006857 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6858 var BssmapCause cause := enum2int(cause_val);
6859
6860 f_init();
6861
6862 /* Wait for initial BSSMAP Reset to pass */
6863 f_sleep(4.0);
6864
6865 d := activate(no_bssmap_reset());
6866
6867 /* Setup up a number of connections and RLSD them again from the MSC
6868 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6869 * Let's do it some more times for good measure. */
6870 for (i := 0; i < 8; i := i+1) {
6871 /* Since we're doing a lot of runs, give each one a fresh
6872 * T_guard from the top. */
6873 T_guard.start;
6874
6875 /* Setup a BSSAP connection and clear it right away. This is
6876 * the MSC telling the BSC about a planned release, it's not an
6877 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006878 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006879
6880 /* Instruct BSC to clear channel */
6881 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6882
6883 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006884 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006885 }
6886
6887 /* In the buggy behavior, a timeout of 2 seconds happens between above
6888 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6889 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6890 f_sleep(4.0);
6891
6892 deactivate(d);
6893 f_shutdown_helper();
6894}
6895
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006896/* OS#3041: Open and close N connections in a normal fashion, and expect no
6897 * BSSMAP Reset just because of that. Close connections from the MS side with a
6898 * Release Ind on RSL. */
6899testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6900 var default d;
6901 var integer i;
6902 var DchanTuple dt;
6903 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006904 var integer j;
6905
6906 f_init();
6907
6908 /* Wait for initial BSSMAP Reset to pass */
6909 f_sleep(4.0);
6910
6911 d := activate(no_bssmap_reset());
6912
6913 /* Setup up a number of connections and RLSD them again from the MSC
6914 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6915 * Let's do it some more times for good measure. */
6916 for (i := 0; i < 8; i := i+1) {
6917 /* Since we're doing a lot of runs, give each one a fresh
6918 * T_guard from the top. */
6919 T_guard.start;
6920
6921 /* Setup a BSSAP connection and clear it right away. This is
6922 * the MSC telling the BSC about a planned release, it's not an
6923 * erratic loss of a connection. */
6924 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6925
6926 /* simulate RLL REL IND */
6927 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6928
6929 /* expect Clear Request on MSC side */
6930 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6931
6932 /* Instruct BSC to clear channel */
6933 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6934 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6935
6936 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006937 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006938 }
6939
6940 /* In the buggy behavior, a timeout of 2 seconds happens between above
6941 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6942 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6943 f_sleep(4.0);
6944
6945 deactivate(d);
6946 f_shutdown_helper();
6947}
6948
Harald Welte94e0c342018-04-07 11:33:23 +02006949/***********************************************************************
6950 * IPA style dynamic PDCH
6951 ***********************************************************************/
6952
6953private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6954 template (omit) RSL_Cause nack := omit)
6955runs on test_CT {
6956 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6957 var RSL_Message rsl_unused;
6958 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6959 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6960 /* expect the BSC to issue the related RSL command */
6961 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6962 if (istemplatekind(nack, "omit")) {
6963 /* respond with a related acknowledgement */
6964 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6965 } else {
6966 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6967 }
6968}
6969
6970private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6971 template (omit) RSL_Cause nack := omit)
6972runs on test_CT {
6973 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6974 var RSL_Message rsl_unused;
6975 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6976 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6977 /* expect the BSC to issue the related RSL command */
6978 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6979 if (istemplatekind(nack, "omit")) {
6980 /* respond with a related acknowledgement */
6981 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6982 } else {
6983 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6984 }
6985}
6986
6987private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6988runs on test_CT return charstring {
6989 var charstring cmd, resp;
6990 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006991 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006992}
6993
6994private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6995 template charstring exp)
6996runs on test_CT {
6997 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
6998 if (not match(mode, exp)) {
6999 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007000 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007001 }
7002}
7003
7004private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7005runs on test_CT {
7006 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7007 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7008 f_vty_transceive(BSCVTY, "end");
7009}
7010
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007011
7012private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7013 var integer i;
7014 for (i := 0; i < 8; i := i + 1) {
7015 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7016 }
7017}
7018
Harald Welte94e0c342018-04-07 11:33:23 +02007019private const charstring TCHF_MODE := "TCH/F mode";
7020private const charstring TCHH_MODE := "TCH/H mode";
7021private const charstring PDCH_MODE := "PDCH mode";
7022private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007023private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007024
7025/* Test IPA PDCH activation / deactivation triggered by VTY */
7026testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7027 var RSL_Message rsl_unused;
7028
7029 /* change Timeslot 6 before f_init() starts RSL */
7030 f_init_vty();
7031 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7032 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7033
7034 f_init(1, false);
7035 f_sleep(1.0);
7036
7037 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7038
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007039 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007040 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7041 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7042 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7043 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7044 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007045 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007046 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7047
7048 /* De-activate it via VTY */
7049 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7050 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007051 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007052 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7053
7054 /* re-activate it via VTY */
7055 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7056 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007057 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007058 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7059
7060 /* and finally de-activate it again */
7061 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7062 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007063 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007064 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7065
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007066 /* clean up config */
7067 f_ts_set_chcomb(0, 0, 6, "PDCH");
7068
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007069 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007070}
7071
7072/* Test IPA PDCH activation NACK */
7073testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7074 var RSL_Message rsl_unused;
7075
7076 /* change Timeslot 6 before f_init() starts RSL */
7077 f_init_vty();
7078 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7079 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7080
7081 f_init(1, false);
7082 f_sleep(1.0);
7083
7084 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7085
7086 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7087 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7088 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7089 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7090 f_sleep(1.0);
7091 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7092
7093 /* De-activate it via VTY */
7094 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7095 f_sleep(1.0);
7096 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7097
7098 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7099 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7100 f_sleep(1.0);
7101 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7102
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007103 /* clean up config */
7104 f_ts_set_chcomb(0, 0, 6, "PDCH");
7105
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007106 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007107}
7108
7109
7110/***********************************************************************
7111 * Osmocom style dynamic PDCH
7112 ***********************************************************************/
7113
7114private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7115 template (omit) RSL_Cause nack := omit)
7116runs on test_CT {
7117 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7118 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007119 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007120 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7121 /* expect the BSC to issue the related RSL command */
7122 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7123 if (istemplatekind(nack, "omit")) {
7124 /* respond with a related acknowledgement */
7125 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7126 } else {
7127 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7128 }
7129}
7130
7131private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7132 template (omit) RSL_Cause nack := omit)
7133runs on test_CT {
7134 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7135 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007136 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007137 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7138 /* expect the BSC to issue the related RSL command */
7139 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7140 if (istemplatekind(nack, "omit")) {
7141 /* respond with a related acknowledgement */
7142 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7143 } else {
7144 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7145 }
7146}
7147
7148/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7149testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7150 var RSL_Message rsl_unused;
7151
7152 /* change Timeslot 6 before f_init() starts RSL */
7153 f_init_vty();
7154 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7155 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7156
7157 f_init(1, false);
7158 f_sleep(1.0);
7159
7160 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7161
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007162 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007163 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7164 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7165 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7166
7167 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7168 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007169 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 +02007170 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7171
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007172 /* clean up config */
7173 f_ts_set_chcomb(0, 0, 6, "PDCH");
7174
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007175 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007176}
7177
7178/* Test Osmocom dyn PDCH activation NACK behavior */
7179testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7180 var RSL_Message rsl_unused;
7181
7182 /* change Timeslot 6 before f_init() starts RSL */
7183 f_init_vty();
7184 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7185 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7186
7187 f_init(1, false);
7188 f_sleep(1.0);
7189
7190 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7191
7192 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7193 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7194 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7195
7196 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7197 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7198 f_sleep(1.0);
7199 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7200
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007201 /* clean up config */
7202 f_ts_set_chcomb(0, 0, 6, "PDCH");
7203
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007204 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007205}
7206
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007207/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7208testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7209 var RSL_Message rsl_unused, rsl_msg;
7210 var DchanTuple dt;
7211 var BSSAP_N_CONNECT_ind rx_c_ind;
7212
7213 /* change Timeslot 6 before f_init() starts RSL */
7214 f_init_vty();
7215 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7216 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7217
7218 f_init(1, false);
7219 f_sleep(1.0);
7220
7221 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7222
7223 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7224 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7225 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7226 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7227
7228 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7229 f_sleep(1.0);
7230 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7231 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7232
7233 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7234 * on CCCH+SDCCH4+CBCH) */
7235 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007236 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007237 dt := f_est_dchan('23'O, i, '00010203040506'O);
7238 }
7239
7240 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7241 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7242 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7243 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7244
7245 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7246 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7247
7248 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7249 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7250 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7251 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7252
7253 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7254 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7255 dt.sccp_conn_id := rx_c_ind.connectionId;
7256 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7257
7258 /* Instruct BSC to clear channel */
7259 var BssmapCause cause := 0;
7260 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7261 f_exp_chan_rel_and_clear(dt, 0);
7262
7263 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7264 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7265 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7266 f_sleep(1.0);
7267 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7268
7269 /* clean up config */
7270 f_ts_set_chcomb(0, 0, 6, "PDCH");
7271
7272 f_shutdown_helper();
7273}
7274
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007275/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7276testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7277 var ASP_RSL_Unitdata rsl_ud;
7278 var integer i;
7279 var integer chreq_total, chreq_nochan;
7280
7281 f_init_vty();
7282 for (i := 1; i < 8; i := i + 1) {
7283 if (i == 2) {
7284 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7285 } else {
7286 f_ts_set_chcomb(0, 0, i, "PDCH");
7287 }
7288 }
7289 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7290
7291 f_init(1);
7292
7293 /* The dyn TS want to activate PDCH mode, ACK that. */
7294 var RslChannelNr chan_nr;
7295 chan_nr := valueof(t_RslChanNr_PDCH(2));
7296 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7297 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7298
7299 f_sleep(1.0);
7300
7301 /* Exhaust all dedicated SDCCH lchans.
7302 /* GSM 44.018 Table 9.1.8.2:
7303 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7304 */
7305 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
7306 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7307 }
7308
7309 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
7310 f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7311 /* Also occupy the seven other SDCCH of the dyn TS */
7312 for (i := 0; i < 7; i := i+1) {
7313 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7314 }
7315
7316 /* clean up config */
7317 f_ts_reset_chcomb(0);
7318
7319 f_shutdown_helper();
7320}
7321
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007322/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7323 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7324 it as TCH directly instead. SYS#5309. */
7325testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7326 var RSL_Message rsl_unused, rsl_msg;
7327 var DchanTuple dt;
7328 var BSSAP_N_CONNECT_ind rx_c_ind;
7329 var integer i;
7330
7331 /* change Timeslot 6 before f_init() starts RSL */
7332 f_init_vty();
7333 for (i := 1; i < 8; i := i + 1) {
7334 if (i == 6) {
7335 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7336 } else {
7337 f_ts_set_chcomb(0, 0, i, "PDCH");
7338 }
7339 }
7340 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7341
7342 f_init(1, false);
7343 f_sleep(1.0);
7344
7345 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7346
7347 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7348 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7349 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7350 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7351
7352 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7353 f_sleep(1.0);
7354 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7355 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7356
7357 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7358 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007359 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007360 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007361 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007362 }
7363
7364 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007365 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007366 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7367 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7368
7369 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7370 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7371
7372 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7373 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7374 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7375 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7376
7377 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7378 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7379 dt.sccp_conn_id := rx_c_ind.connectionId;
7380 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7381
7382 /* Instruct BSC to clear channel */
7383 var BssmapCause cause := 0;
7384 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7385 f_exp_chan_rel_and_clear(dt, 0);
7386
7387 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7388 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7389 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7390 f_sleep(1.0);
7391 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7392
7393 /* clean up config */
7394 f_ts_reset_chcomb(0);
7395 /* TODO: clean up other channels? */
7396
7397 f_shutdown_helper();
7398}
7399
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007400/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7401testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7402 var RSL_Message rsl_unused, rsl_msg;
7403 var DchanTuple dt;
7404 var BSSAP_N_CONNECT_ind rx_c_ind;
7405 var GsmRrMessage rr;
7406
7407 /* change Timeslot 6 before f_init() starts RSL */
7408 f_init_vty();
7409 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7410 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7411
7412 f_init(1, false);
7413 f_sleep(1.0);
7414
7415 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7416
7417 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7418 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7419 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7420 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7421
7422 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7423 f_sleep(1.0);
7424 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7425 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7426
7427 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7428 * on CCCH+SDCCH4+CBCH) */
7429 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007430 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007431 dt := f_est_dchan('23'O, i, '00010203040506'O);
7432 }
7433
7434 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7435 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7436 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7437 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7438
7439 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7440 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7441
7442 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7443 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7444 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7445 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7446 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7447 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7448 }
7449
7450 /* FIXME? Currently the TS stays in state BORKEN: */
7451
7452 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7453 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7454 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7455 * f_sleep(1.0);
7456 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7457 */
7458
7459 /* clean up config */
7460 f_ts_set_chcomb(0, 0, 6, "PDCH");
7461
7462 f_shutdown_helper();
7463}
7464
Stefan Sperling0796a822018-10-05 13:01:39 +02007465testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007466 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007467 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7468 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7469 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007470 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007471}
7472
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007473testcase TC_chopped_ipa_payload() runs on test_CT {
7474 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7475 /* TODO: mp_bsc_ctrl_port does not work yet */};
7476 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7477 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7478 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007479 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007480}
7481
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007482/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7483 the BTS does autonomous MS power control loop */
7484testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7485 var MSC_ConnHdlr vc_conn;
7486 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7487 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7488 pars.exp_ms_power_params := true;
7489
7490 f_init(1, true);
7491 f_sleep(1.0);
7492 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7493 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007494 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007495}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007496
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007497/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7498testcase TC_c0_power_red_mode() runs on test_CT {
7499 f_init(1);
7500
7501 for (var integer red := 6; red >= 0; red := red - 2) {
7502 /* Configure BCCH carrier power reduction mode via the VTY */
7503 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7504
7505 /* Expect Osmocom specific BS Power Control message on the RSL */
7506 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7507 chan_nr := t_RslChanNr_BCCH(0),
7508 bs_power := tr_RSL_IE_BS_Power(red / 2));
7509 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7510 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7511
7512 /* Additionally verify the applied value over the CTRL interface */
7513 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7514 if (cred != int2str(red)) {
7515 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7516 cred, " (expected ", red, ")");
7517 }
7518 }
7519
7520 f_shutdown_helper();
7521}
7522
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007523/***********************************************************************
7524 * MSC Pooling
7525 ***********************************************************************/
7526
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007527template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007528 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 +02007529
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007530private 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 +02007531runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007532 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007533 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007534 f_logp(BSCVTY, "Got RSL RR Release");
7535 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007536 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007537 f_logp(BSCVTY, "Got RSL Deact SACCH");
7538 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007539 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007540 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007541 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7542 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007543 break;
7544 }
7545 }
7546}
7547
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007548friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7549 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007550runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007551 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007552 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7553 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007554 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007555 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007556 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007557 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007558 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007559 }
7560 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007561 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007562 /* Also drop the SCCP connection */
7563 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7564 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007565 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007566 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007567 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7568 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007569 }
7570 }
7571}
7572
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007573private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7574 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007575runs on MSC_ConnHdlr {
7576 timer T := 10.0;
7577 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7578
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007579 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007580 f_create_bssmap_exp(l3_enc);
7581
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007582 /* RSL_Emulation.f_chan_est() on rsl_pt:
7583 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007584 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7585 */
7586 var RSL_Message rx_rsl;
7587 var GsmRrMessage rr;
7588
7589 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007590 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007591 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007592 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007593 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7594 */
7595 timer Tt := 10.0;
7596
7597 /* request a channel to be established */
7598 Tt.start;
7599 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007600 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007601 Tt.stop;
7602 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007603 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007604 setverdict(fail, "Unexpected RSL message on DCHAN");
7605 mtc.stop;
7606 }
7607 [] Tt.timeout {
7608 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7609 mtc.stop;
7610 }
7611 }
7612 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7613 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007614 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007615
7616
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007617 if (expect_bssmap_l3) {
7618 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7619 var template PDU_BSSAP exp_l3_compl;
7620 exp_l3_compl := tr_BSSMAP_ComplL3()
7621 if (g_pars.aoip == false) {
7622 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7623 } else {
7624 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7625 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007626
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007627 var PDU_BSSAP bssap;
7628 T.start;
7629 alt {
7630 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7631 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7632 log("rx exp_l3_compl = ", bssap);
7633 }
7634 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7635 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7636 }
7637 [] T.timeout {
7638 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7639 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007640 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007641
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007642 /* start ciphering, if requested */
7643 if (ispresent(g_pars.encr)) {
7644 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007645 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007646 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007647 }
7648
7649 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007650 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007651 }
7652 setverdict(pass);
7653 f_sleep(1.0);
7654}
7655
7656private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7657 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7658 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007659 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007660 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007661 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007662 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007663 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007664 }
7665}
7666
7667/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7668private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7669 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007670 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7671 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7672 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7673 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 +02007674}
7675testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7676
7677 f_init(1, true);
7678 f_sleep(1.0);
7679 var MSC_ConnHdlr vc_conn;
7680 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007681
7682 f_ctrs_msc_init();
7683
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007684 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7685 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007686
7687 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007688 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007689}
7690
7691/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7692/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7693 * just as well using only RSL. */
7694testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7695
7696 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7697 f_sleep(1.0);
7698
7699 /* Control which MSC gets chosen next by the round-robin, otherwise
7700 * would be randomly affected by which other tests ran before this. */
7701 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7702
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007703 f_ctrs_msc_init();
7704
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007705 var MSC_ConnHdlr vc_conn1;
7706 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7707 pars1.mscpool.rsl_idx := 0;
7708 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7709 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7710 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007711 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007712
7713 var MSC_ConnHdlr vc_conn2;
7714 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7715 pars2.mscpool.rsl_idx := 1;
7716 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7717 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7718 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007719 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007720
7721 /* Test round-robin wrap to the first MSC */
7722 var MSC_ConnHdlr vc_conn3;
7723 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7724 pars3.mscpool.rsl_idx := 2;
7725 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7726 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7727 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007728 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007729 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007730}
7731
7732/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7733 * (configured in osmo-bsc.cfg). */
7734/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7735 * just as well using only RSL. */
7736testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7737
7738 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7739 f_sleep(1.0);
7740
7741 /* Control which MSC gets chosen next by the round-robin, otherwise
7742 * would be randomly affected by which other tests ran before this. */
7743 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7744
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007745 f_ctrs_msc_init();
7746
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007747 var MSC_ConnHdlr vc_conn1;
7748 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7749 pars1.mscpool.rsl_idx := 0;
7750 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7751 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7752 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007753 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007754
7755 var MSC_ConnHdlr vc_conn2;
7756 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7757 pars2.mscpool.rsl_idx := 1;
7758 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7759 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7760 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007761 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007762
7763 /* Test round-robin wrap to the first MSC */
7764 var MSC_ConnHdlr vc_conn3;
7765 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7766 pars3.mscpool.rsl_idx := 2;
7767 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7768 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7769 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007770 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007771 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007772}
7773
7774/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7775 * (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
7776 * NULL-NRI setting is stronger than that. */
7777/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7778 * just as well using only RSL. */
7779testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7780
7781 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7782 f_sleep(1.0);
7783
7784 /* Control which MSC gets chosen next by the round-robin, otherwise
7785 * would be randomly affected by which other tests ran before this. */
7786 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7787
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007788 f_ctrs_msc_init();
7789
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007790 var MSC_ConnHdlr vc_conn1;
7791 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7792 pars1.mscpool.rsl_idx := 0;
7793 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7794 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7795 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007796 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007797
7798 var MSC_ConnHdlr vc_conn2;
7799 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7800 pars2.mscpool.rsl_idx := 1;
7801 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7802 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7803 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007804 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007805
7806 /* Test round-robin wrap to the first MSC */
7807 var MSC_ConnHdlr vc_conn3;
7808 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7809 pars3.mscpool.rsl_idx := 2;
7810 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7811 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7812 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007813 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007814 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007815}
7816
7817/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7818 * assigned to any MSC (configured in osmo-bsc.cfg). */
7819/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7820 * just as well using only RSL. */
7821testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7822
7823 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7824 f_sleep(1.0);
7825
7826 /* Control which MSC gets chosen next by the round-robin, otherwise
7827 * would be randomly affected by which other tests ran before this. */
7828 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7829
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007830 f_ctrs_msc_init();
7831
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007832 var MSC_ConnHdlr vc_conn1;
7833 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7834 pars1.mscpool.rsl_idx := 0;
7835 /* An NRI that is not assigned to any MSC */
7836 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7837 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7838 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007839 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007840
7841 var MSC_ConnHdlr vc_conn2;
7842 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7843 pars2.mscpool.rsl_idx := 1;
7844 /* An NRI that is not assigned to any MSC */
7845 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7846 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7847 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007848 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007849
7850 /* Test round-robin wrap to the first MSC */
7851 var MSC_ConnHdlr vc_conn3;
7852 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7853 pars3.mscpool.rsl_idx := 2;
7854 /* An NRI that is not assigned to any MSC */
7855 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7856 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7857 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007858 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007859 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007860}
7861
7862/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7863 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7864/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7865 * just as well using only RSL. */
7866testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7867
7868 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7869 f_sleep(1.0);
7870
7871 /* Control which MSC gets chosen next by the round-robin, otherwise
7872 * would be randomly affected by which other tests ran before this. */
7873 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7874
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007875 f_ctrs_msc_init();
7876
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007877 var MSC_ConnHdlr vc_conn1;
7878 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7879 pars1.mscpool.rsl_idx := 0;
7880 /* An NRI that is assigned to an unconnected MSC */
7881 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7882 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7883 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007884 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7885 f_ctrs_msc_add(0, "mscpool:subscr:new");
7886 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007887
7888 var MSC_ConnHdlr vc_conn2;
7889 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7890 pars2.mscpool.rsl_idx := 1;
7891 /* An NRI that is assigned to an unconnected MSC */
7892 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7893 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7894 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007895 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7896 f_ctrs_msc_add(1, "mscpool:subscr:new");
7897 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007898
7899 /* Test round-robin wrap to the first MSC */
7900 var MSC_ConnHdlr vc_conn3;
7901 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7902 pars3.mscpool.rsl_idx := 2;
7903 /* An NRI that is assigned to an unconnected MSC */
7904 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7905 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7906 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007907 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7908 f_ctrs_msc_add(0, "mscpool:subscr:new");
7909 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007910 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007911}
7912
7913/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7914 * osmo-bsc.cfg). */
7915/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7916 * just as well using only RSL. */
7917testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7918
7919 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7920 f_sleep(1.0);
7921
7922 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7923 * this is not using round-robin. */
7924 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7925
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007926 f_ctrs_msc_init();
7927
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007928 var MSC_ConnHdlr vc_conn1;
7929 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7930 pars1.mscpool.rsl_idx := 0;
7931 /* An NRI of the second MSC's range (256-511) */
7932 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7933 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7934 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007935 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007936
7937 var MSC_ConnHdlr vc_conn2;
7938 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7939 pars2.mscpool.rsl_idx := 1;
7940 /* An NRI of the second MSC's range (256-511) */
7941 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7942 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7943 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007944 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007945
7946 var MSC_ConnHdlr vc_conn3;
7947 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7948 pars3.mscpool.rsl_idx := 2;
7949 /* An NRI of the second MSC's range (256-511) */
7950 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7951 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7952 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007953 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007954 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007955}
7956
7957/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7958 * while a round-robin remains unaffected by that. */
7959/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7960 * just as well using only RSL. */
7961testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7962
7963 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7964 f_sleep(1.0);
7965
7966 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7967 * this is not using round-robin. */
7968 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7969
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007970 f_ctrs_msc_init();
7971
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007972 var MSC_ConnHdlr vc_conn1;
7973 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7974 pars1.mscpool.rsl_idx := 0;
7975 /* An NRI of the third MSC's range (512-767) */
7976 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7977 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7978 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007979 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007980
7981 var MSC_ConnHdlr vc_conn2;
7982 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7983 pars2.mscpool.rsl_idx := 1;
7984 /* An NRI of the third MSC's range (512-767) */
7985 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7986 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7987 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007988 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007989
7990 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7991 var MSC_ConnHdlr vc_conn3;
7992 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7993 pars3.mscpool.rsl_idx := 2;
7994 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7995 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7996 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007997 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007998 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007999}
8000
8001/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8002/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8003 * just as well using only RSL. */
8004testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8005
8006 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8007 f_sleep(1.0);
8008
8009 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8010 * instead, and hits msc 0. */
8011 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8012
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008013 f_ctrs_msc_init();
8014
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008015 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8016 var MSC_ConnHdlr vc_conn1;
8017 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8018 pars1.mscpool.rsl_idx := 0;
8019 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8020 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8021 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008022 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008023
8024 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8025 var MSC_ConnHdlr vc_conn2;
8026 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8027 pars2.mscpool.rsl_idx := 1;
8028 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8029 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8030 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008031 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008032 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008033}
8034
8035/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8036 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8037private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8038 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8039 //cid_list := { cIl_allInBSS := ''O };
8040 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8041 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8042 var BSSAP_N_UNITDATA_req paging;
8043 var hexstring imsi := '001010000000123'H;
8044
8045 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8046
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008047 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008048 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8049 BSSAP.send(paging);
8050
8051 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8052 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8053 * channel number is picked here. */
8054 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8055 f_rslem_register(0, new_chan_nr);
8056 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8057 f_rslem_unregister(0, new_chan_nr);
8058
8059 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8060 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008061 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008062 f_sleep(1.0);
8063}
8064testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8065 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8066 f_sleep(1.0);
8067
8068 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8069 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8070 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8071
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008072 f_ctrs_msc_init();
8073
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008074 var MSC_ConnHdlr vc_conn1;
8075 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8076 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008077 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8078 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008079 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8080 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008081 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008082 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008083}
8084
8085/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8086 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8087private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8088 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8089 //cid_list := { cIl_allInBSS := ''O };
8090 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8091 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8092 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008093 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008094 var BSSAP_N_UNITDATA_req paging;
8095
8096 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8097
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008098 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008099 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8100 BSSAP.send(paging);
8101
8102 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8103 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8104 * channel number is picked here. */
8105 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8106 f_rslem_register(0, new_chan_nr);
8107 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8108 f_rslem_unregister(0, new_chan_nr);
8109
8110 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8111 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8112 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008113 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 +02008114 f_sleep(1.0);
8115}
8116testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8117 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8118 f_sleep(1.0);
8119
8120 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8121 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8122 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8123
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008124 f_ctrs_msc_init();
8125
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008126 var MSC_ConnHdlr vc_conn1;
8127 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8128 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008129 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8130 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008131 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8132 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008133 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008134 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008135}
8136
8137/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8138/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8139 * just as well using only RSL. */
8140testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8141
8142 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8143 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008144 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8145 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008146
8147 /* Control which MSC gets chosen next by the round-robin, otherwise
8148 * would be randomly affected by which other tests ran before this. */
8149 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8150
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008151 f_ctrs_msc_init();
8152
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008153 var MSC_ConnHdlr vc_conn1;
8154 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8155 pars1.mscpool.rsl_idx := 0;
8156 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8157 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8158 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008159 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008160
8161 var MSC_ConnHdlr vc_conn2;
8162 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8163 pars2.mscpool.rsl_idx := 1;
8164 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8165 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8166 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008167 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008168
8169 var MSC_ConnHdlr vc_conn3;
8170 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8171 pars3.mscpool.rsl_idx := 2;
8172 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8173 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8174 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008175 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008176 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008177}
8178
8179/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8180 * TMSI NRI. */
8181testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8182
8183 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8184 f_sleep(1.0);
8185
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008186 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8187 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8188
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008189 /* Control which MSC gets chosen next by the round-robin, otherwise
8190 * would be randomly affected by which other tests ran before this. */
8191 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8192
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008193 f_ctrs_msc_init();
8194
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008195 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8196 var MSC_ConnHdlr vc_conn1;
8197 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8198 pars1.mscpool.rsl_idx := 0;
8199 /* An NRI of the second MSC's range (256-511) */
8200 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8201 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8202 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008203 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008204
8205 var MSC_ConnHdlr vc_conn2;
8206 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8207 pars2.mscpool.rsl_idx := 1;
8208 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8209 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8210 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008211 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008212
8213 var MSC_ConnHdlr vc_conn3;
8214 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8215 pars3.mscpool.rsl_idx := 2;
8216 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8217 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8218 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008219 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008220 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008221}
8222
Philipp Maier783681c2020-07-16 16:47:06 +02008223/* Allow/Deny emergency calls globally via VTY */
8224private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8225 f_vty_enter_cfg_msc(BSCVTY, 0);
8226 if (allow) {
8227 f_vty_transceive(BSCVTY, "allow-emergency allow");
8228 } else {
8229 f_vty_transceive(BSCVTY, "allow-emergency deny");
8230 }
8231 f_vty_transceive(BSCVTY, "exit");
8232 f_vty_transceive(BSCVTY, "exit");
8233}
8234
8235/* Allow/Deny emergency calls per BTS via VTY */
8236private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8237 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8238 if (allow) {
8239 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8240 } else {
8241 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8242 }
8243 f_vty_transceive(BSCVTY, "exit");
8244 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008245 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008246}
8247
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008248/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8249private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8250 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8251 if (allow) {
8252 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8253 } else {
8254 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8255 }
8256 f_vty_transceive(BSCVTY, "exit");
8257 f_vty_transceive(BSCVTY, "exit");
8258 f_vty_transceive(BSCVTY, "exit");
8259}
8260
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008261/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8262private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8263 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8264 if (allow) {
8265 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8266 } else {
8267 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8268 }
8269 f_vty_transceive(BSCVTY, "exit");
8270 f_vty_transceive(BSCVTY, "exit");
8271 f_vty_transceive(BSCVTY, "exit");
8272}
8273
Philipp Maier783681c2020-07-16 16:47:06 +02008274/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8275private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8276 var PDU_ML3_MS_NW emerg_setup;
8277 var octetstring emerg_setup_enc;
8278 var RSL_Message emerg_setup_data_ind;
8279
8280 f_establish_fully(omit, omit);
8281
8282 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8283 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8284 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8285
8286 RSL.send(emerg_setup_data_ind);
8287}
8288
8289/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8290 * CALLS are permitted by the BSC config. */
8291private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8292 var PDU_BSSAP emerg_setup_data_ind_bssap;
8293 var PDU_ML3_MS_NW emerg_setup;
8294 timer T := 3.0;
8295
8296 f_assignment_emerg_setup()
8297
8298 T.start;
8299 alt {
8300 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8301 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8302 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8303 setverdict(fail, "no emergency setup");
8304 }
8305 }
8306 [] BSSAP.receive {
8307 setverdict(fail, "unexpected BSSAP message!");
8308 }
8309 [] T.timeout {
8310 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8311 }
8312 }
8313
8314 setverdict(pass);
8315}
8316
8317/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8318 * forbidden by the BSC config. */
8319private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8320 var PDU_BSSAP emerg_setup_data_ind_bssap;
8321 timer T := 3.0;
8322
8323 f_assignment_emerg_setup()
8324
8325 T.start;
8326 alt {
8327 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8328 setverdict(pass);
8329 }
8330 [] RSL.receive {
8331 setverdict(fail, "unexpected RSL message!");
8332 }
8333 [] T.timeout {
8334 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8335 }
8336 }
8337}
8338
8339/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8340testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8341 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8342 var MSC_ConnHdlr vc_conn;
8343
8344 f_init(1, true);
8345 f_sleep(1.0);
8346
8347 f_vty_allow_emerg_msc(true);
8348 f_vty_allow_emerg_bts(true, 0);
8349 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8350 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008351 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008352}
8353
8354/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8355testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8356 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8357 var MSC_ConnHdlr vc_conn;
8358
8359 f_init(1, true);
8360 f_sleep(1.0);
8361
8362 f_vty_allow_emerg_msc(false);
8363 f_vty_allow_emerg_bts(true, 0);
8364 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8365 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008366 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008367}
8368
8369/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8370testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8371 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8372 var MSC_ConnHdlr vc_conn;
8373
8374 /* Note: This simulates a spec violation by the MS, correct MS
8375 * implementations would not try to establish an emergency call because
8376 * the system information tells in advance that emergency calls are
8377 * not forbidden */
8378
8379 f_init(1, true);
8380 f_sleep(1.0);
8381
8382 f_vty_allow_emerg_msc(true);
8383 f_vty_allow_emerg_bts(false, 0);
8384 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8385 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008386 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008387}
8388
Philipp Maier82812002020-08-13 18:48:27 +02008389/* Test what happens when an emergency call arrives while all TCH channels are
8390 * busy, the BSC is expected to terminate one call in favor of the incoming
8391 * emergency call */
8392testcase TC_emerg_premption() runs on test_CT {
8393 var ASP_RSL_Unitdata rsl_ud;
8394 var integer i;
8395 var integer chreq_total, chreq_nochan;
8396 var RSL_Message rx_rsl;
8397 var RslChannelNr chan_nr;
8398
8399 f_init(1);
8400 f_sleep(1.0);
8401
8402 f_vty_allow_emerg_msc(true);
8403 f_vty_allow_emerg_bts(true, 0);
8404
8405 /* Fill up all channels on the BTS */
8406 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8407 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8408 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8409 chan_nr := f_chreq_act_ack('33'O, i);
8410 }
8411 IPA_RSL[0].clear;
8412 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8413 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8414
8415 /* Send Channel request for emegergency call */
8416 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8417
8418 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8419 chan_nr := valueof(t_RslChanNr_Bm(1));
8420 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8421
8422 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8423 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8424 chan_nr := rx_rsl.ies[0].body.chan_nr;
8425 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8426 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008427
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008428 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008429}
8430
8431/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008432private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008433private type record FHParamsTs {
8434 boolean enabled,
8435 uint6_t hsn,
8436 uint6_t maio,
8437 ArfcnList ma
8438};
8439
8440/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008441private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02008442 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008443 FHParamsTs ts[8]
8444};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008445
8446/* Randomly generate the hopping parameters for the given timeslot numbers */
8447private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8448runs on test_CT return FHParamsTrx {
8449 var FHParamsTrx fhp;
8450
Philipp Maier798d8952021-10-19 14:43:19 +02008451 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
8452 * fall in the GSM900 band. */
8453 fhp.arfcn.arfcn := f_rnd_int(3);
8454 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008455
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008456 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8457 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008458 fhp.ts[tn].enabled := false;
8459 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008460 continue;
8461 }
8462
8463 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008464 fhp.ts[tn].hsn := f_rnd_int(64);
8465 fhp.ts[tn].maio := f_rnd_int(64);
8466 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008467
8468 /* Random Mobile Allocation (hopping channels) */
8469 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8470 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8471 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008472 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008473 }
8474
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008475 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008476 }
8477
8478 log("f_TC_fh_params_gen(): ", fhp);
8479 return fhp;
8480}
8481
8482/* Make sure that the given Channel Description IE matches the hopping configuration */
8483private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8484{
8485 var template (present) ChannelDescription tr_cd;
8486 var template (present) MaioHsn tr_maio_hsn;
8487 var uint3_t tn := cd.chan_nr.tn;
8488
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008489 if (fhp.ts[tn].enabled) {
8490 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008491 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8492 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02008493 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008494 }
8495
8496 if (not match(cd, tr_cd)) {
8497 setverdict(fail, "Channel Description IE does not match: ",
8498 cd, " vs expected ", tr_cd);
8499 }
8500}
8501
8502/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8503private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8504 in MobileAllocationLV ma)
8505{
8506 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8507
8508 if (not match(ma, tr_ma)) {
8509 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8510 tn, "): ", ma, " vs expected: ", tr_ma);
8511 } else {
8512 setverdict(pass);
8513 }
8514}
8515
8516private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8517 in MobileAllocationLV ma)
8518return template MobileAllocationLV {
8519 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008520 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008521 return { len := 0, ma := ''B };
8522 }
8523
8524 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8525 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8526 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008527
8528 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008529 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8530 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8531 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008532 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008533 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008534 }
8535 }
8536
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008537 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02008538 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008539
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008540 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008541 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8542 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008543 }
8544
8545 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008546 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008547 if (full_mask[i] != '1'B)
8548 { continue; }
8549
8550 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8551 if (slot_mask[i] == '1'B) {
8552 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008553 } else {
8554 ma_mask := ma_mask & '0'B;
8555 }
8556 }
8557
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008558 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8559 if (full_mask[0] == '1'B) {
8560 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8561 if (slot_mask[0] == '1'B) {
8562 ma_mask := ma_mask & '1'B;
8563 } else {
8564 ma_mask := ma_mask & '0'B;
8565 }
8566 }
8567
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008568 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008569 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008570 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8571
8572 return { len := ma_mask_len, ma := ma_mask };
8573}
8574
Philipp Maier798d8952021-10-19 14:43:19 +02008575/* Configure the appropriate band for a given arfcn, exc */
8576private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
8577{
8578 var charstring band;
8579 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
8580
8581 select (arfcn_) {
8582 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
8583 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
8584 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
8585 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
8586 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
8587 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
8588 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
8589 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
8590 case else { return; }
8591 }
8592
8593 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8594 f_vty_transceive(BSCVTY, "band " & band);
8595 f_vty_transceive(BSCVTY, "end");
8596}
8597
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008598/* Configure the hopping parameters in accordance with the given record */
8599private function f_TC_fh_params_set(in FHParamsTrx fhp,
8600 uint8_t bts_nr := 0,
8601 uint8_t trx_nr := 0)
8602runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008603
8604 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
8605
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008606 /* Enter the configuration node for the given BTS/TRX numbers */
8607 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8608
Philipp Maier798d8952021-10-19 14:43:19 +02008609 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008610
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008611 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008612 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8613
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008614 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008615 f_vty_transceive(BSCVTY, "hopping enabled 0");
8616 f_vty_transceive(BSCVTY, "exit"); /* go back */
8617 continue;
8618 }
8619
8620 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008621 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8622 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008623
8624 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008625 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8626 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008627 }
8628
8629 f_vty_transceive(BSCVTY, "hopping enabled 1");
8630 f_vty_transceive(BSCVTY, "exit"); /* go back */
8631 }
8632
8633 f_vty_transceive(BSCVTY, "end");
8634}
8635
8636/* Disable frequency hopping on all timeslots */
8637private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8638 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008639 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02008640 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008641runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008642
8643 f_TC_set_band_by_arfcn(bts_nr, arfcn);
8644
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008645 /* Enter the configuration node for the given BTS/TRX numbers */
8646 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8647
Philipp Maier798d8952021-10-19 14:43:19 +02008648 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008649
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008650 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008651 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8652
8653 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008654 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8655 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008656 }
8657
8658 f_vty_transceive(BSCVTY, "hopping enabled 0");
8659 f_vty_transceive(BSCVTY, "exit"); /* go back */
8660 }
8661
8662 f_vty_transceive(BSCVTY, "end");
8663 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8664}
8665
8666/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8667 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8668testcase TC_fh_params_chan_activ() runs on test_CT {
8669 var FHParamsTrx fhp := f_TC_fh_params_gen();
8670 var RSL_Message rsl_msg;
8671 var RSL_IE_Body ie;
8672
8673 f_init_vty();
8674
8675 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8676 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8677
8678 f_init(1);
8679
8680 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8681 for (var integer i := 0; i < 9; i := i + 1) {
8682 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8683 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8684
8685 /* Make sure that Channel Identification IE is present */
8686 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8687 setverdict(fail, "RSL Channel Identification IE is absent");
8688 continue;
8689 }
8690
8691 /* Make sure that hopping parameters (HSN/MAIO) match */
8692 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8693
8694 /* "Mobile Allocation shall be included but empty" - let's check this */
8695 if (ie.chan_ident.ma.v.len != 0) {
8696 setverdict(fail, "Mobile Allocation IE is not empty: ",
8697 ie.chan_ident.ma, ", despite it shall be");
8698 continue;
8699 }
8700 }
8701
8702 /* Disable frequency hopping */
8703 f_TC_fh_params_unset(fhp);
8704
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008705 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008706}
8707
8708/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8709testcase TC_fh_params_imm_ass() runs on test_CT {
8710 var FHParamsTrx fhp := f_TC_fh_params_gen();
8711 var RSL_Message rsl_msg;
8712 var RSL_IE_Body ie;
8713
8714 f_init_vty();
8715
8716 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8717 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8718
8719 f_init(1);
8720
8721 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8722 for (var integer i := 0; i < 9; i := i + 1) {
8723 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8724 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8725
8726 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8727 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8728
8729 /* Make sure that Full Immediate Assign Info IE is present */
8730 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8731 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8732 continue;
8733 }
8734
8735 /* Decode the actual Immediate Assignment message */
8736 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8737 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8738 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8739 continue;
8740 }
8741
8742 /* Make sure that hopping parameters (HSN/MAIO) match */
8743 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8744
8745 /* Make sure that the Mobile Allocation IE matches */
8746 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8747 rr_msg.payload.imm_ass.mobile_allocation);
8748 }
8749
8750 /* Disable frequency hopping */
8751 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008752
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008753 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008754}
8755
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008756/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8757testcase TC_fh_params_assignment_cmd() runs on test_CT {
8758 var FHParamsTrx fhp := f_TC_fh_params_gen();
8759 var RSL_Message rsl_msg;
8760 var RSL_IE_Body ie;
8761
8762 f_init_vty();
8763
8764 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8765 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8766
8767 f_init(1);
8768
8769 /* HACK: work around "Couldn't find Expect for CRCX" */
8770 vc_MGCP.stop;
8771
8772 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8773 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8774
8775 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8776 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8777 for (var integer i := 0; i < 3; i := i + 1) {
8778 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8779 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8780
8781 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8782 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8783 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8784
8785 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8786 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8787 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8788
8789 /* Make sure that L3 Information IE is present */
8790 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8791 setverdict(fail, "RSL L3 Information IE is absent");
8792 continue;
8793 }
8794
8795 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8796 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8797 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8798 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8799 continue;
8800 }
8801
8802 /* Make sure that hopping parameters (HSN/MAIO) match */
8803 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8804 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8805
8806 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8807 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008808 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008809 continue;
8810 }
8811
8812 /* Make sure that the Mobile Allocation IE matches (if present) */
8813 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8814 if (chan_desc.h and ma_present) {
8815 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8816 l3_msg.payload.ass_cmd.mobile_allocation.v);
8817 } else if (chan_desc.h and not ma_present) {
8818 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8819 continue;
8820 } else if (not chan_desc.h and ma_present) {
8821 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8822 continue;
8823 }
8824 }
8825
8826 /* Give the IUT some time to release all channels */
8827 f_sleep(3.0);
8828
8829 /* Disable frequency hopping */
8830 f_TC_fh_params_unset(fhp);
8831
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008832 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008833}
8834
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008835/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8836private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8837runs on test_CT {
8838 var RSL_Message rsl_msg;
8839 var RSL_IE_Body ie;
8840 var DchanTuple dt;
8841
8842 /* Establish a dedicated channel, so we can trigger handover */
8843 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8844
8845 /* Trigger handover from BTS0 to BTS1 */
8846 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8847 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8848
8849 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8850 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8851
8852 /* ACKnowledge channel activation and expect (RR) Handover Command */
8853 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8854 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8855
8856 /* Make sure that L3 Information IE is present */
8857 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8858 setverdict(fail, "RSL L3 Information IE is absent");
8859 return;
8860 }
8861
8862 /* Decode the L3 message and make sure it is (RR) Handover Command */
8863 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8864 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8865 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8866 return;
8867 }
8868
8869 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8870 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8871 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8872 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8873 return;
8874 }
8875
8876 /* Make sure that hopping parameters (HSN/MAIO) match */
8877 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8878
8879 /* Make sure that Cell Channel Description IE is present */
8880 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8881 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8882 return;
8883 }
8884
8885 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8886 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8887 if (ma_present) {
8888 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8889 l3_msg.payload.ho_cmd.mobile_allocation.v);
8890 } else {
8891 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8892 return;
8893 }
8894}
8895testcase TC_fh_params_handover_cmd() runs on test_CT {
8896 var FHParamsTrx fhp := f_TC_fh_params_gen();
8897
8898 f_init_vty();
8899
8900 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8901 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8902
8903 f_vty_transceive(BSCVTY, "timeslot 0");
8904 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8905 f_vty_transceive(BSCVTY, "exit"); /* go back */
8906
8907 f_vty_transceive(BSCVTY, "timeslot 1");
8908 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8909 f_vty_transceive(BSCVTY, "end"); /* we're done */
8910
8911 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8912 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8913
8914 f_init(2);
8915
8916 f_TC_fh_params_handover_cmd(fhp);
8917
8918 /* Disable frequency hopping on BTS1 */
8919 f_TC_fh_params_unset(fhp, 1);
8920
8921 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8922 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8923
8924 f_vty_transceive(BSCVTY, "timeslot 0");
8925 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8926 f_vty_transceive(BSCVTY, "exit"); /* go back */
8927
8928 f_vty_transceive(BSCVTY, "timeslot 1");
8929 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8930 f_vty_transceive(BSCVTY, "end"); /* we're done */
8931
8932 f_shutdown_helper();
8933}
8934
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008935/* Verify the hopping parameters in System Information Type 4 */
8936testcase TC_fh_params_si4_cbch() runs on test_CT {
8937 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8938 var ASP_RSL_Unitdata rx_rsl_ud;
8939 timer T := 5.0;
8940
8941 f_init_vty();
8942
8943 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
8944 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8945
8946 f_vty_transceive(BSCVTY, "timeslot 0");
8947 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8948 f_vty_transceive(BSCVTY, "exit"); /* go back */
8949
8950 f_vty_transceive(BSCVTY, "timeslot 1");
8951 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
8952 f_vty_transceive(BSCVTY, "end"); /* we're done */
8953
8954 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8955 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8956
8957 f_init(1);
8958
8959 T.start;
8960 alt {
8961 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
8962 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
8963 var SystemInformation si := dec_SystemInformation(ie.other.payload);
8964
8965 /* Make sure that what we decoded is System Information Type 4 */
8966 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
8967 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
8968 repeat;
8969 }
8970
8971 /* Make sure that CBCH Channel Description IE is present */
8972 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
8973 setverdict(fail, "CBCH Channel Description IE is absent");
8974 break;
8975 }
8976
8977 /* Finally, check the hopping parameters (HSN, MAIO) */
8978 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
8979 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8980
8981 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
8982 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
8983 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
8984 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8985 break;
8986 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
8987 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8988 si.payload.si4.cbch_mobile_alloc.v);
8989 }
8990 }
8991 [] IPA_RSL[0].receive { repeat; }
8992 [] T.timeout {
8993 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
8994 }
8995 }
8996
8997 /* Disable frequency hopping */
8998 f_TC_fh_params_unset(fhp);
8999
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009000 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009001 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9002
9003 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009004 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009005 f_vty_transceive(BSCVTY, "exit"); /* go back */
9006
9007 f_vty_transceive(BSCVTY, "timeslot 1");
9008 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9009 f_vty_transceive(BSCVTY, "end"); /* we're done */
9010
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009011 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009012}
9013
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009014template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9015 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9016
9017private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9018 template (present) BSSLAP_PDU expect_bsslap)
9019{
9020 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9021 if (not match(bsslap, expect_bsslap)) {
9022 log("EXPECTING BSSLAP: ", expect_bsslap);
9023 log("GOT BSSLAP: ", bsslap);
9024 setverdict(fail, "BSSLAP is not as expected");
9025 mtc.stop;
9026 }
9027 setverdict(pass);
9028}
9029
9030/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9031const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9032
9033private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9034 var PDU_BSSAP_LE rx_bsslap;
9035 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9036 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9037}
9038
9039/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9040 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9041private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9042 f_sleep(1.0);
9043
9044 f_establish_fully(omit, omit);
9045 f_bssap_le_register_imsi(g_pars.imsi, omit);
9046
9047 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9048 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9049
9050 var PDU_BSSAP_LE plr;
9051 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9052
9053 if (not do_ta_request) {
9054 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9055 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9056 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9057 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9058 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9059 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9060 mtc.stop;
9061 }
9062 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9063 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9064 if (not match(bsslap, expect_ta_layer3)) {
9065 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9066 log("GOT BSSLAP: ", bsslap);
9067 setverdict(fail, "BSSLAP is not as expected");
9068 mtc.stop;
9069 }
9070 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9071 * has no need to request the TA from the BSC and directly responds. */
9072 } else {
9073 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9074 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9075 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9076 }
9077
9078 /* SMLC got the TA from the BSC, now responds with geo information data. */
9079 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9080 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9081 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9082
9083 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9084 f_mo_l3_transceive();
9085
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009086 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009087
9088 f_sleep(2.0);
9089 setverdict(pass);
9090}
9091
9092/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9093 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9094private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9095 f_lcs_loc_req_for_active_ms(false);
9096}
9097testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9098 var MSC_ConnHdlr vc_conn;
9099 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9100
9101 f_init(1, true);
9102 f_sleep(1.0);
9103 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9104 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009105 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009106}
9107
9108/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9109 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9110private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9111 f_lcs_loc_req_for_active_ms(true);
9112}
9113testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9114 var MSC_ConnHdlr vc_conn;
9115 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9116
9117 f_init(1, true);
9118 f_sleep(1.0);
9119 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9120 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009121 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009122}
9123
9124/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9125 * conn without an active lchan. */
9126private function f_clear_A_conn() runs on MSC_ConnHdlr
9127{
9128 var BssmapCause cause := 0;
9129 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9130 BSSAP.receive(tr_BSSMAP_ClearComplete);
9131 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9132
9133 timer no_more_bssap := 5.0;
9134 no_more_bssap.start;
9135 alt {
9136 [] no_more_bssap.timeout { break; }
9137 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9138 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9139 mtc.stop;
9140 }
9141 }
9142 setverdict(pass);
9143}
9144
9145/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9146 * for LCS, for cases where there is only an A conn without an active lchan. */
9147private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9148{
9149 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9150
9151 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9152 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9153 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9154 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9155 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9156 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9157
9158 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9159 f_clear_A_conn();
9160 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9161 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9162}
9163
9164/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9165 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9166 */
9167private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9168 f_sleep(1.0);
9169
9170 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9171 f_bssap_le_register_imsi(g_pars.imsi, omit);
9172
9173 /* Register to receive the Paging Command */
9174 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9175 g_chan_nr := new_chan_nr;
9176 f_rslem_register(0, g_chan_nr);
9177
9178 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9179 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9180 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9181 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9182
9183 var PDU_BSSAP_LE plr;
9184 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9185
9186 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9187 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9188
9189 /* OsmoBSC needs to Page */
9190 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9191 f_logp(BSCVTY, "got Paging Command");
9192
9193 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9194 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009195 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);
9196 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009197
9198 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9199
9200 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9201
9202 /* SMLC got the TA from the BSC, now responds with geo information data. */
9203 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9204 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9205
9206 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9207
9208 /* The lchan is gone, the A-interface conn was created for the LCS only.
9209 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9210 f_verify_active_A_conn_and_clear();
9211
9212 f_sleep(2.0);
9213 setverdict(pass);
9214}
9215testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9216 var MSC_ConnHdlr vc_conn;
9217 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9218
9219 f_init(1, true);
9220 f_sleep(1.0);
9221
9222 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9223 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9224
9225 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9226 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009227 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009228}
9229
9230/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9231 */
9232private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9233 f_sleep(1.0);
9234
9235 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9236 f_bssap_le_register_imsi(g_pars.imsi, omit);
9237
9238 /* provoke an abort by omitting both IMSI and IMEI */
9239 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9240 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9241 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9242 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9243
9244 /* BSC tells MSC about failure */
9245 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9246 locationEstimate := omit, positioningData := omit,
9247 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9248
9249 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9250 f_verify_active_A_conn_and_clear();
9251
9252 f_sleep(2.0);
9253 setverdict(pass);
9254}
9255testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9256 var MSC_ConnHdlr vc_conn;
9257 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9258
9259 f_init(1, true);
9260 f_sleep(1.0);
9261
9262 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9263 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9264
9265 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9266 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009267 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009268}
9269
9270/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9271 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9272private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9273 f_sleep(1.0);
9274
9275 f_establish_fully(omit, omit);
9276 f_bssap_le_register_imsi(g_pars.imsi, omit);
9277
9278 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9279 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9280
9281 var PDU_BSSAP_LE plr;
9282 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9283
9284 if (do_ta) {
9285 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9286 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9287 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9288 }
9289
9290 /* SMLC fails to respond, BSC runs into timeout */
9291 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9292 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9293
9294 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9295 locationEstimate := omit, positioningData := omit,
9296 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9297
9298 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9299 f_verify_active_A_conn_and_clear();
9300
9301 f_sleep(2.0);
9302 setverdict(pass);
9303}
9304
9305/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9306 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9307private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9308 f_lcs_loc_req_for_active_ms_le_timeout(false);
9309}
9310
9311testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9312 var MSC_ConnHdlr vc_conn;
9313 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9314
9315 f_init(1, true);
9316 f_sleep(1.0);
9317 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9318 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009319 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009320}
9321
9322/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9323 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9324private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9325 f_lcs_loc_req_for_active_ms_le_timeout(true);
9326}
9327
9328testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9329 var MSC_ConnHdlr vc_conn;
9330 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9331
9332 f_init(1, true);
9333 f_sleep(1.0);
9334 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9335 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009336 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009337}
9338
9339/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9340private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9341 f_sleep(1.0);
9342
9343 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9344 f_bssap_le_register_imsi(g_pars.imsi, omit);
9345
9346 /* Register to receive the Paging Command */
9347 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9348 g_chan_nr := new_chan_nr;
9349 f_rslem_register(0, g_chan_nr);
9350
9351 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9352 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9353 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9354 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9355
9356 var PDU_BSSAP_LE plr;
9357 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9358
9359 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9360 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9361
9362 /* OsmoBSC needs to Page */
9363 var PDU_BSSAP_LE rx_bsslap;
9364 alt {
9365 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9366 f_logp(BSCVTY, "got Paging Command");
9367 repeat;
9368 }
9369 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9370 /* MS does not respond to Paging, TA Req runs into timeout. */
9371 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9372 }
9373 }
9374
9375 /* SMLC responds with failure */
9376 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9377 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9378
9379 /* BSC tells MSC about failure */
9380 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9381 locationEstimate := omit, positioningData := omit,
9382 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9383
9384 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9385 f_verify_active_A_conn_and_clear();
9386
9387 f_sleep(2.0);
9388 setverdict(pass);
9389}
9390testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9391 var MSC_ConnHdlr vc_conn;
9392 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9393
9394 f_init(1, true);
9395 f_sleep(1.0);
9396
9397 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9398 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9399
9400 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9401 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009402 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009403}
9404
9405/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9406 * over. */
9407private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9408 f_sleep(1.0);
9409
9410 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9411 f_bssap_le_register_imsi(g_pars.imsi, omit);
9412
9413 /* Register to receive the Paging Command */
9414 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9415 g_chan_nr := new_chan_nr;
9416 f_rslem_register(0, g_chan_nr);
9417
9418 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9419 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9420 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9421 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9422
9423 var PDU_BSSAP_LE plr;
9424 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9425
9426 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9427 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009428 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 +02009429 do_clear := false, expect_bssmap_l3 := true);
9430
9431 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9432 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9433
9434 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9435 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9436
9437 /* SMLC got the TA from the BSC, now responds with geo information data. */
9438 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9439 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9440 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9441
9442 /* The lchan should still exist, it was from a CM Service Request. */
9443 f_mo_l3_transceive();
9444
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009445 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009446
9447 f_sleep(2.0);
9448 setverdict(pass);
9449}
9450testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9451 var MSC_ConnHdlr vc_conn;
9452 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9453
9454 f_init(1, true);
9455 f_sleep(1.0);
9456
9457 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9458 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9459
9460 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9461 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009462 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009463}
9464
9465/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9466 * the new lchan after handover. */
9467private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9468 f_sleep(1.0);
9469
9470 f_establish_fully(omit, omit);
9471 f_bssap_le_register_imsi(g_pars.imsi, omit);
9472
9473 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9474 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9475
9476 var PDU_BSSAP_LE plr;
9477 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9478
9479 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9480 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9481
9482 var HandoverState hs := {
9483 rr_ho_cmpl_seen := false,
9484 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02009485 old_chan_nr := -,
9486 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009487 };
9488 /* issue hand-over command on VTY */
9489 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9490 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9491 f_rslem_suspend(RSL1_PROC);
9492
9493 /* From the MGW perspective, a handover is is characterized by
9494 * performing one MDCX operation with the MGW. So we expect to see
9495 * one more MDCX during handover. */
9496 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9497
9498 alt {
9499 [] as_handover(hs);
9500 }
9501
9502 var PDU_BSSAP_LE rx_bsslap;
9503
9504 interleave {
9505 /* Expect the BSC to inform the MSC about the handover */
9506 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9507
9508 /* Expect the BSC to inform the SMLC about the handover */
9509 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9510 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9511 }
9512 }
9513
9514 /* SMLC now responds with geo information data. */
9515 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9516 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9517 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9518
9519 /* lchan still active */
9520 f_mo_l3_transceive(RSL1);
9521
9522 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009523 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009524
9525 f_sleep(2.0);
9526 setverdict(pass);
9527}
9528testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9529 var MSC_ConnHdlr vc_conn;
9530 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9531
9532 f_init(2, true);
9533 f_sleep(1.0);
9534 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9535 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009536 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009537}
9538
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009539/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9540private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9541 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9542
9543 /* Also disable attach for the single connected MSC */
9544 f_vty_msc_allow_attach(BSCVTY, { false });
9545
9546 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) ));
9547 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9548
9549 /* No MSC is found, expecting a proper release on RSL */
9550 interleave {
9551 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9552 f_logp(BSCVTY, "Got RSL RR Release");
9553 }
9554 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9555 f_logp(BSCVTY, "Got RSL Deact SACCH");
9556 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009557 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009558 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9559 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009560 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009561 }
9562 }
9563 setverdict(pass);
9564}
9565testcase TC_no_msc() runs on test_CT {
9566
9567 f_init(1, true);
9568 f_sleep(1.0);
9569 var MSC_ConnHdlr vc_conn;
9570 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9571
9572 f_ctrs_bsc_init(counternames_bsc_mscpool);
9573
9574 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9575 vc_conn.done;
9576
9577 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9578 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009579 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009580}
9581
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009582/* Dyn PDCH todo:
9583 * activate OSMO as TCH/F
9584 * activate OSMO as TCH/H
9585 * does the BSC-located PCU socket get the updated INFO?
9586 * what if no PCU is connected at the time?
9587 * is the info correct on delayed PCU (re)connect?
9588 */
Harald Welte94e0c342018-04-07 11:33:23 +02009589
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009590private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9591 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9592 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9593
9594 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9595 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9596 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9597 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9598 g_pars.ass_codec_list.codecElements[0];
9599 if (isvalue(g_pars.expect_mr_s0_s7)) {
9600 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9601 g_pars.expect_mr_s0_s7;
9602 }
9603 }
9604 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9605 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9606 log("expecting ASS COMPL like this: ", exp_compl);
9607
9608 f_establish_fully(ass_cmd, exp_compl);
9609
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009610 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 +00009611
9612 var RSL_Message rsl;
9613
9614 timer T := 5.0;
9615 T.start;
9616 alt {
9617 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9618 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9619 log("Rx L3 from net: ", l3);
9620 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9621 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9622 mtc.stop;
9623 }
9624 }
9625 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9626 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9627 mtc.stop;
9628 }
9629 [] T.timeout {
9630 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9631 setverdict(pass);
9632 }
9633 }
9634 T.stop;
9635}
9636
9637/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9638 * osmo-bsc. */
9639testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9640 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9641 var MSC_ConnHdlr vc_conn;
9642
9643 f_init(1, true);
9644 f_sleep(1.0);
9645
9646 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9647 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9648 vc_conn.done;
9649 f_shutdown_helper();
9650}
9651
9652/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9653 */
9654testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9655 f_init_vty();
9656
9657 f_init(1, false);
9658 f_sleep(1.0);
9659
9660 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9661
9662 var ASP_RSL_Unitdata rx_rsl_ud;
9663 timer T := 5.0;
9664
9665 T.start;
9666 alt {
9667 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9668 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9669 T.stop;
9670 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9671 mtc.stop;
9672 }
9673 repeat;
9674 }
9675 [] T.timeout {
9676 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9677 setverdict(pass);
9678 }
9679 }
9680}
9681
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009682private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9683 /* First fully set up a speech lchan */
9684 f_TC_assignment_codec(id);
9685
9686 /* Trigger re-assignment to another lchan */
9687 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9688
9689 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9690 * one MDCX on MGCP. */
9691 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9692
9693 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9694 * as the old lchan used. */
9695 g_media.bts.ipa_crcx_seen := false;
9696 g_media.bts.ipa_mdcx_seen := false;
9697
9698 /* Send different BTS side RTP port number for the new lchan */
9699 g_media.bts.bts.port_nr := 4223;
9700
9701 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9702
9703 /* Trigger re-assignment. */
9704 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9705
9706 timer T := 5.0;
9707 T.start;
9708 alt {
9709 [] as_assignment(assignment_st);
9710 [] as_Media();
9711 [] T.timeout {
9712 break;
9713 }
9714 }
9715
9716 if (not assignment_st.assignment_done) {
9717 setverdict(fail, "Assignment did not complete");
9718 mtc.stop;
9719 }
9720
9721 f_check_mgcp_expectations()
9722 setverdict(pass);
9723
9724 f_sleep(2.0);
9725 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9726
9727 /* Instruct BSC to clear channel */
9728 var BssmapCause cause := 0;
9729 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9730 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009731 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9732 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009733 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009734 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009735 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009736 }
9737 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9738 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9739 }
9740 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +02009741 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009742
9743 f_sleep(0.5);
9744}
9745
9746testcase TC_reassignment_fr() runs on test_CT {
9747 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9748 var MSC_ConnHdlr vc_conn;
9749
9750 f_init(1, true);
9751 f_sleep(1.0);
9752
9753 f_ctrs_bsc_and_bts_init();
9754
9755 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9756 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9757 vc_conn.done;
9758
9759 /* from f_establish_fully() */
9760 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9761 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9762 /* from re-assignment */
9763 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9764 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9765 f_ctrs_bsc_and_bts_verify();
9766 f_shutdown_helper();
9767}
9768
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009769const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9770const charstring REEST_CLEAR := "REEST_CLEAR";
9771const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9772
9773/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9774 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9775 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9776 * the MSC as the CM Re-Establishment is handled.
9777 *
9778 * MS bts0 bts1 bsc msc test-component
9779 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9780 * | | _1 wait a bit, to settle down
9781 * |<-x x--| | _1 "lose connection"
9782 * | | REEST_LOST_CONNECTION
9783 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9784 * | | REEST_CLEAR
9785 * | |<-0---| _1 Clear Command on first A-conn
9786 * | |--0-->| _1 Clear Complete
9787 * | |<----------------->| | _1 Release first channel
9788 * | | REEST_CLEAR_DONE
9789 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9790 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9791 *
9792 */
9793private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9794 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9795 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9796
9797 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9798 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9799
9800 f_establish_fully(ass_cmd, exp_compl);
9801
9802 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9803 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9804 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9805 f_sleep(2.0);
9806 COORD.send(REEST_LOST_CONNECTION);
9807
9808 alt {
9809 [] COORD.receive(REEST_CLEAR);
9810 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9811 setverdict(fail, "Unexpected channel release");
9812 mtc.stop;
9813 }
9814 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9815 setverdict(fail, "Unexpected channel release");
9816 mtc.stop;
9817 }
9818 }
9819 f_perform_clear()
9820 f_expect_dlcx_conns();
Neels Hofmeyr969abd02021-09-23 22:24:08 +02009821 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009822 COORD.send(REEST_CLEAR_DONE);
9823}
9824
9825private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9826 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9827
9828 /* The MS lost the connection on the first channel, now establishes another one */
9829 COORD.receive(REEST_LOST_CONNECTION);
9830
9831 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9832 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9833 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9834
9835 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009836 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 +02009837 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9838
9839 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9840 COORD.send(REEST_CLEAR);
9841 COORD.receive(REEST_CLEAR_DONE);
9842
9843 f_sleep(2.0);
9844
9845 /* Answer the CM Re-Establishment with an Assignment Command. */
9846 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9847 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9848 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9849 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9850
9851 var AssignmentState st := valueof(ts_AssignmentStateInit);
9852 st.voice_call := true;
9853 st.is_assignment := true;
9854
9855 var ExpectCriteria mgcpcrit := {
9856 connid := omit,
9857 endpoint := omit,
9858 transid := omit
9859 };
9860 f_create_mgcp_expect(mgcpcrit);
9861
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009862 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009863
9864 BSSAP.send(ass_cmd);
9865
9866 var PDU_BSSAP bssap;
9867
9868 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009869 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9870 [] as_Media_ipacc(RSL1, RSL2);
9871 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009872 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9873 break;
9874 }
9875 }
9876
9877 f_sleep(3.0);
9878
9879 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009880 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009881 f_expect_dlcx_conns();
9882}
9883
9884testcase TC_cm_reestablishment() runs on test_CT {
9885 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9886 var MSC_ConnHdlr vc_conn1;
9887
9888 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9889 var MSC_ConnHdlr vc_conn2;
9890 pars2.imsi := pars1.imsi;
9891 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +02009892 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009893
9894 f_init(2, true, guard_timeout := 40.0);
9895 f_sleep(1.0);
9896
9897 vc_conn1 := f_start_handler_create(pars1);
9898 vc_conn2 := f_start_handler_create(pars2);
9899 connect(vc_conn1:COORD, vc_conn2:COORD);
9900 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9901 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9902 vc_conn1.done;
9903 vc_conn2.done;
9904
9905 f_shutdown_helper();
9906}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009907
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009908function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9909 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9910runs on test_CT return template (omit) RSL_Message {
9911 var ASP_RSL_Unitdata rx_rsl_ud;
9912 timer T := t_secs;
9913
9914 T.start;
9915 alt {
9916 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9917 T.stop;
9918 }
9919 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9920 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9921 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9922 T.stop;
9923 return omit;
9924 }
9925 [] T.timeout {
9926 return omit;
9927 }
9928 }
9929 return rx_rsl_ud.rsl;
9930}
9931
9932private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9933 f_vty_enter_cfg_bts(pt, bts_nr);
9934 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9935 f_vty_transceive(pt, "exit");
9936 f_vty_transceive(pt, "exit");
9937 f_vty_transceive(pt, "exit");
9938}
9939
9940private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009941 template RslChannelNr chan_nr := ?,
9942 template (present) uint12_t arfcn := ?,
9943 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009944{
9945 var RSL_IE_Body full_imm_ass_info;
9946 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
9947 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9948 mtc.stop;
9949 }
9950
9951 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
9952 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
9953 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009954 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009955 page_mode := ?);
9956 if (not match(rr_imm_ass, expect_imm_ass)) {
9957 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
9958 setverdict(fail, "Failed to match Immediate Assignment");
9959 mtc.stop;
9960 }
9961}
9962
9963testcase TC_imm_ass_post_chan_ack() runs on test_CT {
9964 var RSL_Message chan_act;
9965 var RSL_Message imm_ass;
9966
9967 f_init(1, false);
9968 f_sleep(1.0);
9969
9970 /* (should be the default anyway, just to make things clear) */
9971 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
9972
9973 /* RA containing reason=LU */
9974 var GsmFrameNumber fn := 2342;
9975 var uint8_t ra := 2;
9976 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9977
9978 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9979
9980 /* First send the Chan Act ACK */
9981 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009982 var RSL_IE_Body chan_ident_ie;
9983 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9984 setverdict(fail, "RSL Channel Identification IE is absent");
9985 mtc.stop;
9986 }
9987
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009988 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
9989
9990 /* Then expect the Immediate Assignment, after we ACKed the chan act */
9991 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9992
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009993 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9994 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009995
9996 /* Check that the lchan is working */
9997 var octetstring l3 := '00010203040506'O;
9998 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9999
10000 var BSSAP_N_CONNECT_ind rx_c_ind;
10001 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10002 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10003
10004 f_sleep(1.0);
10005 f_shutdown_helper();
10006}
10007
10008testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10009 var RSL_Message chan_act;
10010 var RSL_Message imm_ass;
10011
10012 f_init(1, false);
10013 f_sleep(1.0);
10014
10015 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10016
10017 /* RA containing reason=LU */
10018 var GsmFrameNumber fn := 2342;
10019 var uint8_t ra := 2;
10020 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10021
10022 /* (set bts 0 cfg back to default) */
10023 f_vty_set_imm_ass(BSCVTY);
10024
10025 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10026 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010027 var RSL_IE_Body chan_ident_ie;
10028 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10029 setverdict(fail, "RSL Channel Identification IE is absent");
10030 mtc.stop;
10031 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010032
10033 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10034 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010035 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10036 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010037
10038 /* Only now send the Chan Act ACK */
10039 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10040
10041 /* Check that the lchan is working */
10042 var octetstring l3 := '00010203040506'O;
10043 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10044
10045 var BSSAP_N_CONNECT_ind rx_c_ind;
10046 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10047 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10048
10049 f_sleep(1.0);
10050 f_shutdown_helper();
10051}
10052
Neels Hofmeyr23158742021-09-07 19:08:07 +020010053testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10054 var RSL_Message chan_act;
10055 var RSL_Message imm_ass;
10056
10057 f_init(1, false);
10058 f_sleep(1.0);
10059
10060 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10061
10062 /* RA containing reason=LU */
10063 var GsmFrameNumber fn := 2342;
10064 var uint8_t ra := 2;
10065 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10066
10067 /* (set bts 0 cfg back to default) */
10068 f_vty_set_imm_ass(BSCVTY);
10069
10070 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10071 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
10072 var RSL_IE_Body chan_ident_ie;
10073 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10074 setverdict(fail, "RSL Channel Identification IE is absent");
10075 mtc.stop;
10076 }
10077
10078 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10079 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10080 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10081 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10082
10083 /* Only now send the Chan Act ACK */
10084 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10085
10086 /* Check that the lchan is working */
10087 var octetstring l3 := '00010203040506'O;
10088 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10089
10090 var BSSAP_N_CONNECT_ind rx_c_ind;
10091 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10092 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10093
10094 f_sleep(1.0);
10095 f_shutdown_helper();
10096}
10097
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010098testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10099 /* change Timeslot 6 before f_init() starts RSL */
10100 f_init_vty();
10101 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10102 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10103
10104 f_init(1, false);
10105 f_sleep(1.0);
10106
10107 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10108 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10109 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10110 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10111
10112 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10113 f_ts_set_chcomb(0, 0, 6, "PDCH");
10114
10115 /* block all static timeslots so that the dyn TS will be used */
10116 f_disable_all_tch_f();
10117 f_disable_all_tch_h();
10118 f_disable_all_sdcch();
10119
10120 var RSL_Message chan_act;
10121 var RSL_Message imm_ass;
10122
10123 f_init(1, false);
10124 f_sleep(1.0);
10125
10126 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10127
10128 /* RA containing reason=LU */
10129 var GsmFrameNumber fn := 2342;
10130 var uint8_t ra := 2;
10131 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10132
10133 /* (set bts 0 cfg back to default) */
10134 f_vty_set_imm_ass(BSCVTY);
10135
10136 /* Expect the dyn TS to deactivate PDCH first */
10137 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10138 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10139
10140 /* Now activation as SDCCH8 */
10141 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10142
10143 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010144 var RSL_IE_Body chan_ident_ie;
10145 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10146 setverdict(fail, "RSL Channel Identification IE is absent");
10147 mtc.stop;
10148 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010149
10150 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10151 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010152 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10153 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010154
10155 /* Only now send the Chan Act ACK */
10156 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10157
10158 /* Check that the lchan is working */
10159 var octetstring l3 := '00010203040506'O;
10160 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10161
10162 var BSSAP_N_CONNECT_ind rx_c_ind;
10163 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10164 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10165
10166 f_sleep(1.0);
10167 f_shutdown_helper();
10168}
10169
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010170testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10171 /* change Timeslot 6 before f_init() starts RSL */
10172 f_init_vty();
10173 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10174 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10175
10176 f_init(1, false);
10177 f_sleep(1.0);
10178
10179 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10180 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10181 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10182 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10183
10184 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10185 f_ts_set_chcomb(0, 0, 6, "PDCH");
10186
10187 /* block all static timeslots so that the dyn TS will be used */
10188 f_disable_all_tch_f();
10189 f_disable_all_tch_h();
10190 f_disable_all_sdcch();
10191
10192 var RSL_Message chan_act;
10193 var RSL_Message imm_ass;
10194
10195 f_init(1, false);
10196 f_sleep(1.0);
10197
10198 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10199
10200 /* RA containing reason=LU */
10201 var GsmFrameNumber fn := 2342;
10202 var uint8_t ra := 2;
10203 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10204
10205 /* (set bts 0 cfg back to default) */
10206 f_vty_set_imm_ass(BSCVTY);
10207
10208 /* Expect the dyn TS to deactivate PDCH first */
10209 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10210
10211 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10212 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10213
10214 /* continue the Osmo style PDCH Deact (usual chan rel) */
10215 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10216
10217 /* Now activation as SDCCH8 */
10218 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10219
10220 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010221 var RSL_IE_Body chan_ident_ie;
10222 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10223 setverdict(fail, "RSL Channel Identification IE is absent");
10224 mtc.stop;
10225 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010226 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10227
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010228 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10229 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010230
10231 /* Check that the lchan is working */
10232 var octetstring l3 := '00010203040506'O;
10233 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10234
10235 var BSSAP_N_CONNECT_ind rx_c_ind;
10236 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10237 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10238
10239 f_sleep(1.0);
10240 f_shutdown_helper();
10241}
10242
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010243/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10244testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10245 var MSC_ConnHdlr vc_conn;
10246
10247 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10248 f_sleep(1.0);
10249
10250 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10251 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10252 "0,0,operational,unlocked,on,rsl-up;" &
10253 "1,0,operational,unlocked,on,rsl-up;" &
10254 "2,0,operational,unlocked,on,rsl-down;" &
10255 "3,0,inoperational,locked,on,rsl-down;");
10256
10257 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10258 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10259 /* give it a moment to settle the FSM status */
10260 f_sleep(1.0);
10261
10262 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10263 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10264 * of "off"? But that's for a future patch if at all. */
10265 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10266 "0,0,operational,unlocked,on,rsl-up;" &
10267 "1,0,operational,locked,on,rsl-up;" &
10268 "2,0,operational,unlocked,on,rsl-down;" &
10269 "3,0,inoperational,locked,on,rsl-down;");
10270
10271 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10272 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10273 f_sleep(1.0);
10274 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10275 "0,0,operational,unlocked,on,rsl-up;" &
10276 "1,0,operational,locked,on,rsl-up;" &
10277 "2,0,operational,unlocked,on,rsl-down;" &
10278 "3,0,inoperational,locked,on,rsl-down;");
10279
10280 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10281 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10282 f_sleep(1.0);
10283 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10284 "0,0,operational,unlocked,on,rsl-up;" &
10285 "1,0,operational,unlocked,on,rsl-up;" &
10286 "2,0,operational,unlocked,on,rsl-down;" &
10287 "3,0,inoperational,locked,on,rsl-down;");
10288
10289 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10290 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10291 f_sleep(1.0);
10292 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10293 "0,0,operational,unlocked,on,rsl-up;" &
10294 "1,0,operational,unlocked,on,rsl-up;" &
10295 "2,0,operational,unlocked,on,rsl-down;" &
10296 "3,0,inoperational,locked,on,rsl-down;");
10297
10298 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10299 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10300 f_sleep(1.0);
10301 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10302 "0,0,operational,unlocked,on,rsl-up;" &
10303 "1,0,operational,unlocked,on,rsl-up;" &
10304 "2,0,operational,unlocked,on,rsl-down;" &
10305 "3,0,inoperational,locked,on,rsl-down;");
10306
10307 f_shutdown_helper();
10308}
10309
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010310/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10311 * Activ Ack (SYS#5627). */
10312private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10313 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10314 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10315 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10316 }
10317 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10318 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10319
10320 var BSSMAP_FIELD_CodecType codecType;
10321 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
10322
10323 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
10324
10325 /* First establish a signalling lchan */
10326 f_create_chan_and_exp();
10327 f_rslem_dchan_queue_enable();
10328
10329 /* we should now have a COMPL_L3 at the MSC */
10330 var template PDU_BSSAP exp_l3_compl;
10331 exp_l3_compl := tr_BSSMAP_ComplL3()
10332 if (g_pars.aoip == false) {
10333 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
10334 } else {
10335 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
10336 }
10337 timer T := 10.0;
10338 T.start;
10339 alt {
10340 [] BSSAP.receive(exp_l3_compl);
10341 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
10342 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
10343 }
10344 [] T.timeout {
10345 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
10346 }
10347 }
10348
10349 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
10350 activate(as_Media_mgw());
10351
10352 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
10353 f_rslem_register(0, chan_nr);
10354
10355 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
10356 BSSAP.send(ass_cmd);
10357
10358
10359 /* Wait for the Channel Activ for the TCH channel */
10360 var ASP_RSL_Unitdata rx_rsl_ud;
10361 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
10362
10363 /* make the original SDCCH disappear */
10364 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
10365
10366 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
10367 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
10368
10369 interleave {
10370 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
10371 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
10372 }
10373
10374 BSSAP.send(ts_BSSMAP_ClearCommand(0));
10375 BSSAP.receive(tr_BSSMAP_ClearComplete);
10376 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10377
10378 var MgcpCommand mgcp;
10379 MGCP.receive(tr_DLCX()) -> value mgcp {
10380 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
10381 };
10382
10383 f_sleep(0.5);
10384}
10385testcase TC_lost_sdcch_during_assignment() runs on test_CT {
10386 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10387 var MSC_ConnHdlr vc_conn;
10388
10389 f_init(1, true);
10390 f_sleep(1.0);
10391
10392 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10393 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
10394 vc_conn.done;
10395
10396 f_shutdown_helper();
10397}
10398
Harald Welte28d943e2017-11-25 15:00:50 +010010399control {
Harald Welte898113b2018-01-31 18:32:21 +010010400 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010401 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010402 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020010403 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
10404 * these in the AoIP test suite. */
10405 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10406 execute( TC_stat_num_msc_connected_1() );
10407 execute( TC_stat_num_msc_connected_2() );
10408 execute( TC_stat_num_msc_connected_3() );
10409 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020010410 execute( TC_stat_num_bts_connected_1() );
10411 execute( TC_stat_num_bts_connected_2() );
10412 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010413 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010414 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010415 execute( TC_ctrl_location() );
10416 }
Harald Welte898113b2018-01-31 18:32:21 +010010417
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010418 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010419 execute( TC_si2quater_2_earfcns() );
10420 execute( TC_si2quater_3_earfcns() );
10421 execute( TC_si2quater_4_earfcns() );
10422 execute( TC_si2quater_5_earfcns() );
10423 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010424 execute( TC_si2quater_12_earfcns() );
10425 execute( TC_si2quater_23_earfcns() );
10426 execute( TC_si2quater_32_earfcns() );
10427 execute( TC_si2quater_33_earfcns() );
10428 execute( TC_si2quater_42_earfcns() );
10429 execute( TC_si2quater_48_earfcns() );
10430 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010431 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010432 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010433
Harald Welte898113b2018-01-31 18:32:21 +010010434 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010435 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010436 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010437 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010438 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010439 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010440 execute( TC_chan_act_ack_est_ind_noreply() );
10441 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010442 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010443 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010444 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010445 execute( TC_chan_rel_rll_rel_ind() );
10446 execute( TC_chan_rel_conn_fail() );
10447 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010448 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10449 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010450 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010451 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010452 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010453 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010454 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010455 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010456
Harald Weltecfe2c962017-12-15 12:09:32 +010010457 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010458
10459 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010460 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010461 execute( TC_assignment_csd() );
10462 execute( TC_assignment_ctm() );
10463 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010464 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10465 execute( TC_assignment_aoip_tla_v6() );
10466 }
Harald Welte235ebf12017-12-15 14:18:16 +010010467 execute( TC_assignment_fr_a5_0() );
10468 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010469 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010470 execute( TC_assignment_fr_a5_1_codec_missing() );
10471 }
Harald Welte235ebf12017-12-15 14:18:16 +010010472 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010473 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010474 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010475 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010476 execute( TC_ciph_mode_a5_0() );
10477 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010478 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010479 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010480 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010481 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010482
Harald Welte60aa5762018-03-21 19:33:13 +010010483 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010484 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010485 execute( TC_assignment_codec_hr() );
10486 execute( TC_assignment_codec_efr() );
10487 execute( TC_assignment_codec_amr_f() );
10488 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010489
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010490 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010491 execute( TC_assignment_codec_amr_f_S1() );
10492 execute( TC_assignment_codec_amr_h_S1() );
10493 execute( TC_assignment_codec_amr_f_S124() );
10494 execute( TC_assignment_codec_amr_h_S124() );
10495 execute( TC_assignment_codec_amr_f_S0() );
10496 execute( TC_assignment_codec_amr_f_S02() );
10497 execute( TC_assignment_codec_amr_f_S024() );
10498 execute( TC_assignment_codec_amr_f_S0247() );
10499 execute( TC_assignment_codec_amr_h_S0() );
10500 execute( TC_assignment_codec_amr_h_S02() );
10501 execute( TC_assignment_codec_amr_h_S024() );
10502 execute( TC_assignment_codec_amr_h_S0247() );
10503 execute( TC_assignment_codec_amr_f_S01234567() );
10504 execute( TC_assignment_codec_amr_f_S0234567() );
10505 execute( TC_assignment_codec_amr_f_zero() );
10506 execute( TC_assignment_codec_amr_f_unsupp() );
10507 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010508 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10509 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010510 execute( TC_assignment_codec_amr_f_start_mode_4() );
10511 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010512 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010513 }
Harald Welte60aa5762018-03-21 19:33:13 +010010514
Philipp Maierac09bfc2019-01-08 13:41:39 +010010515 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10516 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10517 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10518 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10519 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10520 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10521 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10522 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10523 execute( TC_assignment_codec_req_hr_fr() );
10524 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010525 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10526 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10527 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010528
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010529 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010530
Harald Welte898113b2018-01-31 18:32:21 +010010531 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010532 execute( TC_rll_est_ind_inact_lchan() );
10533 execute( TC_rll_est_ind_inval_sapi1() );
10534 execute( TC_rll_est_ind_inval_sapi3() );
10535 execute( TC_rll_est_ind_inval_sacch() );
10536
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010537 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10538 execute( TC_tch_dlci_link_id_sapi() );
10539
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010540 /* SAPI N Reject triggered by RLL establishment failures */
10541 execute( TC_rll_rel_ind_sapi_n_reject() );
10542 execute( TC_rll_err_ind_sapi_n_reject() );
10543 execute( TC_rll_timeout_sapi_n_reject() );
10544
Harald Welte898113b2018-01-31 18:32:21 +010010545 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010546 execute( TC_paging_imsi_nochan() );
10547 execute( TC_paging_tmsi_nochan() );
10548 execute( TC_paging_tmsi_any() );
10549 execute( TC_paging_tmsi_sdcch() );
10550 execute( TC_paging_tmsi_tch_f() );
10551 execute( TC_paging_tmsi_tch_hf() );
10552 execute( TC_paging_imsi_nochan_cgi() );
10553 execute( TC_paging_imsi_nochan_lac_ci() );
10554 execute( TC_paging_imsi_nochan_ci() );
10555 execute( TC_paging_imsi_nochan_lai() );
10556 execute( TC_paging_imsi_nochan_lac() );
10557 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010558 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10559 execute( TC_paging_imsi_nochan_rnc() );
10560 execute( TC_paging_imsi_nochan_lac_rnc() );
10561 execute( TC_paging_imsi_nochan_lacs() );
10562 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010563 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010564 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010565 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010566 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010567 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010568
10569 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010570 execute( TC_rsl_unknown_unit_id() );
10571
10572 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010573
10574 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010575 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010576 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010577 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010578 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010579 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010580 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010581
Harald Welte261af4b2018-02-12 21:20:39 +010010582 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010583 execute( TC_ho_int_a5_0() );
10584 execute( TC_ho_int_a5_1() );
10585 execute( TC_ho_int_a5_3() );
10586 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010587 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010588
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010589 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010590 execute( TC_ho_out_fail_no_msc_response() );
10591 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010592 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010593
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010594 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010595 execute( TC_ho_into_this_bsc_a5_0() );
10596 execute( TC_ho_into_this_bsc_a5_1() );
10597 execute( TC_ho_into_this_bsc_a5_3() );
10598 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010599 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10600 execute( TC_ho_into_this_bsc_tla_v6() );
10601 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010602 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010603 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010604 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10605 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010606 execute( TC_ho_in_fail_msc_clears() );
10607 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10608 execute( TC_ho_in_fail_no_detect() );
10609 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010610
Neels Hofmeyr91401012019-07-11 00:42:35 +020010611 execute( TC_ho_neighbor_config_1() );
10612 execute( TC_ho_neighbor_config_2() );
10613 execute( TC_ho_neighbor_config_3() );
10614 execute( TC_ho_neighbor_config_4() );
10615 execute( TC_ho_neighbor_config_5() );
10616 execute( TC_ho_neighbor_config_6() );
10617 execute( TC_ho_neighbor_config_7() );
10618
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010619 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010620 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010621 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010622
10623 execute( TC_dyn_pdch_ipa_act_deact() );
10624 execute( TC_dyn_pdch_ipa_act_nack() );
10625 execute( TC_dyn_pdch_osmo_act_deact() );
10626 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010627 if (mp_enable_dyn_sdcch8_test) {
10628 execute( TC_dyn_ts_sdcch8_act_deact() );
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +020010629 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
Vadim Yanitskiy07e4b632021-10-12 14:04:45 +030010630 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010631 execute( TC_dyn_ts_sdcch8_act_nack() );
10632 }
Harald Welte99f3ca02018-06-14 13:40:29 +020010633
Stefan Sperling0796a822018-10-05 13:01:39 +020010634 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010635 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010636
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010637 /* Power control related */
10638 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010639 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010640
10641 /* MSC pooling */
10642 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10643 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10644 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10645 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10646 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10647 execute( TC_mscpool_L3Compl_on_1_msc() );
10648 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10649 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10650 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10651 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10652 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10653 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10654 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10655 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10656 execute( TC_mscpool_paging_and_response_imsi() );
10657 execute( TC_mscpool_paging_and_response_tmsi() );
10658 execute( TC_mscpool_no_allow_attach_round_robin() );
10659 execute( TC_mscpool_no_allow_attach_valid_nri() );
10660 }
10661
Harald Welte99f3ca02018-06-14 13:40:29 +020010662 execute( TC_early_conn_fail() );
10663 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010664 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010665
Philipp Maier783681c2020-07-16 16:47:06 +020010666 /* Emergency call handling (deny / allow) */
10667 execute( TC_assignment_emerg_setup_allow() );
10668 execute( TC_assignment_emerg_setup_deny_msc() );
10669 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010670 execute( TC_emerg_premption() );
10671
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010672 /* Frequency hopping parameters handling */
10673 execute( TC_fh_params_chan_activ() );
10674 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010675 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010676 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010677 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010678
10679 if (mp_enable_lcs_tests) {
10680 execute( TC_lcs_loc_req_for_active_ms() );
10681 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10682 execute( TC_lcs_loc_req_for_idle_ms() );
10683 execute( TC_lcs_loc_req_no_subscriber() );
10684 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10685 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10686 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10687 execute( TC_cm_service_during_lcs_loc_req() );
10688 execute( TC_ho_during_lcs_loc_req() );
10689 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010690
10691 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010692
10693 execute( TC_refuse_chan_act_to_vamos() );
10694 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010695
10696 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010697
10698 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010699
10700 execute( TC_imm_ass_post_chan_ack() );
10701 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010702 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010703 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010704 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010705
10706 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010707
10708 execute( TC_lost_sdcch_during_assignment() );
Harald Welte28d943e2017-11-25 15:00:50 +010010709}
10710
10711}