blob: 6040a967561106526538354f43ede6f108a6e29b [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
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001403 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001404 * 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
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001645type record of DchanTuple DchanTuples;
1646
Harald Welted6939652017-12-13 21:02:46 +01001647/* Send CHAN RQD and wait for allocation; acknowledge it */
1648private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1649runs on test_CT return RslChannelNr {
1650 var RSL_Message rx_rsl;
1651 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1652 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1653 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1654 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001655 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001656 return chan_nr;
1657}
1658
Harald Welte4003d112017-12-09 22:35:39 +01001659/* helper function to establish a dedicated channel via BTS and MSC */
1660function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1661runs on test_CT return DchanTuple {
1662 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001663 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001664
Harald Welte4003d112017-12-09 22:35:39 +01001665 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001666 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001667
1668 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1669
1670 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1671 dt.sccp_conn_id := rx_c_ind.connectionId;
1672 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1673
1674 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001675}
1676
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001677/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1678function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1679runs on test_CT return DchanTuple {
1680 var BSSAP_N_CONNECT_ind rx_c_ind;
1681 var DchanTuple dt;
1682
1683 /* Send CHAN RQD */
1684 var RSL_Message rx_rsl;
1685 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1686
1687 /* The dyn TS first deactivates PDCH */
1688 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1689 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1690 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1691
1692 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1693 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1694
1695 /* Now activates the signalling channel */
1696 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1697 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1698
1699 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1700
1701 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1702 dt.sccp_conn_id := rx_c_ind.connectionId;
1703 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1704
1705 return dt;
1706}
1707
Harald Welte641fcbe2018-06-14 10:58:35 +02001708/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1709private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1710 var RSL_Message rx_rsl;
1711 /* expect BSC to disable the channel */
1712 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1713 /* respond with CHAN REL ACK */
1714 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1715
1716 /* expect Clear Complete from BSC */
1717 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1718
1719 /* MSC disconnects as instructed. */
1720 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1721}
1722
Harald Welte4003d112017-12-09 22:35:39 +01001723/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1724testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001725 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001726 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001727
Harald Welte89d42e82017-12-17 16:42:41 +01001728 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001729
Harald Welte4003d112017-12-09 22:35:39 +01001730 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1731
1732 /* simulate RLL REL IND */
1733 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1734
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001735 /* expect Clear Request on MSC side */
1736 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1737
1738 /* Instruct BSC to clear channel */
1739 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1740 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1741
Harald Welte4003d112017-12-09 22:35:39 +01001742 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001743 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001744
1745 /* wait for SCCP emulation to do its job */
1746 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001747
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001748 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001749}
1750
1751/* Test behavior of channel release after CONN FAIL IND from BTS */
1752testcase TC_chan_rel_conn_fail() runs on test_CT {
1753 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001754 var DchanTuple dt;
1755
Harald Welte89d42e82017-12-17 16:42:41 +01001756 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001757
1758 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1759
1760 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001761 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 +01001762 /* TODO: different cause values? */
1763
Harald Welte4003d112017-12-09 22:35:39 +01001764 /* expect Clear Request from BSC */
1765 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1766
1767 /* Instruct BSC to clear channel */
1768 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1769 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1770
Harald Welte6ff76ea2018-01-28 13:08:01 +01001771 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001772 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001773
1774 /* wait for SCCP emulation to do its job */
1775 f_sleep(1.0);
1776
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001777 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001778}
1779
Harald Welte99f3ca02018-06-14 13:40:29 +02001780/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1781/* See also https://www.osmocom.org/issues/3182 */
1782testcase TC_early_conn_fail() runs on test_CT {
1783 var RSL_Message rx_rsl;
1784 var DchanTuple dt;
1785
1786 f_init(1);
1787
1788 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001789 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001790
1791 /* BTS->BSC: simulate CONN FAIL IND */
1792 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1793
1794 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1795 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1796
1797 /* BTS<-BSC: respond with CHAN REL ACK */
1798 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1799
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001800 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001801}
1802
1803/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1804/* See also https://www.osmocom.org/issues/3182 */
1805testcase TC_late_conn_fail() runs on test_CT {
1806 var RSL_Message rx_rsl;
1807 var DchanTuple dt;
1808
1809 f_init(1);
1810
1811 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1812
1813 /* BSC<-MSC: Instruct BSC to clear connection */
1814 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1815
1816 /* BTS->BSC: expect BSC to deactivate SACCH */
1817 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1818
1819 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1820 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1821
1822 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1823 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1824 /* BTS->BSC: respond with CHAN REL ACK */
1825 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1826
1827 /* BSC->MSC: expect Clear Complete from BSC */
1828 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1829
1830 /* BSC<-MSC: MSC disconnects as requested. */
1831 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1832
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001833 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001834}
1835
Oliver Smithaf03bef2021-08-24 15:34:51 +02001836private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1837 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1838 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1839
1840 f_statsd_reset();
1841
1842 /* Establish SDCCH */
1843 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1844 f_establish_fully(ass_cmd, exp_fail);
1845
1846 /* Expect stats to be 0 */
1847 var StatsDExpects expect := {
1848 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1849 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1850 };
1851 f_statsd_expect(expect);
1852
1853 /* Simulate CONN FAIL IND on SDCCH */
1854 RSL.send(ts_ASP_RSL_UD(
1855 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1856 IPAC_PROTO_RSL_TRX0));
1857
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001858 f_sleep(1.0);
1859
Oliver Smithaf03bef2021-08-24 15:34:51 +02001860 /* Expect stats to be 1 */
1861 expect := {
1862 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1863 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1864 };
1865 f_statsd_expect(expect);
1866}
1867testcase TC_stats_conn_fail() runs on test_CT {
1868 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1869 var MSC_ConnHdlr vc_conn;
1870
1871 f_init(1, true);
1872 f_sleep(1.0);
1873
1874 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1875 vc_conn.done;
1876
1877 f_shutdown_helper();
1878}
1879
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001880function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001881 boolean expect_deact_sacch := true,
1882 boolean expect_rr_chan_rel := true,
1883 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001884 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001885 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001886 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001887 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001888
1889 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001890 var boolean got_deact_sacch := false;
1891 var boolean got_rr_chan_rel := false;
1892 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001893 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001894 var RSL_IE_Body l3_ie;
1895 var PDU_ML3_NW_MS l3;
1896 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001897 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1898 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001899 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001900 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001901 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001902 repeat;
1903 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001904 [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 +01001905 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001906
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001907 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1908 setverdict(fail, "cannot find L3");
1909 mtc.stop;
1910 }
1911 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1912
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001913 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001914 var CellSelIndValue cells := dec_CellSelIndValue(
1915 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1916
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001917 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1918 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001919 setverdict(pass);
1920 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001921 log("EXPECTED CELLS: ", expect_cells);
1922 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001923 }
1924 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001925
1926 if (not istemplatekind(expect_rr_cause, "omit")) {
1927 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1928 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1929 if (match(got_cause, expect_rr_cause)) {
1930 setverdict(pass);
1931 } else {
1932 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1933 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1934 }
1935 }
Harald Welte99787102019-02-04 10:41:36 +01001936 repeat;
1937 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001938 [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 +01001939 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001940
1941 if (not istemplatekind(expect_rr_cause, "omit")) {
1942 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1943 setverdict(fail, "cannot find L3");
1944 mtc.stop;
1945 }
1946 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1947
1948 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1949 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1950 if (match(got_cause, expect_rr_cause)) {
1951 setverdict(pass);
1952 } else {
1953 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1954 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1955 }
1956 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001957 repeat;
1958 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001959 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001960 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001961 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001962 if (handle_rll_rel) {
1963 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1964 }
Harald Welte91d54a52018-01-28 15:35:07 +01001965 repeat;
1966 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001967 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001968 /* respond with CHAN REL ACK */
1969 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1970 }
1971 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001972 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001973 repeat;
1974 }
1975 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001976
1977 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
1978 " got_rll_rel_req=", got_rll_rel_req);
1979
1980 if (expect_deact_sacch != got_deact_sacch) {
1981 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
1982 }
1983 if (expect_rr_chan_rel != got_rr_chan_rel) {
1984 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
1985 }
1986 if (expect_rll_rel_req != got_rll_rel_req) {
1987 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
1988 }
Harald Welte91d54a52018-01-28 15:35:07 +01001989}
1990
Harald Welte4003d112017-12-09 22:35:39 +01001991/* Test behavior of channel release after hard Clear Command from MSC */
1992testcase TC_chan_rel_hard_clear() runs on test_CT {
1993 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001994 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01001995
Harald Welte89d42e82017-12-17 16:42:41 +01001996 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001997
1998 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1999
2000 /* Instruct BSC to clear channel */
2001 var BssmapCause cause := 0;
2002 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2003
2004 /* expect Clear Complete from BSC on A */
2005 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2006 /* release the SCCP connection */
2007 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2008 }
2009
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002010 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002011 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002012}
2013
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002014function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2015 var BSSAP_N_DATA_ind rx_di;
2016 var DchanTuple dt;
2017
2018 f_init(1);
2019
2020 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2021 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2022 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2023 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2024
2025 /* Instruct BSC to clear channel */
2026 var BssmapCause cause := 0;
2027 if (tx_csfb_ind) {
2028 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2029 } else {
2030 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2031 }
2032
2033 /* expect Clear Complete from BSC on A */
2034 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2035 /* release the SCCP connection */
2036 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2037 }
2038
2039 /* 1 neighbor is added by default in osmo-bts.cfg and
2040 SystemInformationConfig_default, use that: */
2041 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2042
2043 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2044 f_shutdown_helper();
2045}
2046
2047/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2048 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2049 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2050 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2051 Indicator or not shouldn't matter at all. */
2052testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2053 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2054}
2055
2056/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2057 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2058 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2059 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2060testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2061 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2062}
2063
2064/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2065 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2066 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2067 CSFB Indicator should not be used anymore, and hence, there should be no
2068 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2069 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002070testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2071 var BSSAP_N_DATA_ind rx_di;
2072 var DchanTuple dt;
2073
2074 f_init(1);
2075
2076 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2077
2078 /* Instruct BSC to clear channel */
2079 var BssmapCause cause := 0;
2080 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2081
2082 /* expect Clear Complete from BSC on A */
2083 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2084 /* release the SCCP connection */
2085 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2086 }
2087
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002088 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002089 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002090}
2091
Harald Welted8c36cd2017-12-09 23:05:31 +01002092/* Test behavior of channel release after hard RLSD from MSC */
2093testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002094 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002095
Harald Welte89d42e82017-12-17 16:42:41 +01002096 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002097
2098 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2099
2100 /* release the SCCP connection */
2101 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2102
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002103 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002104 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002105}
2106
Harald Welte550daf92018-06-11 19:22:13 +02002107/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2108testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2109 var DchanTuple dt;
2110
2111 f_init(1);
2112
2113 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2114
2115 /* release the SCCP connection */
2116 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2117
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002118 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002119 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002120}
2121
Harald Welte85804d42017-12-10 14:11:58 +01002122/* Test behavior of channel release after BSSMAP RESET from MSC */
2123testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002124 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002125
Harald Welte89d42e82017-12-17 16:42:41 +01002126 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002127
2128 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2129
2130 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2131 IPA_RSL[0].clear;
2132
2133 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002134 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 +01002135 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002136 [] 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 +01002137 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2138 }
2139
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002140 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002141 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002142}
2143
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002144/* Verify T(iar) triggers and releases the channel */
2145testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2146 var DchanTuple dt;
2147
2148 /* Set T(iar) in BSC low enough that it will trigger before other side
2149 has time to keep alive with a T(ias). Keep recommended ratio of
2150 T(iar) >= T(ias)*2 */
2151 g_bsc_sccp_timer_ias := 2;
2152 g_bsc_sccp_timer_iar := 5;
2153
2154 f_init(1);
2155
2156 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2157 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002158 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002159}
2160
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002161private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2162runs on test_CT
2163{
2164 var DchanTuple dt;
2165
2166 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2167 var BssmapCause cause := 0;
2168 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2169 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2170 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2171 }
2172
2173 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 +02002174}
2175
2176/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2177testcase TC_chan_rel_rr_cause() runs on test_CT {
2178 f_init(1);
2179
2180 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2181 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2182 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2183 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2184 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2185 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002186
2187 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002188}
2189
Harald Welte5cd20ed2017-12-13 21:03:20 +01002190/* Test behavior if RSL EST IND for non-active channel */
2191testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2192 timer T := 2.0;
2193
Harald Welte89d42e82017-12-17 16:42:41 +01002194 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002195
2196 var octetstring l3 := '00010203040506'O;
2197 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2198 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2199
2200 T.start;
2201 alt {
2202 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2203 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2204 }
2205 [] BSSAP.receive {}
2206 [] IPA_RSL[0].receive {}
2207 [] T.timeout {}
2208 }
2209
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002210 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002211}
2212
2213/* Test behavior if RSL EST IND for invalid SAPI */
2214testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2215 var RslChannelNr chan_nr;
2216
Harald Welte89d42e82017-12-17 16:42:41 +01002217 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002218
2219 chan_nr := f_chreq_act_ack()
2220
2221 var octetstring l3 := '00010203040506'O;
2222 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2223
2224 timer T := 2.0;
2225 T.start;
2226 alt {
2227 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2228 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2229 }
2230 [] BSSAP.receive { repeat; }
2231 [] IPA_RSL[0].receive { repeat; }
2232 [] T.timeout {}
2233 }
2234
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002235 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002236}
2237
2238/* Test behavior if RSL EST IND for invalid SAPI */
2239testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2240 timer T := 2.0;
2241
Harald Welte89d42e82017-12-17 16:42:41 +01002242 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002243
2244 var RslChannelNr chan_nr := f_chreq_act_ack();
2245
2246 var octetstring l3 := '00010203040506'O;
2247 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2248
2249 T.start;
2250 alt {
2251 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2252 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2253 }
2254 [] BSSAP.receive { repeat; }
2255 [] IPA_RSL[0].receive { repeat; }
2256 [] T.timeout {}
2257 }
2258
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002259 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002260}
2261
2262/* Test behavior if RSL EST IND for invalid SACCH */
2263testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2264 timer T := 2.0;
2265
Harald Welte89d42e82017-12-17 16:42:41 +01002266 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002267
2268 var RslChannelNr chan_nr := f_chreq_act_ack();
2269
2270 var octetstring l3 := '00010203040506'O;
2271 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2272
2273 T.start;
2274 alt {
2275 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2276 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2277 }
2278 [] BSSAP.receive { repeat; }
2279 [] IPA_RSL[0].receive { repeat; }
2280 [] T.timeout {}
2281 }
2282
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002283 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002284}
2285
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002286/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2287private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2288 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2289 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2290
2291 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2292 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2293
2294 f_establish_fully(ass_cmd, exp_compl);
2295
2296 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2297 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2298 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2299 BSSAP.receive(PDU_BSSAP:{
2300 discriminator := '1'B,
2301 spare := '0000000'B,
2302 dlci := 'C3'O,
2303 lengthIndicator := ?,
2304 pdu := { dtap := '0904'O }
2305 });
2306
2307 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2308 for (var integer i := 0; i < 32; i := i + 1) {
2309 var octetstring l3 := '09'O & f_rnd_octstring(14);
2310 var template (value) RslLinkId link_id;
2311 var template (value) OCT1 dlci;
2312
2313 if (i mod 2 == 0) {
2314 /* SAPI0 on FACCH or SDCCH */
2315 link_id := ts_RslLinkID_DCCH(0);
2316 dlci := '80'O;
2317 } else {
2318 /* SAPI3 on SACCH */
2319 link_id := ts_RslLinkID_SACCH(3);
2320 dlci := 'C3'O;
2321 }
2322
2323 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002324 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002325 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002326 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002327 }
2328}
2329testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2330 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2331 var MSC_ConnHdlr vc_conn;
2332
2333 f_init(1, true);
2334 f_sleep(1.0);
2335
2336 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2337 vc_conn.done;
2338
2339 f_shutdown_helper();
2340}
2341
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002342private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2343 template myBSSMAP_Cause cause := ?,
2344 float T_val := 2.0)
2345runs on test_CT {
2346 var BSSAP_N_DATA_ind rx_di;
2347 timer T;
2348
2349 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2350 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2351
2352 T.start(T_val);
2353 alt {
2354 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2355 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2356 if (not match(rx_cause, tr_cause)) {
2357 setverdict(fail, "Rx unexpected Cause IE: ",
2358 rx_cause, " vs expected ", tr_cause);
2359 }
2360 setverdict(pass);
2361 }
2362 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2363 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2364 }
2365 [] T.timeout {
2366 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2367 }
2368 }
2369}
2370
2371/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2372testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2373 var octetstring rnd_data := f_rnd_octstring(16);
2374 var RSL_Message rx_rsl;
2375 var DchanTuple dt;
2376
2377 f_init(1);
2378
2379 /* MS establishes a SAPI=0 link on DCCH */
2380 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2381
2382 /* MSC sends some data on (not yet established) SAPI=3 link */
2383 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2384 /* BSC attempts to establish a SAPI=3 link on DCCH */
2385 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2386
2387 /* MS sends unexpected RELease INDication on SAPI=3 */
2388 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2389 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2390 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2391
2392 /* Clean up the connection */
2393 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2394 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2395
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002396 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002397}
2398
2399/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2400testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2401 var octetstring rnd_data := f_rnd_octstring(16);
2402 var RSL_Message rx_rsl;
2403 var DchanTuple dt;
2404
2405 f_init(1);
2406
2407 /* MS establishes a SAPI=0 link on DCCH */
2408 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2409
2410 /* MSC sends some data on (not yet established) SAPI=3 link */
2411 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2412 /* BSC attempts to establish a SAPI=3 link on DCCH */
2413 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2414
2415 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2416 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2417 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2418 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2419
2420 /* Clean up the connection */
2421 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2422 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2423
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002424 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002425}
2426
2427/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2428testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2429 var octetstring rnd_data := f_rnd_octstring(16);
2430 var RSL_Message rx_rsl;
2431 var DchanTuple dt;
2432
2433 f_init(1);
2434
2435 /* MS establishes a SAPI=0 link on DCCH */
2436 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2437
2438 /* MSC sends some data on (not yet established) SAPI=3 link */
2439 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2440 /* BSC attempts to establish a SAPI=3 link on DCCH */
2441 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2442
2443 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2444 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2445
2446 /* Clean up the connection */
2447 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2448 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2449
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002450 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002451}
2452
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002453testcase TC_si_default() runs on test_CT {
2454 f_init(0);
2455 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002456 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002457}
Harald Welte4003d112017-12-09 22:35:39 +01002458
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002459/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2460 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2461private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2462{
2463 select (earfcn_index) {
2464 case (0) {
2465 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2466 return 111;
2467 }
2468 case (1) {
2469 return 1;
2470 }
2471 case (2) {
2472 return 0;
2473 }
2474 case (3) {
2475 return 65535;
2476 }
2477 case else {
2478 return 23 * (earfcn_index - 3);
2479 }
2480 }
2481}
2482
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002483function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2484 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002485
2486 f_init(0);
2487
2488 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2489 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002490 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2491 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002492 }
2493
2494 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2495
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002496 if (not istemplatekind(expect_cells, "omit")) {
2497 /* Also check that RR Channel Release contains these EARFCNs.
2498 * (copied code from TC_chan_rel_hard_clear_csfb) */
2499 var BSSAP_N_DATA_ind rx_di;
2500 var DchanTuple dt;
2501
2502 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002503 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2504 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2505 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002506
2507 /* Instruct BSC to clear channel */
2508 var BssmapCause cause := 0;
2509 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2510
2511 /* expect Clear Complete from BSC on A */
2512 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2513 /* release the SCCP connection */
2514 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2515 }
2516
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002517 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 +02002518 }
2519
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002520 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002521 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 +02002522 }
2523}
2524
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002525private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2526{
2527 var template SI2quaterRestOctetsList si2quater := {};
2528 var integer si2quater_count := (count + 2) / 3;
2529
2530 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002531 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002532 var integer index := i / 3;
2533 var integer earfcn_index := i mod 3;
2534 if (index >= lengthof(si2quater)) {
2535 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2536 }
2537 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);
2538 }
2539
2540 return si2quater;
2541}
2542
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002543private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2544{
2545 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2546
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002547 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002548 for (var integer i := 0; i < count; i := i + 1) {
2549 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002550 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002551 }
2552
2553 return tr_CellSelIndValue_EUTRAN(cells);
2554}
2555
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002556private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2557{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002558 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002559 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002560 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2561 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002562}
2563
2564testcase TC_si2quater_2_earfcns() runs on test_CT {
2565 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002566 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002567}
2568
2569testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002570 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002571 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002572}
2573
2574testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002575 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002576 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002577}
2578
2579testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002580 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002581 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002582}
2583
2584testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002585 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002586 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002587}
2588
2589testcase TC_si2quater_12_earfcns() runs on test_CT {
2590 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002591 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002592}
2593
2594testcase TC_si2quater_23_earfcns() runs on test_CT {
2595 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002596 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002597}
2598
2599testcase TC_si2quater_32_earfcns() runs on test_CT {
2600 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002601 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002602}
2603
2604testcase TC_si2quater_33_earfcns() runs on test_CT {
2605 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002606 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002607}
2608
2609testcase TC_si2quater_42_earfcns() runs on test_CT {
2610 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002611 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002612}
2613
2614testcase TC_si2quater_48_earfcns() runs on test_CT {
2615 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002616 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002617}
2618
2619/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2620 * 48 EARFCNs. */
2621testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002622 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002623 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2624 f_init(0);
2625
2626 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002627 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2628 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002629 }
2630
2631 /* The 49th EARFCN no longer fits, expect VTY error */
2632 f_vty_enter_cfg_bts(BSCVTY, 0);
2633 var charstring vty_error;
2634 vty_error := f_vty_transceive_ret(BSCVTY,
2635 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2636 f_vty_transceive(BSCVTY, "end");
2637
2638 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2639 log("Got expected VTY error: ", vty_error);
2640 setverdict(pass);
2641 } else {
2642 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2643 }
2644
2645 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2646
2647 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002648 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 +02002649 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002650 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002651}
2652
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002653private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2654{
2655 var uint8_t count := 0;
2656 for (var integer i := 5; i < 16; i := i + 1) {
2657 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2658 count := count + 1;
2659 }
2660 }
2661 return count;
2662}
2663
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002664private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2665{
2666 var ASP_RSL_Unitdata rx_rsl_ud;
2667 var SystemInformationType1 last_si1;
2668
2669 timer T := 30.0;
2670 T.start;
2671 alt {
2672 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2673 tr_RSL_BCCH_INFO,
2674 tr_RSL_NO_SACCH_FILL,
2675 tr_RSL_SACCH_FILL))
2676 ) -> value rx_rsl_ud {
2677 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2678 if (g_system_information[rsl_idx].si1 == omit) {
2679 repeat;
2680 }
2681 last_si1 := g_system_information[rsl_idx].si1;
2682 g_system_information[rsl_idx].si1 := omit;
2683 T.stop;
2684 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002685 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002686 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2687 }
2688 return last_si1;
2689}
2690
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002691/* verify ACC rotate feature */
2692testcase TC_si_acc_rotate() runs on test_CT {
2693 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002694 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002695 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002696 var uint8_t count;
2697 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2698
2699 f_init(0, guard_timeout := 60.0);
2700
2701 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2702 "access-control-class-rotate 3",
2703 "access-control-class-rotate-quantum 1"});
2704
2705 /* Init and get first sysinfo */
2706 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2707
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002708 for (var integer i:= 0; i < 20; i := i + 1) {
2709 last_si1 := f_recv_next_si1(0);
2710 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002711 count := f_acc09_count_allowed(acc);
2712 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2713
2714 if (count != 3) {
2715 log("RSL: EXPECTED SI ACC len=3");
2716 setverdict(fail, "received SI does not match expectations");
2717 break;
2718 }
2719
2720 for (var integer j := 0; j < 10; j := j + 1) {
2721 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2722 times_allowed[j] := times_allowed[j] + 1;
2723 }
2724 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002725 }
2726
2727 for (var integer j := 0; j < 10; j := j + 1) {
2728 log("ACC", j, " allowed ", times_allowed[j], " times" );
2729 if (j != 5 and times_allowed[j] < 3) {
2730 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2731 } else if (j == 5 and times_allowed[j] > 0) {
2732 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2733 }
2734 }
2735
2736 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2737 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002738 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002739}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002740
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002741/* verify ACC startup ramp+rotate feature */
2742testcase TC_si_acc_ramp_rotate() runs on test_CT {
2743 var template SystemInformationConfig sic := SystemInformationConfig_default;
2744 var SystemInformationType1 last_si1;
2745 var AccessControlClass acc;
2746 var ASP_RSL_Unitdata rx_rsl_ud;
2747 var uint8_t count;
2748 var uint8_t prev_count;
2749 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2750
2751 f_init(0, guard_timeout := 80.0);
2752
2753 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2754 "access-control-class-rotate 0",
2755 "access-control-class-rotate-quantum 1",
2756 "access-control-class-ramping",
2757 "access-control-class-ramping-step-interval 5",
2758 "access-control-class-ramping-step-size 5"});
2759
2760 /* Init and get first sysinfo */
2761 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2762 last_si1 := g_system_information[0].si1;
2763 acc := last_si1.rach_control.acc;
2764 count := f_acc09_count_allowed(acc);
2765 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2766 while (count > 0) {
2767 last_si1 := f_recv_next_si1(0);
2768 acc := last_si1.rach_control.acc;
2769 count := f_acc09_count_allowed(acc);
2770 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2771 }
2772
2773 /* Increase adm subset size, we should see ramping start up */
2774 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2775 prev_count := 0;
2776 while (true) {
2777 last_si1 := f_recv_next_si1(0);
2778 acc := last_si1.rach_control.acc;
2779 count := f_acc09_count_allowed(acc);
2780 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2781
2782 if (prev_count > count) {
2783 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2784 break;
2785 }
2786
2787 if (count == 9) {
2788 break; /* Maximum reached (10 - 1 perm barred), done here */
2789 }
2790
2791 prev_count := count;
2792 }
2793
2794 setverdict(pass);
2795
2796 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2797 "rach access-control-class 4 allowed",
2798 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002799 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002800}
2801
Harald Welte4003d112017-12-09 22:35:39 +01002802testcase TC_ctrl_msc_connection_status() runs on test_CT {
2803 var charstring ctrl_resp;
2804
Harald Welte89d42e82017-12-17 16:42:41 +01002805 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002806
2807 /* See https://osmocom.org/issues/2729 */
2808 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002809 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002810}
2811
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002812testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2813 var charstring ctrl_resp;
2814
2815 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002816
2817 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002818 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002819}
2820
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002821/* Verify correct stats on the number of configured and connected MSCs */
2822private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2823 g_pars := f_gen_test_hdlr_pars();
2824 var StatsDExpects expect := {
2825 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2826 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2827 };
2828 f_statsd_expect(expect);
2829}
2830
2831private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2832{
2833 var MSC_ConnHdlr vc_conn;
2834
2835 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2836 f_sleep(1.0);
2837 vc_conn := f_start_handler(tc_fn);
2838 vc_conn.done;
2839
2840 /* Also verify stat exposed on CTRL interface */
2841 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2842 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2843
2844 f_shutdown_helper();
2845}
2846
2847/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2848private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2849 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2850}
2851testcase TC_stat_num_msc_connected_1() runs on test_CT {
2852 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2853}
2854
2855/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2856private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2857 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2858}
2859testcase TC_stat_num_msc_connected_2() runs on test_CT {
2860 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2861}
2862
2863/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2864private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2865 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2866}
2867testcase TC_stat_num_msc_connected_3() runs on test_CT {
2868 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2869}
2870
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002871/* Verify correct stats on the number of configured and connected MSCs */
2872private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
2873 g_pars := f_gen_test_hdlr_pars();
2874 var StatsDExpects expect := {
2875 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
2876 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2877 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
2878 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2879 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
2880 };
2881 f_statsd_expect(expect);
2882}
2883
2884private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
2885 var MSC_ConnHdlr vc_conn;
2886
2887 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
2888 f_sleep(1.0);
2889 vc_conn := f_start_handler(tc_fn);
2890 vc_conn.done;
2891
2892 /* Also verify stat exposed on CTRL interface */
2893 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
2894 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
2895 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
2896 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
2897
Neels Hofmeyra41ae302021-09-06 22:06:02 +02002898 /* Verify rf_states exposed on CTRL interface */
2899 var charstring expect_net_rf_states := "";
2900 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
2901 var charstring expect_bts_rf_states := int2str(i) & ",0,";
2902 if (i < NUM_BTS) {
2903 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
2904 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
2905 } else {
2906 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
2907 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
2908 }
2909 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
2910 expect_bts_rf_states := expect_bts_rf_states & "on,";
2911 if (i < nr_bts) {
2912 /* For BTS where RSL is connected, the RSL state will be "up" */
2913 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
2914 } else {
2915 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
2916 }
2917
2918 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
2919 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
2920 }
2921 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
2922
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002923 f_shutdown_helper();
2924}
2925
2926/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
2927private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
2928 f_tc_stat_num_bts_connected_msc_connhdlr(1);
2929}
2930testcase TC_stat_num_bts_connected_1() runs on test_CT {
2931 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
2932}
2933
2934/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
2935private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
2936 f_tc_stat_num_bts_connected_msc_connhdlr(2);
2937}
2938testcase TC_stat_num_bts_connected_2() runs on test_CT {
2939 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
2940}
2941
2942/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
2943private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
2944 f_tc_stat_num_bts_connected_msc_connhdlr(3);
2945}
2946testcase TC_stat_num_bts_connected_3() runs on test_CT {
2947 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
2948}
2949
Harald Welte4003d112017-12-09 22:35:39 +01002950testcase TC_ctrl() runs on test_CT {
2951 var charstring ctrl_resp;
2952
Harald Welte89d42e82017-12-17 16:42:41 +01002953 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002954
2955 /* all below values must match the osmo-bsc.cfg config file used */
2956
Harald Welte6a129692018-03-17 17:30:14 +01002957 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2958 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002959 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002960
2961 var integer bts_nr := 0;
2962 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2963 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2964 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2965 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2966 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2967 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2968 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2969
2970 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2971 f_sleep(2.0);
2972 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2973 setverdict(fail, "oml-uptime not incrementing as expected");
2974 }
2975 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2976
2977 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2978
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002979 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002980}
2981
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002982/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2983 "location-state" over the SCCPlite IPA conn */
2984testcase TC_ctrl_location() runs on test_CT {
2985 var MSC_ConnHdlr vc_conn;
2986 var integer bts_nr := 0;
2987
2988 f_init(1, true);
2989 f_sleep(1.0);
2990
2991 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2992 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2993 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2994
2995 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2996 f_sleep(2.0);
2997
2998 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2999 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3000 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3001
3002 /* should match the one from config */
3003 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3004
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003005 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003006}
3007
Harald Welte6f521d82017-12-11 19:52:02 +01003008
3009/***********************************************************************
3010 * Paging Testing
3011 ***********************************************************************/
3012
3013type record Cell_Identity {
3014 GsmMcc mcc,
3015 GsmMnc mnc,
3016 GsmLac lac,
3017 GsmCellId ci
3018};
Harald Welte24135bd2018-03-17 19:27:53 +01003019private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003020private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003021
Harald Welte5d1a2202017-12-13 19:51:29 +01003022type set of integer BtsIdList;
3023
3024private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3025 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3026 if (bts_id == bts_ids[j]) {
3027 return true;
3028 }
3029 }
3030 return false;
3031}
Harald Welte6f521d82017-12-11 19:52:02 +01003032
3033/* core paging test helper function; used by most paging test cases */
3034private function f_pageing_helper(hexstring imsi,
3035 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003036 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003037 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003038 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003039{
3040 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003041 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003042 var RSL_Message rx_rsl;
3043 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003044 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003045
3046 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003047
3048 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003049 for (i := 0; i < NUM_BTS; i := i + 1) {
3050 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003051 }
Harald Welte6f521d82017-12-11 19:52:02 +01003052
3053 if (isvalue(rsl_chneed)) {
3054 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3055 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3056 } else {
3057 bssmap_chneed := omit;
3058 }
3059
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003060 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3061 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003062
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003063 if (not istemplatekind(tmsi, "omit")) {
3064 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003065 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003066 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003067 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003068
Harald Welte5d1a2202017-12-13 19:51:29 +01003069 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003070 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003071 /* check channel type, paging group */
3072 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3073 setverdict(fail, "Paging for wrong paging group");
3074 }
3075 if (ispresent(rsl_chneed) and
3076 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3077 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3078 }
Harald Welte6f521d82017-12-11 19:52:02 +01003079 }
Harald Welte2fccd982018-01-31 15:48:19 +01003080 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003081 /* do a quick check on all not-included BTSs if they received paging */
3082 for (i := 0; i < NUM_BTS; i := i + 1) {
3083 timer T := 0.1;
3084 if (f_bts_in_list(i, bts_ids)) {
3085 continue;
3086 }
3087 T.start;
3088 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003089 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003090 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3091 }
3092 [] IPA_RSL[i].receive { repeat; }
3093 [] T.timeout { }
3094 }
Harald Welte6f521d82017-12-11 19:52:02 +01003095 }
3096
3097 setverdict(pass);
3098}
3099
Harald Welte5d1a2202017-12-13 19:51:29 +01003100const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003101const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003102const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3103const BtsIdList c_BtsId_LAC2 := { 2 };
3104
Harald Welte6f521d82017-12-11 19:52:02 +01003105/* PAGING by IMSI + TMSI */
3106testcase TC_paging_imsi_nochan() runs on test_CT {
3107 var BSSMAP_FIELD_CellIdentificationList cid_list;
3108 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003109 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003110 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003111}
3112
3113/* PAGING by IMSI + TMSI */
3114testcase TC_paging_tmsi_nochan() runs on test_CT {
3115 var BSSMAP_FIELD_CellIdentificationList cid_list;
3116 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003117 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003118 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003119}
3120
3121/* Paging with different "channel needed' values */
3122testcase TC_paging_tmsi_any() runs on test_CT {
3123 var BSSMAP_FIELD_CellIdentificationList cid_list;
3124 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003125 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003126 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003127}
3128testcase TC_paging_tmsi_sdcch() runs on test_CT {
3129 var BSSMAP_FIELD_CellIdentificationList cid_list;
3130 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003131 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003132 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003133}
3134testcase TC_paging_tmsi_tch_f() runs on test_CT {
3135 var BSSMAP_FIELD_CellIdentificationList cid_list;
3136 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003137 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003138 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003139}
3140testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3141 var BSSMAP_FIELD_CellIdentificationList cid_list;
3142 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003143 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003144 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003145}
3146
3147/* Paging by CGI */
3148testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3149 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3150 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003151 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003152 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003153}
3154
3155/* Paging by LAC+CI */
3156testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3157 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3158 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003159 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003160 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003161}
3162
3163/* Paging by CI */
3164testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3165 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3166 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003167 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003168 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003169}
3170
3171/* Paging by LAI */
3172testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3173 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3174 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003175 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003176 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003177}
3178
3179/* Paging by LAC */
3180testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3181 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3182 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003183 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003184 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003185}
3186
3187/* Paging by "all in BSS" */
3188testcase TC_paging_imsi_nochan_all() runs on test_CT {
3189 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3190 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003191 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003192 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003193}
3194
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003195/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003196testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3197 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3198 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 +01003199 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003200 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003201}
Harald Welte6f521d82017-12-11 19:52:02 +01003202
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003203/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003204testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3205 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3206 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003207 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003208 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003209}
3210
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003211/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003212testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3213 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3214 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003215 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003216 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003217}
3218
Harald Welte6f521d82017-12-11 19:52:02 +01003219/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003220testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3221 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3222 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3223 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003224 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003225}
3226
3227/* Paging on empty list: Verify none of them page */
3228testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3229 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3230 cid_list := { cIl_LAC := { } };
3231 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003232 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003233}
3234
Stefan Sperling049a86e2018-03-20 15:51:00 +01003235/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3236testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3237 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3238 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3239 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3240 f_shutdown_helper();
3241}
3242
Harald Welte6f521d82017-12-11 19:52:02 +01003243/* Verify paging retransmission interval + count */
3244/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003245/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003246
Harald Weltee65d40e2017-12-13 00:09:06 +01003247/* Verify PCH load */
3248testcase TC_paging_imsi_load() runs on test_CT {
3249 var BSSMAP_FIELD_CellIdentificationList cid_list;
3250 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003251 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003252 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003253 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003254
3255 /* tell BSC there is no paging space anymore */
3256 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003257 f_sleep(0.2);
3258 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003259
3260 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3261 * there would be 8 retransmissions during 4 seconds */
3262 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003263 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003264 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003265 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003266 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003267 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003268 }
Harald Welte2caa1062018-03-17 18:19:05 +01003269 [] T_retrans.timeout {
3270 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3271 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3272 T_retrans.start;
3273 repeat;
3274 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003275 [] T.timeout {
3276 setverdict(pass);
3277 }
3278 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003279
3280 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003281}
3282
Harald Welte235ebf12017-12-15 14:18:16 +01003283/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003284testcase TC_paging_counter() runs on test_CT {
3285 var BSSMAP_FIELD_CellIdentificationList cid_list;
3286 timer T := 4.0;
3287 var integer i;
3288 var integer paging_attempted_bsc;
3289 var integer paging_attempted_bts[NUM_BTS];
3290 var integer paging_expired_bts[NUM_BTS];
3291 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3292
3293 f_init();
3294
3295 /* read counters before paging */
3296 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3297 for (i := 0; i < NUM_BTS; i := i+1) {
3298 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3299 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3300 }
3301
3302 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3303
3304 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3305 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3306 for (i := 0; i < NUM_BTS; i := i+1) {
3307 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3308 paging_attempted_bts[i]+1);
3309 }
3310
3311 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3312 f_sleep(12.0);
3313 for (i := 0; i < NUM_BTS; i := i+1) {
3314 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3315 paging_expired_bts[i]+1);
3316 }
Harald Welte1ff69992017-12-14 12:31:17 +01003317
Philipp Maier282ca4b2018-02-27 17:17:00 +01003318 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003319}
3320
3321
Harald Welte10985002017-12-12 09:29:15 +01003322/* Verify paging stops after A-RESET */
3323testcase TC_paging_imsi_a_reset() runs on test_CT {
3324 var BSSMAP_FIELD_CellIdentificationList cid_list;
3325 timer T := 3.0;
3326 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003327 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003328
3329 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003330 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 +01003331 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003332 [] 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 +01003333 [] BSSAP.receive { repeat; }
3334 }
3335
Daniel Willmanncbef3982018-07-30 09:22:40 +02003336 /* Wait to avoid a possible race condition if a paging message is
3337 * received right before the reset ACK. */
3338 f_sleep(0.2);
3339
Harald Welte10985002017-12-12 09:29:15 +01003340 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003341 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3342 IPA_RSL[i].clear;
3343 }
Harald Welte10985002017-12-12 09:29:15 +01003344
3345 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3346 T.start;
3347 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003348 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003349 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003350 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003351 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003352 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003353 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003354 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003355 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003356 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003357 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003358 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003359 }
Harald Welte10985002017-12-12 09:29:15 +01003360 [] T.timeout {
3361 setverdict(pass);
3362 }
3363 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003364
3365 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003366}
Harald Welteae026692017-12-09 01:03:01 +01003367
Philipp Maierf45824a2019-08-14 14:44:10 +02003368/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3369 * paging response we can not know which MSC is in charge, so we will blindly
3370 * pick the first configured MSC. This behavior is required in order to make
3371 * MT-CSFB calls working because in those cases the BSC can not know that the
3372 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3373 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003374 */
3375testcase TC_paging_resp_unsol() runs on test_CT {
3376
3377 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003378 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003379
3380 var BSSAP_N_CONNECT_ind rx_c_ind;
3381 var DchanTuple dt;
3382 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003383 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003384
3385 /* Send CHAN RQD and wait for allocation; acknowledge it */
3386 dt.rsl_chan_nr := f_chreq_act_ack();
3387
3388 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3389 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3390
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003391
Philipp Maierf45824a2019-08-14 14:44:10 +02003392 /* Expevct a CR with a matching Paging response on the A-Interface */
3393 T.start;
3394 alt {
3395 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3396 setverdict(pass);
3397 }
3398 [] BSSAP.receive {
3399 setverdict(fail, "Received unexpected message on A-Interface!");
3400 }
3401 [] T.timeout {
3402 setverdict(fail, "Received nothing on A-Interface!");
3403 }
3404 }
3405
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003406 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003407}
3408
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003409/* Test RSL link drop causes counter increment */
3410testcase TC_rsl_drop_counter() runs on test_CT {
3411 var integer rsl_fail;
3412
Harald Welte89d42e82017-12-17 16:42:41 +01003413 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003414
3415 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3416
3417 bts[0].rsl.vc_IPA.stop;
3418
3419 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3420
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003421 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003422}
3423
3424/* TODO: Test OML link drop causes counter increment */
3425
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003426/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3427function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3428 timer T := 10.0;
3429
3430 bts[0].rsl.id := "IPA-0-RSL";
3431 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3432 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3433 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003434 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003435
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003436 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003437
3438 f_init_mgcp("VirtMSC");
3439
3440 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3441 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3442 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3443 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3444
3445 /* wait for IPA OML link to connect and then disconnect */
3446 T.start;
3447 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003448 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003449 T.stop;
3450 return true;
3451 }
3452 [] IPA_RSL[0].receive { repeat }
3453 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003454 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003455 }
3456 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003457 return false;
3458}
3459
3460/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3461testcase TC_rsl_unknown_unit_id() runs on test_CT {
3462 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3463 setverdict(pass);
3464 } else {
3465 setverdict(fail, "Timeout RSL waiting for connection to close");
3466 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003467 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003468}
3469
3470
3471/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3472testcase TC_oml_unknown_unit_id() runs on test_CT {
3473 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3474 setverdict(pass);
3475 } else {
3476 setverdict(fail, "Timeout OML waiting for connection to close");
3477 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003478 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003479}
3480
3481
Harald Weltec1a2fff2017-12-17 11:06:19 +01003482/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003483 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003484 ***********************************************************************/
3485
Harald Welte6811d102019-04-14 22:23:14 +02003486import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003487import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003488import from RSL_Emulation all;
3489import from MSC_ConnectionHandler all;
3490
3491type function void_fn(charstring id) runs on MSC_ConnHdlr;
3492
Harald Welte336820c2018-05-31 20:34:52 +02003493/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003494private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3495 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003496 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003497 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003498 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003499 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003500 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3501 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3502 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003503 if (isvalue(bts[2])) {
3504 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3505 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3506 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003507 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003508 if (mp_enable_lcs_tests) {
3509 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3510 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3511 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003512 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003513 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003514 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003515}
3516
Neels Hofmeyrda436782021-07-20 22:09:06 +02003517function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003518runs on test_CT return MSC_ConnHdlr {
3519 var charstring id := testcasename();
3520 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003521 var integer bssap_idx := 0;
3522 if (isvalue(pars)) {
3523 bssap_idx := valueof(pars).mscpool.bssap_idx;
3524 }
Harald Welte336820c2018-05-31 20:34:52 +02003525 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003526 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003527 return vc_conn;
3528}
3529
3530function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3531runs on test_CT return MSC_ConnHdlr {
3532 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003533 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003534 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003535 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003536 return vc_conn;
3537}
3538
Neels Hofmeyrda436782021-07-20 22:09:06 +02003539function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3540runs on test_CT return MSC_ConnHdlr {
3541 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3542}
3543
Harald Weltea0630032018-03-20 21:09:55 +01003544/* first function inside ConnHdlr component; sets g_pars + starts function */
3545private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3546runs on MSC_ConnHdlr {
3547 if (isvalue(pars)) {
3548 g_pars := valueof(pars);
3549 }
3550 fn.apply(id);
3551}
3552
Oliver Smith26a3db72021-07-09 13:51:29 +02003553private function f_vty_encryption_a5(charstring options) runs on test_CT {
3554 f_vty_transceive(BSCVTY, "configure terminal");
3555 f_vty_transceive(BSCVTY, "network");
3556 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3557 f_vty_transceive(BSCVTY, "exit");
3558 f_vty_transceive(BSCVTY, "exit");
3559}
3560
3561private function f_vty_encryption_a5_reset() runs on test_CT {
3562 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3563 f_vty_encryption_a5("0 1 3");
3564}
3565
Harald Welte3c86ea02018-05-10 22:28:05 +02003566/* Establish signalling channel (non-assignment case) followed by cipher mode */
3567private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003568 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3569 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003570 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003571 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3572 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3573 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3574 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003575
Philipp Maier23000732018-05-18 11:25:37 +02003576 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003577}
3578testcase TC_ciph_mode_a5_0() runs on test_CT {
3579 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003580 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003581 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3582
3583 f_init(1, true);
3584 f_sleep(1.0);
3585 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3586 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003587 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003588}
3589testcase TC_ciph_mode_a5_1() runs on test_CT {
3590 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003591 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003592 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3593
3594 f_init(1, true);
3595 f_sleep(1.0);
3596 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3597 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003598 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003599}
Oliver Smith50b98122021-07-09 15:00:28 +02003600/* OS#4975: verify that A5/2 is preferred over A5/0 */
3601testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3602 var MSC_ConnHdlr vc_conn;
3603 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3604
3605 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3606 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3607
3608 f_init(1, true);
3609 f_vty_encryption_a5("0 1 2 3");
3610 f_sleep(1.0);
3611 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3612 vc_conn.done;
3613 f_vty_encryption_a5_reset();
3614 f_shutdown_helper();
3615}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003616/* OS#4975: verify that A5/1 is preferred over A5/2 */
3617testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3618 var MSC_ConnHdlr vc_conn;
3619 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3620
3621 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3622 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3623
3624 f_init(1, true);
3625 f_vty_encryption_a5("1 2");
3626 f_sleep(1.0);
3627 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3628 vc_conn.done;
3629 f_vty_encryption_a5_reset();
3630 f_shutdown_helper();
3631}
Harald Welte3c86ea02018-05-10 22:28:05 +02003632testcase TC_ciph_mode_a5_3() runs on test_CT {
3633 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003634 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003635 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3636
3637 f_init(1, true);
3638 f_sleep(1.0);
3639 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3640 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003641 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003642}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003643/* Establish a Signalling channel with A5/4 encryption. */
3644testcase TC_ciph_mode_a5_4() runs on test_CT {
3645 var MSC_ConnHdlr vc_conn;
3646 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3647 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003648
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003649 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003650 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003651 f_sleep(1.0);
3652 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3653 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003654 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003655 f_shutdown_helper();
3656}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003657/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3658private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3659 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3660 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3661 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3662 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3663
3664 f_establish_fully(ass_cmd, exp_compl);
3665}
3666testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3667 var MSC_ConnHdlr vc_conn;
3668 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3669
3670 f_init(1, true);
3671 f_sleep(1.0);
3672 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3673 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003674 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003675}
3676
Harald Welte3c86ea02018-05-10 22:28:05 +02003677
3678/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003679private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003680 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3681 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003682
Harald Welte552620d2017-12-16 23:21:36 +01003683 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3684 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003685
Harald Weltea0630032018-03-20 21:09:55 +01003686 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003687}
Harald Welte552620d2017-12-16 23:21:36 +01003688testcase TC_assignment_fr_a5_0() runs on test_CT {
3689 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003690 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003691 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003692
Harald Welte89d42e82017-12-17 16:42:41 +01003693 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003694 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003695 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003696 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003697 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003698}
Harald Welte552620d2017-12-16 23:21:36 +01003699testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003700 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003701 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003702 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003703
Harald Welte89d42e82017-12-17 16:42:41 +01003704 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003705 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003706 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3707 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003708 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003709}
3710testcase TC_assignment_fr_a5_3() runs on test_CT {
3711 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003712 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003713 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003714
Harald Welte651fcdc2018-05-10 20:23:16 +02003715 f_init(1, true);
3716 f_sleep(1.0);
3717 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003718 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003719 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003720}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003721/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3722testcase TC_assignment_fr_a5_4() runs on test_CT {
3723 var MSC_ConnHdlr vc_conn;
3724 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3725 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3726
3727 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003728 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003729 f_sleep(1.0);
3730 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3731 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003732 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003733 f_shutdown_helper();
3734}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003735
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003736/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3737testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3738 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3739 var MSC_ConnHdlr vc_conn;
3740
3741 f_init(1, true);
3742 f_sleep(1.0);
3743
3744 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3745 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3746 vc_conn.done;
3747 f_shutdown_helper();
3748}
3749
Harald Welte552620d2017-12-16 23:21:36 +01003750/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3751private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003752 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003753 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003754 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003755
3756 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003757 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3758
Harald Weltea0630032018-03-20 21:09:55 +01003759 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003760}
Harald Welte552620d2017-12-16 23:21:36 +01003761testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3762 var MSC_ConnHdlr vc_conn;
3763
Harald Welte89d42e82017-12-17 16:42:41 +01003764 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003765 f_sleep(1.0);
3766
Harald Welte8863fa12018-05-10 20:15:27 +02003767 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003768 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003769 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003770}
3771
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003772private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3773 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3774 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003775
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003776 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3777 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3778
3779 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3780
3781 var BSSMAP_FIELD_CodecType codecType;
3782 timer T := 10.0;
3783
3784 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3785 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3786
3787 f_create_chan_and_exp();
3788 /* we should now have a COMPL_L3 at the MSC */
3789
3790 var template PDU_BSSAP exp_l3_compl;
3791 exp_l3_compl := tr_BSSMAP_ComplL3()
3792 if (g_pars.aoip == false) {
3793 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3794 } else {
3795 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3796 }
3797 T.start;
3798 alt {
3799 [] BSSAP.receive(exp_l3_compl);
3800 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3801 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3802 }
3803 [] T.timeout {
3804 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3805 }
3806 }
3807
3808 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003809 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003810}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003811testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3812 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003813 var MSC_ConnHdlr vc_conn;
3814
Harald Welte89d42e82017-12-17 16:42:41 +01003815 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003816 f_sleep(1.0);
3817
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003818 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003819 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003820 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003821 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003822}
3823
3824
Harald Welte4532e0a2017-12-23 02:05:44 +01003825private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003826 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003827 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003828 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003829 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003830
3831 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003832 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003833
3834 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003835 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3836 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003837 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3838 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3839 };
3840 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003841}
3842
3843testcase TC_assignment_sign() runs on test_CT {
3844 var MSC_ConnHdlr vc_conn;
3845
3846 f_init(1, true);
3847 f_sleep(1.0);
3848
Harald Welte8863fa12018-05-10 20:15:27 +02003849 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003850 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003851 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003852}
3853
Harald Welte60aa5762018-03-21 19:33:13 +01003854/***********************************************************************
3855 * Codec (list) testing
3856 ***********************************************************************/
3857
3858/* check if the given rsl_mode is compatible with the a_elem */
3859private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3860return boolean {
3861 select (a_elem.codecType) {
3862 case (GSM_FR) {
3863 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3864 return true;
3865 }
3866 }
3867 case (GSM_HR) {
3868 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3869 return true;
3870 }
3871 }
3872 case (GSM_EFR) {
3873 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3874 return true;
3875 }
3876 }
3877 case (FR_AMR) {
3878 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3879 return true;
3880 }
3881 }
3882 case (HR_AMR) {
3883 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3884 return true;
3885 }
3886 }
3887 case else { }
3888 }
3889 return false;
3890}
3891
3892/* check if the given rsl_mode is compatible with the a_list */
3893private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3894return boolean {
3895 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3896 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3897 return true;
3898 }
3899 }
3900 return false;
3901}
3902
3903/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003904function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003905return BSSMAP_IE_ChannelType {
3906 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3907 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3908 select (a_elem.codecType) {
3909 case (GSM_FR) {
3910 ret.channelRateAndType := ChRate_TCHF;
3911 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3912 }
3913 case (GSM_HR) {
3914 ret.channelRateAndType := ChRate_TCHH;
3915 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3916 }
3917 case (GSM_EFR) {
3918 ret.channelRateAndType := ChRate_TCHF;
3919 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3920 }
3921 case (FR_AMR) {
3922 ret.channelRateAndType := ChRate_TCHF;
3923 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3924 }
3925 case (HR_AMR) {
3926 ret.channelRateAndType := ChRate_TCHH;
3927 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3928 }
3929 case else {
3930 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003931 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003932 }
3933 }
3934 return ret;
3935}
3936
Harald Weltea63b9102018-03-22 20:36:16 +01003937private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3938return template RSL_IE_Body {
3939 var template RSL_IE_Body mode_ie := {
3940 chan_mode := {
3941 len := ?,
3942 reserved := ?,
3943 dtx_d := ?,
3944 dtx_u := ?,
3945 spd_ind := RSL_SPDI_SPEECH,
3946 ch_rate_type := -,
3947 coding_alg_rate := -
3948 }
3949 }
3950
3951 select (a_elem.codecType) {
3952 case (GSM_FR) {
3953 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3954 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3955 }
3956 case (GSM_HR) {
3957 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3958 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3959 }
3960 case (GSM_EFR) {
3961 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3962 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3963 }
3964 case (FR_AMR) {
3965 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3966 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3967 }
3968 case (HR_AMR) {
3969 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3970 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3971 }
3972 }
3973 return mode_ie;
3974}
3975
Harald Welte60aa5762018-03-21 19:33:13 +01003976type record CodecListTest {
3977 BSSMAP_IE_SpeechCodecList codec_list,
3978 charstring id
3979}
3980type record of CodecListTest CodecListTests
3981
3982private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003983 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3984 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003985
3986 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003987 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003988 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3989 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3990 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003991 if (isvalue(g_pars.expect_mr_s0_s7)) {
3992 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3993 g_pars.expect_mr_s0_s7;
3994 }
Harald Welte79f3f542018-05-25 20:02:37 +02003995 }
Harald Welte60aa5762018-03-21 19:33:13 +01003996 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3997 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003998 log("expecting ASS COMPL like this: ", exp_compl);
3999
4000 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004001
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004002 if (not g_pars.expect_channel_mode_modify) {
4003 /* Verify that the RSL-side activation actually matches our expectations */
4004 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004005
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004006 var RSL_IE_Body mode_ie;
4007 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4008 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004009 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004010 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004011 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4012 if (not match(mode_ie, t_mode_ie)) {
4013 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4014 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004015 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004016
4017 var RSL_IE_Body mr_conf;
4018 if (g_pars.expect_mr_conf_ie != omit) {
4019 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4020 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4021 mtc.stop;
4022 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004023 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004024
4025 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4026 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4027 g_pars.expect_mr_conf_ie);
4028 }
4029 } else {
4030 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4031 log("found RSL MR CONFIG IE: ", mr_conf);
4032 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4033 mtc.stop;
4034 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004035 }
4036 }
Harald Welte60aa5762018-03-21 19:33:13 +01004037}
4038
Philipp Maierd0e64b02019-03-13 14:15:23 +01004039private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4040
4041 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4042 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4043
4044 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004045 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004046 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4047 }
4048 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4049 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4050 log("expecting ASS FAIL like this: ", exp_fail);
4051
4052 f_establish_fully(ass_cmd, exp_fail);
4053}
4054
Harald Welte60aa5762018-03-21 19:33:13 +01004055testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004056 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004057 var MSC_ConnHdlr vc_conn;
4058
4059 f_init(1, true);
4060 f_sleep(1.0);
4061
4062 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004063 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004064 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004065 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004066}
4067
4068testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004069 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004070 var MSC_ConnHdlr vc_conn;
4071
4072 f_init(1, true);
4073 f_sleep(1.0);
4074
4075 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004076 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004077 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004078 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004079}
4080
4081testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004082 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004083 var MSC_ConnHdlr vc_conn;
4084
4085 f_init(1, true);
4086 f_sleep(1.0);
4087
4088 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004089 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004090 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004091 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004092}
4093
Philipp Maierd0e64b02019-03-13 14:15:23 +01004094/* Allow 5,90k only (current default config) */
4095private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004096 f_vty_cfg_msc(BSCVTY, 0, {
4097 "amr-config 12_2k forbidden",
4098 "amr-config 10_2k forbidden",
4099 "amr-config 7_95k forbidden",
4100 "amr-config 7_40k forbidden",
4101 "amr-config 6_70k forbidden",
4102 "amr-config 5_90k allowed",
4103 "amr-config 5_15k forbidden",
4104 "amr-config 4_75k forbidden"
4105 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004106}
4107
4108/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4109 * ("Config-NB-Code = 1") */
4110private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004111 f_vty_cfg_msc(BSCVTY, 0, {
4112 "amr-config 12_2k allowed",
4113 "amr-config 10_2k forbidden",
4114 "amr-config 7_95k forbidden",
4115 "amr-config 7_40k allowed",
4116 "amr-config 6_70k forbidden",
4117 "amr-config 5_90k allowed",
4118 "amr-config 5_15k forbidden",
4119 "amr-config 4_75k allowed"
4120 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004121}
4122
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004123private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4124 var charstring tch;
4125 if (fr) {
4126 tch := "tch-f";
4127 } else {
4128 tch := "tch-h";
4129 }
4130 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4131}
4132
4133/* Set the AMR start-mode for this TCH back to the default configuration. */
4134private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4135 f_vty_amr_start_mode_set(fr, "auto");
4136}
4137
Harald Welte60aa5762018-03-21 19:33:13 +01004138testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004139 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004140 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004141
4142 /* Note: This setups the codec configuration. The parameter payload in
4143 * mr_conf must be consistant with the parameter codecElements in pars
4144 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004145 var RSL_IE_Body mr_conf := {
4146 other := {
4147 len := 2,
4148 payload := '2804'O
4149 }
4150 };
Harald Welte60aa5762018-03-21 19:33:13 +01004151
Philipp Maier7695a0d2018-09-27 17:52:14 +02004152 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004153 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004154 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4155 pars.expect_mr_conf_ie := mr_conf;
4156
Harald Welte60aa5762018-03-21 19:33:13 +01004157 f_init(1, true);
4158 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004159 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004160
Harald Welte8863fa12018-05-10 20:15:27 +02004161 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004162 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004163
4164 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004165 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004166}
4167
4168testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004169 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004170 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004171
4172 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004173 var RSL_IE_Body mr_conf := {
4174 other := {
4175 len := 2,
4176 payload := '2804'O
4177 }
4178 };
Harald Welte60aa5762018-03-21 19:33:13 +01004179
Philipp Maier7695a0d2018-09-27 17:52:14 +02004180 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004181 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004182 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4183 pars.expect_mr_conf_ie := mr_conf;
4184
Harald Welte60aa5762018-03-21 19:33:13 +01004185 f_init(1, true);
4186 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004187 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004188
Harald Welte8863fa12018-05-10 20:15:27 +02004189 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004190 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004191
4192 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004193 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004194}
4195
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004196/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4197testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4198 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4199 var MSC_ConnHdlr vc_conn;
4200
4201 f_init(1, true);
4202 f_sleep(1.0);
4203
4204 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4205 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4206 * expecting a Channel Mode Modify if the channel type is compatible. */
4207 f_disable_all_sdcch();
4208 f_disable_all_tch_h();
4209
4210 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4211 pars.expect_channel_mode_modify := true;
4212 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4213 vc_conn.done;
4214
4215 f_enable_all_sdcch();
4216 f_enable_all_tch();
4217 f_shutdown_helper();
4218}
4219
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004220/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4221testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4222 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4223 var MSC_ConnHdlr vc_conn;
4224
4225 var RSL_IE_Body mr_conf := {
4226 other := {
4227 len := 2,
4228 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4229 }
4230 };
4231
4232 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4233 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4234 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4235 pars.expect_mr_conf_ie := mr_conf;
4236
4237 f_init(1, true);
4238 f_sleep(1.0);
4239
4240 /* First set nonzero start mode bits */
4241 f_vty_amr_start_mode_set(true, "4");
4242 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4243 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4244 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4245 f_vty_amr_start_mode_set(true, "auto");
4246
4247 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4248 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004249
4250 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4251 f_vty_amr_start_mode_set(true, "1");
4252 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004253 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004254}
4255
Neels Hofmeyr21863562020-11-26 00:34:33 +00004256function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4257 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004258runs on test_CT {
4259
4260 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4261 var MSC_ConnHdlr vc_conn;
4262
4263 /* See note above */
4264 var RSL_IE_Body mr_conf := {
4265 other := {
4266 len := lengthof(mrconf),
4267 payload := mrconf
4268 }
4269 };
4270
4271 if (fr) {
4272 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4273 } else {
4274 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4275 }
4276 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4277 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4278 pars.expect_mr_conf_ie := mr_conf;
4279 pars.expect_mr_s0_s7 := exp_s8_s0;
4280
4281 f_init(1, true);
4282 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004283 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004284 f_sleep(1.0);
4285
4286 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4287 vc_conn.done;
4288 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004289 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004290}
4291
4292function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4293runs on test_CT {
4294
4295 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4296 var MSC_ConnHdlr vc_conn;
4297
4298 if (fr) {
4299 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4300 } else {
4301 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4302 }
4303 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4304 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4305
4306 f_init(1, true);
4307 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004308 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004309 f_sleep(1.0);
4310
4311 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4312 vc_conn.done;
4313 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004314 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004315}
4316
4317
4318/* Set S1, we expect an AMR multirate configuration IE with all four rates
4319 * set. */
4320testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004321 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004322 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004323}
4324
4325/* Set S1, we expect an AMR multirate configuration IE with the lower three
4326 * rates set. */
4327testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004328 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004329 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004330}
4331
4332/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4333 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4334testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004335 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004336 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004337}
4338
4339/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4340 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4341testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004342 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004343 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004344}
4345
4346/* The following block of tests selects more and more rates until all four
4347 * possible rates are in the active set (full rate) */
4348testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004349 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004350 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004351}
4352
4353testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004354 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004355 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004356}
4357
4358testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004359 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004360 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004361}
4362
4363testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004364 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004365 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004366}
4367
4368/* The following block of tests selects more and more rates until all three
4369 * possible rates are in the active set (half rate) */
4370testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004371 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004372 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004373}
4374
4375testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004376 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004377 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004378}
4379
4380testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004381 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004382 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004383}
4384
4385/* The following block tests what happens when the MSC does offer rate
4386 * configurations that are not supported by the BSC. Normally such situations
4387 * should not happen because the MSC gets informed by the BSC in advance via
4388 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4389 * to offer rates that are not applicable anyway. */
4390
4391testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004392 /* Try to include 12,2k in into the active set even though the channel
4393 * is half rate only. The BSC is expected to remove the 12,0k */
4394 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004395 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004396}
4397
4398testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004399 /* See what happens when all rates are selected at once. Since then
4400 * Also S1 is selected, this setting will be prefered and we should
4401 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4402 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004403 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004404}
4405
4406testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004407 /* Same as above, but with S1 missing, the MSC is then expected to
4408 * select the currently supported rates, which are also 12.2k, 7,40k,
4409 * 5,90k, and 4,75k, into the active set. */
4410 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004411 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004412}
4413
4414testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004415 /* Try to select no rates at all */
4416 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004417 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004418}
4419
4420testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004421 /* Try to select only unsupported rates */
4422 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004423 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004424}
4425
4426testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004427 /* Try to select 12,2k for half rate */
4428 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004429 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004430}
4431
Neels Hofmeyr21863562020-11-26 00:34:33 +00004432testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4433 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4434 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004435 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004436}
4437
4438testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4439 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4440 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004441 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004442}
4443
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004444testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004445 /* "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 +00004446 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4447 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004448 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004449}
4450
4451testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004452 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4453 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004454 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004455 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004456}
4457
Philipp Maierac09bfc2019-01-08 13:41:39 +01004458private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004459 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4460 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4461 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4462 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004463}
4464
4465private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004466 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4467 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004468}
4469
4470private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004471 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4472 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4473 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4474 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4475 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4476 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004477}
4478
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004479private function f_disable_all_sdcch() runs on test_CT {
4480 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4481 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4482 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4483 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4484}
4485
4486private function f_enable_all_sdcch() runs on test_CT {
4487 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4488 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4489 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4490 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4491}
4492
Philipp Maierac09bfc2019-01-08 13:41:39 +01004493/* Allow HR only */
4494private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4495 g_pars := f_gen_test_hdlr_pars();
4496 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4497 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4498 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4499 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4500 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4501 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4502 f_establish_fully(ass_cmd, exp_compl);
4503}
4504
4505/* Allow FR only */
4506private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4507 g_pars := f_gen_test_hdlr_pars();
4508 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4509 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4510 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4511 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4512 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4513 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4514 f_establish_fully(ass_cmd, exp_compl);
4515}
4516
4517/* Allow HR only (expect assignment failure) */
4518private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4519 g_pars := f_gen_test_hdlr_pars();
4520 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4521 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4522 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4523 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4524 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4525 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4526 f_establish_fully(ass_cmd, exp_fail);
4527}
4528
4529/* Allow FR only (expect assignment failure) */
4530private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4531 g_pars := f_gen_test_hdlr_pars();
4532 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4533 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4534 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4535 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4536 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4537 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4538 f_establish_fully(ass_cmd, exp_fail);
4539}
4540
4541/* Allow FR and HR, but prefer FR */
4542private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4543 g_pars := f_gen_test_hdlr_pars();
4544 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4545 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4546 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4547 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4548 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4549 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4550 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4551 f_establish_fully(ass_cmd, exp_compl);
4552}
4553
4554/* Allow FR and HR, but prefer HR */
4555private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4556 g_pars := f_gen_test_hdlr_pars();
4557 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4558 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4559 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4560 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4561 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4562 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4563 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4564 f_establish_fully(ass_cmd, exp_compl);
4565}
4566
4567/* Allow FR and HR, but prefer FR */
4568private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4569 g_pars := f_gen_test_hdlr_pars();
4570 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4571 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4572 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4573 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4574 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4575 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4576 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4577 f_establish_fully(ass_cmd, exp_compl);
4578}
4579
4580/* Allow FR and HR, but prefer HR */
4581private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4582 g_pars := f_gen_test_hdlr_pars();
4583 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4584 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4585 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4586 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4587 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4588 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4589 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4590 f_establish_fully(ass_cmd, exp_compl);
4591}
4592
4593/* Request a HR channel while all FR channels are exhausted, this is expected
4594 * to work without conflicts */
4595testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4596 var MSC_ConnHdlr vc_conn;
4597 f_init(1, true);
4598 f_sleep(1.0);
4599 f_enable_all_tch();
4600 f_disable_all_tch_f();
4601 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4602 vc_conn.done;
4603 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004604 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004605}
4606
4607/* Request a FR channel while all FR channels are exhausted, this is expected
4608 * to fail. */
4609testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4610 var MSC_ConnHdlr vc_conn;
4611 f_init(1, true);
4612 f_sleep(1.0);
4613 f_enable_all_tch();
4614 f_disable_all_tch_f();
4615 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4616 vc_conn.done;
4617 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004618 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004619}
4620
4621/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4622 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4623testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4624 var MSC_ConnHdlr vc_conn;
4625 f_init(1, true);
4626 f_sleep(1.0);
4627 f_enable_all_tch();
4628 f_disable_all_tch_f();
4629 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4630 vc_conn.done;
4631 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004632 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004633}
4634
4635/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4636 * are exhausted, this is expected to work without conflicts. */
4637testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4638 var MSC_ConnHdlr vc_conn;
4639 f_init(1, true);
4640 f_sleep(1.0);
4641 f_enable_all_tch();
4642 f_disable_all_tch_f();
4643 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4644 vc_conn.done;
4645 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004646 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004647}
4648
4649/* Request a FR channel while all HR channels are exhausted, this is expected
4650 * to work without conflicts */
4651testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4652 var MSC_ConnHdlr vc_conn;
4653 f_init(1, true);
4654 f_sleep(1.0);
4655 f_enable_all_tch();
4656 f_disable_all_tch_h();
4657 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4658 vc_conn.done;
4659 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004660 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004661}
4662
4663/* Request a HR channel while all HR channels are exhausted, this is expected
4664 * to fail. */
4665testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4666 var MSC_ConnHdlr vc_conn;
4667 f_init(1, true);
4668 f_sleep(1.0);
4669 f_enable_all_tch();
4670 f_disable_all_tch_h();
4671 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4672 vc_conn.done;
4673 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004674 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004675}
4676
4677/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4678 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4679testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4680 var MSC_ConnHdlr vc_conn;
4681 f_init(1, true);
4682 f_sleep(1.0);
4683 f_enable_all_tch();
4684 f_disable_all_tch_h();
4685 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4686 vc_conn.done;
4687 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004688 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004689}
4690
4691/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4692 * are exhausted, this is expected to work without conflicts. */
4693testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4694 var MSC_ConnHdlr vc_conn;
4695 f_init(1, true);
4696 f_sleep(1.0);
4697 f_enable_all_tch();
4698 f_disable_all_tch_h();
4699 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4700 vc_conn.done;
4701 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004702 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004703}
4704
4705/* Allow FR and HR, but prefer HR */
4706private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4707 g_pars := f_gen_test_hdlr_pars();
4708 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4709 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4710 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4711 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4712 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4713 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4714 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4715 f_establish_fully(ass_cmd, exp_compl);
4716}
4717
4718/* Allow FR and HR, but prefer FR */
4719private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4720 g_pars := f_gen_test_hdlr_pars();
4721 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4722 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4723 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4724 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4725 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4726 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4727 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4728 f_establish_fully(ass_cmd, exp_compl);
4729}
4730
4731/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4732 * HR, which is the prefered type, is selected. */
4733testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4734 var MSC_ConnHdlr vc_conn;
4735 f_init(1, true);
4736 f_sleep(1.0);
4737 f_enable_all_tch();
4738 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4739 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004740 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004741}
4742
4743/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4744 * FR, which is the prefered type, is selected. */
4745testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4746 var MSC_ConnHdlr vc_conn;
4747 f_init(1, true);
4748 f_sleep(1.0);
4749 f_enable_all_tch();
4750 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4751 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004752 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004753}
4754
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004755/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4756private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4757 g_pars := f_gen_test_hdlr_pars();
4758 g_pars.ra := '02'O; /* RA containing reason=LU */
4759
4760 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4761 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4762 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4763 var template uint3_t tsc := ?;
4764
4765 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4766 f_create_bssmap_exp(l3_enc);
4767 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4768 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4769
4770 /* we should now have a COMPL_L3 at the MSC */
4771 timer T := 10.0;
4772 T.start;
4773 alt {
4774 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4775 [] T.timeout {
4776 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4777 }
4778 }
4779}
4780testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4781 var MSC_ConnHdlr vc_conn;
4782 f_init(1, true);
4783 f_sleep(1.0);
4784 f_disable_all_sdcch();
4785 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4786 vc_conn.done;
4787 f_enable_all_sdcch();
4788 f_shutdown_helper();
4789}
4790
4791/* Request a signalling channel with all SDCCH exhausted, it is
4792 expected that no TCH will be selected for signalling and assigment will fail
4793 because it's dictated by VTY config */
4794testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4795 var RSL_Message rsl_unused, rsl_msg;
4796 var GsmRrMessage rr;
4797 f_init(1, false);
4798 f_sleep(1.0);
4799 f_vty_allow_tch_for_signalling(false, 0);
4800 f_disable_all_sdcch();
4801
4802 /* RA containing reason=LU */
4803 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4804 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4805 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4806 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4807 setverdict(fail, "Expected reject");
4808 }
4809
4810 f_vty_allow_tch_for_signalling(true, 0);
4811 f_enable_all_sdcch();
4812 f_shutdown_helper();
4813}
4814
4815/* Request a voice channel with all SDCCH exhausted, it is
4816 * expected that TCH channel will be allocated since the VTY option is only
4817 * aimed at signalling requests */
4818private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4819 g_pars := f_gen_test_hdlr_pars();
4820 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4821
4822 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4823 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4824 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4825 var template uint3_t tsc := ?;
4826
4827 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4828 f_create_bssmap_exp(l3_enc);
4829 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4830 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4831
4832 /* we should now have a COMPL_L3 at the MSC */
4833 timer T := 10.0;
4834 T.start;
4835 alt {
4836 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4837 [] T.timeout {
4838 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4839 }
4840 }
4841}
4842testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4843 var MSC_ConnHdlr vc_conn;
4844 f_init(1, true);
4845 f_sleep(1.0);
4846 f_vty_allow_tch_for_signalling(false, 0);
4847 f_disable_all_sdcch();
4848
4849 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4850 vc_conn.done;
4851
4852 f_vty_allow_tch_for_signalling(true, 0);
4853 f_enable_all_sdcch();
4854 f_shutdown_helper();
4855}
4856
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004857testcase TC_assignment_osmux() runs on test_CT {
4858 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4859 var MSC_ConnHdlr vc_conn;
4860
4861 /* See note above */
4862 var RSL_IE_Body mr_conf := {
4863 other := {
4864 len := 2,
4865 payload := '2804'O
4866 }
4867 };
4868
4869 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4870 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4871 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4872 pars.expect_mr_conf_ie := mr_conf;
4873 pars.use_osmux := true;
4874
4875 f_init(1, true, true);
4876 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004877 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004878
4879 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4880 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004881
4882 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004883 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004884}
4885
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004886/* test the procedure of the MSC requesting a Classmark Update:
4887 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4888 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004889private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004890 g_pars := f_gen_test_hdlr_pars();
4891
Harald Weltea0630032018-03-20 21:09:55 +01004892 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004893 /* we should now have a COMPL_L3 at the MSC */
4894 BSSAP.receive(tr_BSSMAP_ComplL3);
4895
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004896 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4897 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4898
Harald Welte898113b2018-01-31 18:32:21 +01004899 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4900 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4901 setverdict(pass);
4902}
4903testcase TC_classmark() runs on test_CT {
4904 var MSC_ConnHdlr vc_conn;
4905 f_init(1, true);
4906 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004907 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004908 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004909 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004910}
4911
Harald Welteeddf0e92020-06-21 19:42:15 +02004912/* Send a CommonID from the simulated MSC and verify that the information is used to
4913 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4914private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4915 g_pars := f_gen_test_hdlr_pars();
4916 f_MscConnHdlr_init_vty();
4917
4918 f_create_chan_and_exp();
4919 /* we should now have a COMPL_L3 at the MSC */
4920 BSSAP.receive(tr_BSSMAP_ComplL3);
4921
4922 /* Send CommonID */
4923 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4924
4925 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4926 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4927 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4928
4929 setverdict(pass);
4930}
4931testcase TC_common_id() runs on test_CT {
4932 var MSC_ConnHdlr vc_conn;
4933 f_init(1, true);
4934 f_sleep(1.0);
4935 vc_conn := f_start_handler(refers(f_tc_common_id));
4936 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004937 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004938}
4939
Harald Weltee3bd6582018-01-31 22:51:25 +01004940private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004941 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004942 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004943 /* we should now have a COMPL_L3 at the MSC */
4944 BSSAP.receive(tr_BSSMAP_ComplL3);
4945
Harald Weltee3bd6582018-01-31 22:51:25 +01004946 /* send the single message we want to send */
4947 f_rsl_send_l3(l3);
4948}
4949
4950private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4951 timer T := sec;
4952 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004953 T.start;
4954 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004955 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4956 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004957 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004958 }
4959 [] T.timeout {
4960 setverdict(pass);
4961 }
4962 }
4963}
4964
Harald Weltee3bd6582018-01-31 22:51:25 +01004965/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4966private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4967 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4968 f_bssap_expect_nothing();
4969}
Harald Welte898113b2018-01-31 18:32:21 +01004970testcase TC_unsol_ass_fail() runs on test_CT {
4971 var MSC_ConnHdlr vc_conn;
4972 f_init(1, true);
4973 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004974 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004975 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004976 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004977}
Harald Welte552620d2017-12-16 23:21:36 +01004978
Harald Welteea99a002018-01-31 20:46:43 +01004979
4980/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4981private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004982 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4983 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004984}
4985testcase TC_unsol_ass_compl() runs on test_CT {
4986 var MSC_ConnHdlr vc_conn;
4987 f_init(1, true);
4988 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004989 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004990 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004991 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004992}
4993
4994
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004995/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4996private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004997 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4998 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004999}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005000testcase TC_unsol_ho_fail() runs on test_CT {
5001 var MSC_ConnHdlr vc_conn;
5002 f_init(1, true);
5003 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005004 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005005 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005006 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005007}
5008
5009
Harald Weltee3bd6582018-01-31 22:51:25 +01005010/* short message from MS should be ignored */
5011private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005012 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005013 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005014 /* we should now have a COMPL_L3 at the MSC */
5015 BSSAP.receive(tr_BSSMAP_ComplL3);
5016
5017 /* send short message */
5018 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5019 f_bssap_expect_nothing();
5020}
5021testcase TC_err_82_short_msg() runs on test_CT {
5022 var MSC_ConnHdlr vc_conn;
5023 f_init(1, true);
5024 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005025 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005026 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005027 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005028}
5029
5030
Harald Weltee9e02e42018-01-31 23:36:25 +01005031/* 24.008 8.4 Unknown message must trigger RR STATUS */
5032private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5033 f_est_single_l3(ts_RRM_UL_REL('00'O));
5034 timer T := 3.0
5035 alt {
5036 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5037 setverdict(pass);
5038 }
5039 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005040 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005041 }
5042}
5043testcase TC_err_84_unknown_msg() runs on test_CT {
5044 var MSC_ConnHdlr vc_conn;
5045 f_init(1, true);
5046 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005047 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005048 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005049 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005050}
5051
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005052/***********************************************************************
5053 * Handover
5054 ***********************************************************************/
5055
Harald Welte94e0c342018-04-07 11:33:23 +02005056/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5057private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5058runs on test_CT {
5059 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5060 " timeslot "&int2str(ts_nr)&" ";
5061 f_vty_transceive(BSCVTY, cmd & suffix);
5062}
5063
Harald Welte261af4b2018-02-12 21:20:39 +01005064/* 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 +07005065private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5066 uint8_t bts_nr, uint8_t trx_nr,
5067 in RslChannelNr chan_nr)
5068{
Harald Welte261af4b2018-02-12 21:20:39 +01005069 /* FIXME: resolve those from component-global state */
5070 var integer ts_nr := chan_nr.tn;
5071 var integer ss_nr;
5072 if (ischosen(chan_nr.u.ch0)) {
5073 ss_nr := 0;
5074 } else if (ischosen(chan_nr.u.lm)) {
5075 ss_nr := chan_nr.u.lm.sub_chan;
5076 } else if (ischosen(chan_nr.u.sdcch4)) {
5077 ss_nr := chan_nr.u.sdcch4.sub_chan;
5078 } else if (ischosen(chan_nr.u.sdcch8)) {
5079 ss_nr := chan_nr.u.sdcch8.sub_chan;
5080 } else {
5081 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005082 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005083 }
5084
5085 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5086 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005087 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005088}
5089
Neels Hofmeyr91401012019-07-11 00:42:35 +02005090/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5091 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5092 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5093 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5094 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005095private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5096 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5097{
5098 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005099}
5100
5101/* intra-BSC hand-over between BTS0 and BTS1 */
5102private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005103 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5104 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005105
5106 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5107 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5108
Harald Weltea0630032018-03-20 21:09:55 +01005109 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005110 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005111
5112 var HandoverState hs := {
5113 rr_ho_cmpl_seen := false,
5114 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005115 old_chan_nr := -,
5116 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005117 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005118 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005119 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005120 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5121 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005122
5123 /* From the MGW perspective, a handover is is characterized by
5124 * performing one MDCX operation with the MGW. So we expect to see
5125 * one more MDCX during handover. */
5126 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5127
Harald Welte261af4b2018-02-12 21:20:39 +01005128 alt {
5129 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005130 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005131
Philipp Maier4dae0652018-11-12 12:03:26 +01005132 /* Since this is an internal handover we expect the BSC to inform the
5133 * MSC about the event */
5134 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5135
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005136 /* Check the amount of MGCP transactions is still consistant with the
5137 * test expectation */
5138 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005139
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005140 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5141
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005142 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5143 * 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 +02005144 f_verify_encr_info(chan_act);
5145
5146 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005147
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005148 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005149}
5150
5151testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005152 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005153 var MSC_ConnHdlr vc_conn;
5154 f_init(2, true);
5155 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005156
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005157 pars.expect_tsc := BTS_TSC[0];
5158
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005159 f_ctrs_bsc_and_bts_init();
5160
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005161 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005162 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005163
5164 /* from f_establish_fully() */
5165 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5166 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5167 /* from handover */
5168 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5169 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5170 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5171 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5172 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005173 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005174}
Harald Weltee9e02e42018-01-31 23:36:25 +01005175
Oliver Smith7eabd312021-07-12 14:18:56 +02005176function 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 +02005177 var MSC_ConnHdlr vc_conn;
5178 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5179 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5180
5181 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005182 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005183 f_sleep(1.0);
5184
5185 f_ctrs_bsc_and_bts_init();
5186
5187 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5188 vc_conn.done;
5189
5190 /* from f_establish_fully() */
5191 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5192 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5193 /* from handover */
5194 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5195 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5196 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5197 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5198 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005199 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005200 f_shutdown_helper();
5201}
5202
5203testcase TC_ho_int_a5_0() runs on test_CT {
5204 f_tc_ho_int_a5('01'O);
5205}
5206
5207testcase TC_ho_int_a5_1() runs on test_CT {
5208 f_tc_ho_int_a5('02'O);
5209}
5210
5211testcase TC_ho_int_a5_3() runs on test_CT {
5212 f_tc_ho_int_a5('08'O);
5213}
5214
5215testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005216 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005217}
5218
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005219/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5220private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5221 g_pars := f_gen_test_hdlr_pars();
5222 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5223 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005224
5225 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5226 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5227
5228 f_establish_fully(ass_cmd, exp_compl);
5229 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5230
5231 var HandoverState hs := {
5232 rr_ho_cmpl_seen := false,
5233 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005234 old_chan_nr := -,
5235 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005236 };
5237 /* issue hand-over command on VTY */
5238 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5239 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5240 f_rslem_suspend(RSL1_PROC);
5241
5242 /* From the MGW perspective, a handover is is characterized by
5243 * performing one MDCX operation with the MGW. So we expect to see
5244 * one more MDCX during handover. */
5245 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5246
5247 var RSL_Message rsl;
5248 var PDU_ML3_NW_MS l3;
5249 var RslChannelNr new_chan_nr;
5250 var GsmArfcn arfcn;
5251 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5252 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5253 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5254 setverdict(fail, "Expected handoverCommand");
5255 mtc.stop;
5256 }
5257 }
5258 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5259 new_chan_nr, arfcn);
5260
5261 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5262
5263 /* resume processing of RSL DChan messages, which was temporarily suspended
5264 * before performing a hand-over */
5265 f_rslem_resume(RSL1_PROC);
5266 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5267
5268 f_sleep(1.0);
5269
5270 /* Handover fails because no HANDO DET appears on the new lchan,
5271 * and the old lchan reports a Radio Link Failure. */
5272 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5273
5274 var PDU_BSSAP rx_clear_request;
5275 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5276 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5277 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5278
5279 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5280
5281 var MgcpCommand mgcp;
5282 interleave {
5283 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5284 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005285 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005286 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005287 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005288 }
5289 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005290 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005291 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005292 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005293 }
5294 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5295 }
5296
5297 f_sleep(0.5);
5298 setverdict(pass);
5299}
5300testcase TC_ho_int_radio_link_failure() runs on test_CT {
5301 var MSC_ConnHdlr vc_conn;
5302 f_init(2, true);
5303 f_sleep(1.0);
5304
5305 f_ctrs_bsc_and_bts_init();
5306
5307 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5308 vc_conn.done;
5309
5310 /* from f_establish_fully() */
5311 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5312 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5313 /* from handover */
5314 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5315 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5316 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5317 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
5318 f_ctrs_bsc_and_bts_verify();
5319 f_shutdown_helper();
5320}
5321
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005322/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005323private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005324 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005325 var template MgcpResponse mgcp_resp;
5326 var MGCP_RecvFrom mrf;
5327 var template MgcpMessage msg_resp;
5328 var template MgcpMessage msg_dlcx := {
5329 command := tr_DLCX()
5330 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005331
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005332 if (g_pars.aoip) {
5333 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005334 log("Got first DLCX: ", mgcp);
5335 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005336 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005337
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005338 MGCP.receive(tr_DLCX()) -> value mgcp {
5339 log("Got second DLCX: ", mgcp);
5340 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5341 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005342 } else {
5343 /* For SCCPLite, BSC doesn't handle the MSC-side */
5344 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5345 log("Got first DLCX: ", mrf.msg.command);
5346 msg_resp := {
5347 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5348 }
5349 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5350 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005351 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005352}
5353
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005354private 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 +01005355
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005356 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005357 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5358
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005359 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005360
5361 f_sleep(0.5);
5362 /* The MSC negotiates Handover Request and Handover Request Ack with
5363 * the other BSS and comes back with a BSSMAP Handover Command
5364 * containing an RR Handover Command coming from the target BSS... */
5365
5366 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5367 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5368 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5369 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5370 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5371
5372 /* expect the Handover Command to go out on RR */
5373 var RSL_Message rsl_ho_cmd
5374 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5375 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5376 var RSL_IE_Body rsl_ho_cmd_l3;
5377 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5378 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5379 setverdict(fail);
5380 } else {
5381 log("Found L3 Info: ", rsl_ho_cmd_l3);
5382 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5383 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5384 setverdict(fail);
5385 } else {
5386 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5387 setverdict(pass);
5388 }
5389 }
5390
5391 /* When the other BSS has reported a completed handover, this side is
5392 * torn down. */
5393
5394 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5395 var BssmapCause cause := enum2int(cause_val);
5396 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5397
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005398 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005399
5400 interleave {
5401 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5402 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5403 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005404 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005405 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005406 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005407}
5408
5409private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5410 g_pars := f_gen_test_hdlr_pars();
5411 var PDU_BSSAP ass_req := f_gen_ass_req();
5412 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5413 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5414 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5415 f_establish_fully(ass_req, exp_compl);
5416
5417 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005418}
5419testcase TC_ho_out_of_this_bsc() runs on test_CT {
5420 var MSC_ConnHdlr vc_conn;
5421
5422 f_init(1, true);
5423 f_sleep(1.0);
5424
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005425 f_ctrs_bsc_and_bts_init();
5426
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005427 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5428 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005429
5430 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5431 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5432 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5433 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5434 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5435 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5436 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005437 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005438}
5439
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005440private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5441 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005442 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005443 octetstring l3 := '0123456789'O)
5444runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005445 /* The old lchan and conn should still be active. See that arbitrary L3
5446 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005447 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005448 var template PDU_BSSAP exp_data := {
5449 discriminator := '1'B,
5450 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005451 dlci := dlci,
5452 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005453 pdu := {
5454 dtap := l3
5455 }
5456 };
5457 BSSAP.receive(exp_data);
5458 setverdict(pass);
5459}
5460
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005461private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5462 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005463 template (value) OCT1 dlci := '00'O,
5464 octetstring l3 := '0123456789'O)
5465runs on MSC_ConnHdlr {
5466 BSSAP.send(PDU_BSSAP:{
5467 discriminator := '1'B,
5468 spare := '0000000'B,
5469 dlci := dlci,
5470 lengthIndicator := lengthof(l3),
5471 pdu := {
5472 dtap := l3
5473 }
5474 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005475 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005476 setverdict(pass);
5477}
5478
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005479/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5480 * simply never sends a BSSMAP Handover Command. */
5481private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005482 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005483
5484 var PDU_BSSAP ass_req := f_gen_ass_req();
5485 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5486 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5487 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5488 f_establish_fully(ass_req, exp_compl);
5489
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005490 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005491 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5492
5493 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5494
5495 /* osmo-bsc should time out 10 seconds after the handover started.
5496 * Let's give it a bit extra. */
5497 f_sleep(15.0);
5498
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005499 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005500 f_sleep(1.0);
5501}
5502testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5503 var MSC_ConnHdlr vc_conn;
5504
5505 f_init(1, true);
5506 f_sleep(1.0);
5507
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005508 f_ctrs_bsc_and_bts_init();
5509
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005510 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5511 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005512
5513 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5514 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5515 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5516 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5517 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5518 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5519 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005520 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005521}
5522
5523/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5524 * RR Handover Failure. */
5525private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005526 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005527
5528 var PDU_BSSAP ass_req := f_gen_ass_req();
5529 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5530 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5531 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5532 f_establish_fully(ass_req, exp_compl);
5533
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005534 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005535 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5536
5537 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5538
5539 f_sleep(0.5);
5540 /* The MSC negotiates Handover Request and Handover Request Ack with
5541 * the other BSS and comes back with a BSSMAP Handover Command
5542 * containing an RR Handover Command coming from the target BSS... */
5543
5544 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5545 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5546 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5547 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5548 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5549
5550 /* expect the Handover Command to go out on RR */
5551 var RSL_Message rsl_ho_cmd
5552 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5553 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5554 var RSL_IE_Body rsl_ho_cmd_l3;
5555 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5556 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5557 setverdict(fail);
5558 } else {
5559 log("Found L3 Info: ", rsl_ho_cmd_l3);
5560 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5561 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5562 setverdict(fail);
5563 } else {
5564 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5565 setverdict(pass);
5566 }
5567 }
5568
5569 f_sleep(0.2);
5570 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5571
5572 /* Should tell the MSC about the failure */
5573 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5574
5575 f_sleep(1.0);
5576
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005577 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005578 f_sleep(1.0);
5579
5580 setverdict(pass);
5581 f_sleep(1.0);
5582}
5583testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5584 var MSC_ConnHdlr vc_conn;
5585
5586 f_init(1, true);
5587 f_sleep(1.0);
5588
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005589 f_ctrs_bsc_and_bts_init();
5590
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005591 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5592 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005593
5594 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5595 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5596 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5597 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5598 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5599 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5600 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005601 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005602}
5603
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005604/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5605 * (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 +02005606 * and the lchan is released. */
5607private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005608 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005609
5610 var PDU_BSSAP ass_req := f_gen_ass_req();
5611 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5612 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5613 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5614 f_establish_fully(ass_req, exp_compl);
5615
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005616 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005617 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5618
5619 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5620
5621 f_sleep(0.5);
5622 /* The MSC negotiates Handover Request and Handover Request Ack with
5623 * the other BSS and comes back with a BSSMAP Handover Command
5624 * containing an RR Handover Command coming from the target BSS... */
5625
5626 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5627 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5628 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5629 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5630 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5631
5632 /* expect the Handover Command to go out on RR */
5633 var RSL_Message rsl_ho_cmd
5634 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5635 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5636 var RSL_IE_Body rsl_ho_cmd_l3;
5637 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5638 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5639 setverdict(fail);
5640 } else {
5641 log("Found L3 Info: ", rsl_ho_cmd_l3);
5642 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5643 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5644 setverdict(fail);
5645 } else {
5646 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5647 setverdict(pass);
5648 }
5649 }
5650
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005651 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5652 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5653 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005654
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005655 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005656 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5657 log("Got BSSMAP Clear Request");
5658 /* Instruct BSC to clear channel */
5659 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5660 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5661
5662 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005663 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005664 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5665 log("Got Deact SACCH");
5666 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005667 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005668 log("Got RR Release");
5669 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005670 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005671 log("Got RF Chan Rel");
5672 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005673 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005674 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005675 }
5676
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005677 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005678 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005679
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005680 setverdict(pass);
5681 f_sleep(1.0);
5682}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005683testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005684 var MSC_ConnHdlr vc_conn;
5685
5686 f_init(1, true);
5687 f_sleep(1.0);
5688
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005689 f_ctrs_bsc_and_bts_init();
5690
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005691 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005692 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005693
5694 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5695 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5696 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5697 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5698 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5699 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5700 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005701 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005702}
5703
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005704private 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 +01005705 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5706 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5707 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5708 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5709 * before we get started. */
5710 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5711 f_rslem_register(0, new_chan_nr);
5712 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005713 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005714 f_sleep(1.0);
5715
5716 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5717 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5718 activate(as_Media());
5719
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005720 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005721 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005722 oldToNewBSSIEs := oldToNewBSSIEs,
5723 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005724 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005725
5726 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5727
5728 var PDU_BSSAP rx_bssap;
5729 var octetstring ho_command_str;
5730
5731 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005732
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005733 /* we're sure that the channel activation is done now, verify the parameters in it */
5734 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
5735 f_verify_encr_info(chan_act);
5736 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005737
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005738 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5739 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5740 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5741 log("L3 Info in HO Request Ack is ", ho_command);
5742
5743 var GsmArfcn arfcn;
5744 var RslChannelNr actual_new_chan_nr;
5745 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5746 actual_new_chan_nr, arfcn);
5747
5748 if (actual_new_chan_nr != new_chan_nr) {
5749 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5750 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5751 setverdict(fail);
5752 return;
5753 }
5754 log("Handover Command chan_nr is", actual_new_chan_nr);
5755
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02005756 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
5757 if (not match(got_tsc, expect_target_tsc)) {
5758 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
5759 expect_target_tsc, " got ", got_tsc);
5760 mtc.stop;
5761 } else {
5762 log("handoverCommand: verified TSC = ", got_tsc);
5763 }
5764
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005765 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5766 * tells the MS to handover to the new lchan. Here comes the new MS on
5767 * the new lchan with a Handover RACH: */
5768
5769 /* send handover detect */
5770
5771 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5772
5773 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5774
5775 /* send handover complete over the new channel */
5776
5777 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5778 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5779 enc_PDU_ML3_MS_NW(l3_tx)));
5780
5781 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005782 setverdict(pass);
5783}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005784
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005785private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005786 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005787 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5788 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5789 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005790 }
5791 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005792 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005793 } else {
5794 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005795 }
5796 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005797 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005798 setverdict(pass);
5799}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005800function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005801 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005802
5803 f_init(1, true);
5804 f_sleep(1.0);
5805
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005806 f_ctrs_bsc_and_bts_init();
5807
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005808 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5809 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005810
5811 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5812 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005813
5814 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5815 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5816 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5817 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5818 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005819}
5820
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005821testcase TC_ho_into_this_bsc() runs on test_CT {
5822 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5823 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005824 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005825}
5826
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005827function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5828 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5829 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5830 f_tc_ho_into_this_bsc_main(pars);
5831 f_shutdown_helper();
5832}
5833
5834testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5835 f_tc_ho_into_this_bsc_a5('01'O);
5836}
5837
5838testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5839 f_tc_ho_into_this_bsc_a5('02'O);
5840}
5841
5842testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5843 f_tc_ho_into_this_bsc_a5('08'O);
5844}
5845
5846testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5847 f_tc_ho_into_this_bsc_a5('10'O);
5848}
5849
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005850testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5851 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5852 pars.host_aoip_tla := "::6";
5853 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005854 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005855}
5856
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005857/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005858 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005859 channel is later released (RR CHannel Release), should trigger inclusion of
5860 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5861 neighbors. */
5862testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5863 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5864 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005865 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005866 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005867
5868 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5869 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5870 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005871 f_shutdown_helper();
5872}
5873
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005874/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5875 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5876 list when the channel is released. */
5877testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5878 f_init_vty();
5879 f_vty_allow_srvcc_fast_return(true, 0)
5880
5881 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5882 pars.last_used_eutran_plmn := '323454'O;
5883 pars.exp_fast_return := false;
5884 f_tc_ho_into_this_bsc_main(pars);
5885 f_vty_allow_srvcc_fast_return(false, 0);
5886 f_shutdown_helper();
5887}
5888
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005889private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5890 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5891 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5892 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5893 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5894 setverdict(pass);
5895}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005896
5897private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5898 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005899 var MSC_ConnHdlr vc_conn;
5900 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5901
5902 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005903 if (disable_fast_return) {
5904 f_vty_allow_srvcc_fast_return(true, 0);
5905 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005906 f_sleep(1.0);
5907
5908 f_ctrs_bsc_and_bts_init();
5909
5910 pars.last_used_eutran_plmn := '323454'O;
5911 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5912 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5913
5914 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5915 vc_conn.done;
5916
5917 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5918 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5919 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5920 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5921 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5922 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005923
5924 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5925 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005926 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005927
5928 if (disable_fast_return) {
5929 f_vty_allow_srvcc_fast_return(false, 0);
5930 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005931 f_shutdown_helper();
5932}
5933
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005934/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5935 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5936 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5937 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5938testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5939 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5940}
5941/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5942 * independently of fast-reture allowed/forbidden in local BTS */
5943testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5944 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5945}
5946
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005947private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5948 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5949 f_rslem_register(0, new_chan_nr);
5950 g_chan_nr := new_chan_nr;
5951 f_sleep(1.0);
5952
5953 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5954 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5955 activate(as_Media());
5956
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005957 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005958 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005959 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005960
5961 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5962
5963 var PDU_BSSAP rx_bssap;
5964 var octetstring ho_command_str;
5965
5966 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5967
5968 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5969 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5970 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5971 log("L3 Info in HO Request Ack is ", ho_command);
5972
5973 var GsmArfcn arfcn;
5974 var RslChannelNr actual_new_chan_nr;
5975 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5976 actual_new_chan_nr, arfcn);
5977
5978 if (actual_new_chan_nr != new_chan_nr) {
5979 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5980 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5981 setverdict(fail);
5982 return;
5983 }
5984 log("Handover Command chan_nr is", actual_new_chan_nr);
5985
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005986 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5987 f_sleep(1.0);
5988
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005989 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5990 * tells the MS to handover to the new lchan. In this case, the MS
5991 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5992 * Handover Failure to the MSC. The procedure according to 3GPP TS
5993 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5994 * BSSMAP Clear Command: */
5995
5996 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5997 var BssmapCause cause := enum2int(cause_val);
5998 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5999
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006000 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006001 BSSAP.receive(tr_BSSMAP_ClearComplete);
6002
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006003 setverdict(pass);
6004 f_sleep(1.0);
6005
6006 setverdict(pass);
6007}
6008testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6009 var MSC_ConnHdlr vc_conn;
6010 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6011
6012 f_init(1, true);
6013 f_sleep(1.0);
6014
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006015 f_ctrs_bsc_and_bts_init();
6016
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006017 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6018 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006019
6020 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6021 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006022
6023 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6024 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6025 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6026 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6027 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006028 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006029}
6030
6031private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6032 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6033 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6034 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6035 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6036 * before we get started. */
6037 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6038 f_rslem_register(0, new_chan_nr);
6039 g_chan_nr := new_chan_nr;
6040 f_sleep(1.0);
6041
6042 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6043 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6044 activate(as_Media());
6045
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006046 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006047 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006048 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006049
6050 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6051
6052 var PDU_BSSAP rx_bssap;
6053 var octetstring ho_command_str;
6054
6055 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6056
6057 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6058 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6059 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6060 log("L3 Info in HO Request Ack is ", ho_command);
6061
6062 var GsmArfcn arfcn;
6063 var RslChannelNr actual_new_chan_nr;
6064 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6065 actual_new_chan_nr, arfcn);
6066
6067 if (actual_new_chan_nr != new_chan_nr) {
6068 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6069 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6070 setverdict(fail);
6071 return;
6072 }
6073 log("Handover Command chan_nr is", actual_new_chan_nr);
6074
6075 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6076 * tells the MS to handover to the new lchan. Here comes the new MS on
6077 * the new lchan with a Handover RACH: */
6078
6079 /* send handover detect */
6080
6081 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6082
6083 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6084
6085 /* The MSC chooses to clear the connection now, maybe we got the
6086 * Handover RACH on the new cell but the MS still signaled Handover
6087 * Failure to the old BSS? */
6088
6089 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6090 var BssmapCause cause := enum2int(cause_val);
6091 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6092
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006093 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006094 BSSAP.receive(tr_BSSMAP_ClearComplete);
6095
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006096 f_sleep(1.0);
6097}
6098testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6099 var MSC_ConnHdlr vc_conn;
6100 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6101
6102 f_init(1, true);
6103 f_sleep(1.0);
6104
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006105 f_ctrs_bsc_and_bts_init();
6106
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006107 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6108 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006109
6110 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6111 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006112
6113 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6114 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6115 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6116 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6117 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006118 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006119}
6120
6121/* The new BSS's lchan times out before the MSC decides that handover failed. */
6122private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6123 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6124 f_rslem_register(0, new_chan_nr);
6125 g_chan_nr := new_chan_nr;
6126 f_sleep(1.0);
6127
6128 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6129 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6130 activate(as_Media());
6131
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006132 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006133 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006134 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006135
6136 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6137
6138 var PDU_BSSAP rx_bssap;
6139 var octetstring ho_command_str;
6140
6141 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6142
6143 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6144 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6145 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6146 log("L3 Info in HO Request Ack is ", ho_command);
6147
6148 var GsmArfcn arfcn;
6149 var RslChannelNr actual_new_chan_nr;
6150 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6151 actual_new_chan_nr, arfcn);
6152
6153 if (actual_new_chan_nr != new_chan_nr) {
6154 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6155 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6156 setverdict(fail);
6157 return;
6158 }
6159 log("Handover Command chan_nr is", actual_new_chan_nr);
6160
6161 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6162 * tells the MS to handover to the new lchan. But the MS never shows up
6163 * on the new lchan. */
6164
6165 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6166
6167 /* Did osmo-bsc also send a Clear Request? */
6168 timer T := 0.5;
6169 T.start;
6170 alt {
6171 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6172 [] T.timeout { }
6173 }
6174
6175 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6176 * asked for it, this is a Handover Failure after all). */
6177
6178 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6179 var BssmapCause cause := enum2int(cause_val);
6180 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6181
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006182 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006183 BSSAP.receive(tr_BSSMAP_ClearComplete);
6184
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006185 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006186}
6187testcase TC_ho_in_fail_no_detect() runs on test_CT {
6188 var MSC_ConnHdlr vc_conn;
6189 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6190
6191 f_init(1, true);
6192 f_sleep(1.0);
6193
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006194 f_ctrs_bsc_and_bts_init();
6195
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006196 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6197 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006198
6199 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6200 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006201
6202 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6203 f_ctrs_bsc_and_bts_add(0, "handover:error");
6204 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6205 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6206 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006207 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006208}
6209
6210/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6211private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6212 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6213 f_rslem_register(0, new_chan_nr);
6214 g_chan_nr := new_chan_nr;
6215 f_sleep(1.0);
6216
6217 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6218 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6219 activate(as_Media());
6220
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006221 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006222 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006223 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006224
6225 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6226
6227 var PDU_BSSAP rx_bssap;
6228 var octetstring ho_command_str;
6229
6230 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6231
6232 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6233 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6234 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6235 log("L3 Info in HO Request Ack is ", ho_command);
6236
6237 var GsmArfcn arfcn;
6238 var RslChannelNr actual_new_chan_nr;
6239 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6240 actual_new_chan_nr, arfcn);
6241
6242 if (actual_new_chan_nr != new_chan_nr) {
6243 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6244 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6245 setverdict(fail);
6246 return;
6247 }
6248 log("Handover Command chan_nr is", actual_new_chan_nr);
6249
6250 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6251 * tells the MS to handover to the new lchan. But the MS never shows up
6252 * on the new lchan. */
6253
6254 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6255
6256 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006257 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006258
6259 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006260 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6261 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6262 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006263 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006264 BSSAP.receive(tr_BSSMAP_ClearComplete);
6265
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006266 f_sleep(1.0);
6267}
6268testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6269 var MSC_ConnHdlr vc_conn;
6270 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6271
6272 f_init(1, true);
6273 f_sleep(1.0);
6274
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006275 f_ctrs_bsc_and_bts_init();
6276
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006277 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6278 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006279
6280 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6281 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006282
6283 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6284 f_ctrs_bsc_and_bts_add(0, "handover:error");
6285 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6286 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6287 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006288 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006289}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006290
Neels Hofmeyr91401012019-07-11 00:42:35 +02006291type record of charstring Commands;
6292
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006293private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006294{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006295 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006296 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006297 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006298 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006299 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006300}
6301
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006302private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6303{
6304 f_vty_enter_cfg_cs7_inst(pt, 0);
6305 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6306 f_vty_transceive(pt, cmds[i]);
6307 }
6308 f_vty_transceive(pt, "end");
6309}
6310
Neels Hofmeyr91401012019-07-11 00:42:35 +02006311private function f_probe_for_handover(charstring log_label,
6312 charstring log_descr,
6313 charstring handover_vty_cmd,
6314 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006315 boolean is_inter_bsc_handover := false,
6316 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006317runs on MSC_ConnHdlr
6318{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006319 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6320 * lchans to be established on bts 1 or bts 2. */
6321 f_rslem_suspend(RSL1_PROC);
6322 f_rslem_suspend(RSL2_PROC);
6323
Neels Hofmeyr91401012019-07-11 00:42:35 +02006324 var RSL_Message rsl;
6325
6326 var charstring log_msg := " (expecting handover)"
6327 if (not expect_handover) {
6328 log_msg := " (expecting NO handover)";
6329 }
6330 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6331 f_vty_transceive(BSCVTY, handover_vty_cmd);
6332
Neels Hofmeyr91401012019-07-11 00:42:35 +02006333 timer T := 2.0;
6334 T.start;
6335
6336 alt {
6337 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6338 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6339 log("Rx L3 from net: ", l3);
6340 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6341 var RslChannelNr new_chan_nr;
6342 var GsmArfcn arfcn;
6343 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6344 new_chan_nr, arfcn);
6345 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6346 log(l3.msgs.rrm.handoverCommand);
6347
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006348 /* Verify correct TSC in handoverCommand */
6349 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6350 if (not match(got_tsc, expect_target_tsc)) {
6351 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6352 expect_target_tsc, " got ", got_tsc);
6353 mtc.stop;
6354 } else {
6355 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6356 expect_target_tsc, ")");
6357 }
6358
Neels Hofmeyr91401012019-07-11 00:42:35 +02006359 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6360 * matter on which BTS it really is, we're not going to follow through an entire handover
6361 * anyway. */
6362 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6363 f_rslem_resume(RSL1_PROC);
6364 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6365 f_rslem_resume(RSL2_PROC);
6366
6367 if (expect_handover and not is_inter_bsc_handover) {
6368 setverdict(pass);
6369 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6370 } else {
6371 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6372 & log_label & ": " & log_descr);
6373 }
6374
6375 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6376 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6377 * Handover Failure. */
6378 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6379
6380 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6381 f_sleep(0.5);
6382 RSL1.clear;
6383 RSL2.clear;
6384 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6385 break;
6386 } else {
6387 repeat;
6388 }
6389 }
6390 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6391 if (expect_handover and is_inter_bsc_handover) {
6392 setverdict(pass);
6393 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6394 } else {
6395 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6396 & log_label & ": " & log_descr);
6397 }
6398
6399 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6400
6401 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6402 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6403 * setting a short timeout and waiting is the only way. */
6404 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6405 f_sleep(1.5);
6406 log("f_probe_for_handover(" & log_label & "): ...done");
6407
6408 break;
6409 }
6410 [] T.timeout {
6411 if (expect_handover) {
6412 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6413 & log_label & ": " & log_descr);
6414 } else {
6415 setverdict(pass);
6416 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6417 }
6418 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6419 break;
6420 }
6421 }
6422
6423 f_rslem_resume(RSL1_PROC);
6424 f_rslem_resume(RSL2_PROC);
6425 f_sleep(3.0);
6426 RSL.clear;
6427
6428 log("f_probe_for_handover(" & log_label & "): done clearing");
6429}
6430
6431/* Test the effect of various neighbor configuration scenarios:
6432 *
6433 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6434 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6435 */
6436private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6437 g_pars := f_gen_test_hdlr_pars();
6438 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6439 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006440
6441 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6442 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6443
6444 /* Establish lchan at bts 0 */
6445 f_establish_fully(ass_cmd, exp_compl);
6446
6447 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6448 f_vty_enter_cfg_network(BSCVTY);
6449 f_vty_transceive(BSCVTY, "timer T7 1");
6450 f_vty_transceive(BSCVTY, "end");
6451}
6452
6453private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6454 f_tc_ho_neighbor_config_start();
6455
6456 /*
6457 * bts 0 ARFCN 871 BSIC 10
6458 * bts 1 ARFCN 871 BSIC 11
6459 * bts 2 ARFCN 871 BSIC 12
6460 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6461 */
6462
6463 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006464 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006465 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6466 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006467 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006468
6469 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6470 "handover any to arfcn 13 bsic 39",
6471 false);
6472
6473 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6474 "handover any to arfcn 871 bsic 12",
6475 false);
6476
6477 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6478 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006479 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006480}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006481testcase TC_ho_neighbor_config_1() runs on test_CT {
6482 var MSC_ConnHdlr vc_conn;
6483 f_init(3, true, guard_timeout := 60.0);
6484 f_sleep(1.0);
6485 f_ctrs_bsc_and_bts_init();
6486 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6487 vc_conn.done;
6488
6489 /* f_tc_ho_neighbor_config_start() */
6490 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6491 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6492
6493 /* 1.a */
6494 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6495 * handover quickly by sending a Handover Failure message. */
6496 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6497 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6498 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6499 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6500
6501 /* 1.b */
6502 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6503 f_ctrs_bsc_and_bts_add(0, "handover:error");
6504
6505 /* 1.c */
6506 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6507 f_ctrs_bsc_and_bts_add(0, "handover:error");
6508
6509 /* 1.d */
6510 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6511 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6512 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6513 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6514
6515 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006516 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006517}
6518
Neels Hofmeyr91401012019-07-11 00:42:35 +02006519private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6520 f_tc_ho_neighbor_config_start();
6521
6522 /*
6523 * bts 0 ARFCN 871 BSIC 10
6524 * bts 1 ARFCN 871 BSIC 11
6525 * bts 2 ARFCN 871 BSIC 12
6526 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6527 */
6528
6529 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006530 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006531 f_sleep(0.5);
6532
6533 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6534 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006535 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006536
6537 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6538 "handover any to arfcn 871 bsic 12",
6539 false);
6540}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006541testcase TC_ho_neighbor_config_2() runs on test_CT {
6542 var MSC_ConnHdlr vc_conn;
6543 f_init(3, true, guard_timeout := 50.0);
6544 f_sleep(1.0);
6545 f_ctrs_bsc_and_bts_init();
6546 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6547 vc_conn.done;
6548
6549 /* f_tc_ho_neighbor_config_start() */
6550 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6551 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6552
6553 /* 2.a */
6554 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6555 * handover quickly by sending a Handover Failure message. */
6556 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6557 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6558 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6559 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6560
6561 /* 2.b */
6562 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6563 f_ctrs_bsc_and_bts_add(0, "handover:error");
6564
6565 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006566 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006567}
6568
Neels Hofmeyr91401012019-07-11 00:42:35 +02006569private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6570 f_tc_ho_neighbor_config_start();
6571
6572 /*
6573 * bts 0 ARFCN 871 BSIC 10
6574 * bts 1 ARFCN 871 BSIC 11
6575 * bts 2 ARFCN 871 BSIC 12
6576 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6577 */
6578
6579 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006580 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006581 f_sleep(0.5);
6582
6583 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6584 "handover any to arfcn 871 bsic 11",
6585 false);
6586 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",
6587 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006588 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006589}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006590testcase TC_ho_neighbor_config_3() runs on test_CT {
6591 var MSC_ConnHdlr vc_conn;
6592 f_init(3, true, guard_timeout := 50.0);
6593 f_sleep(1.0);
6594 f_ctrs_bsc_and_bts_init();
6595 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6596 vc_conn.done;
6597
6598 /* f_tc_ho_neighbor_config_start() */
6599 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6600 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6601
6602 /* 3.a */
6603 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6604 f_ctrs_bsc_and_bts_add(0, "handover:error");
6605
6606 /* 3.b */
6607 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6608 * handover quickly by sending a Handover Failure message. */
6609 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6610 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6611 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6612 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6613
6614 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006615 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006616}
6617
Neels Hofmeyr91401012019-07-11 00:42:35 +02006618private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6619 f_tc_ho_neighbor_config_start();
6620
6621 /*
6622 * bts 0 ARFCN 871 BSIC 10
6623 * bts 1 ARFCN 871 BSIC 11
6624 * bts 2 ARFCN 871 BSIC 12
6625 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6626 */
6627
6628 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006629 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006630 f_sleep(0.5);
6631
6632 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6633 "handover any to arfcn 871 bsic 11",
6634 false);
6635 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6636 "handover any to arfcn 871 bsic 12",
6637 false);
6638 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6639 "handover any to arfcn 123 bsic 45",
6640 true, true);
6641}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006642testcase TC_ho_neighbor_config_4() runs on test_CT {
6643 var MSC_ConnHdlr vc_conn;
6644 f_init(3, true, guard_timeout := 50.0);
6645 f_sleep(1.0);
6646 f_ctrs_bsc_and_bts_init();
6647 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6648 vc_conn.done;
6649
6650 /* f_tc_ho_neighbor_config_start() */
6651 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6652 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6653
6654 /* 4.a */
6655 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6656 f_ctrs_bsc_and_bts_add(0, "handover:error");
6657
6658 /* 4.b */
6659 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6660 f_ctrs_bsc_and_bts_add(0, "handover:error");
6661
6662 /* 4.c */
6663 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6664 * handover quickly by timing out after the Handover Required message */
6665 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6666 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6667 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6668 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6669
6670 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006671 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006672}
6673
Neels Hofmeyr91401012019-07-11 00:42:35 +02006674private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6675 f_tc_ho_neighbor_config_start();
6676
6677 /*
6678 * bts 0 ARFCN 871 BSIC 10
6679 * bts 1 ARFCN 871 BSIC 11
6680 * bts 2 ARFCN 871 BSIC 12
6681 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6682 */
6683
6684 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 +02006685 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006686 f_sleep(0.5);
6687
6688 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6689 "handover any to arfcn 871 bsic 12",
6690 true, true);
6691}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006692testcase TC_ho_neighbor_config_5() runs on test_CT {
6693 var MSC_ConnHdlr vc_conn;
6694 f_init(3, true);
6695 f_sleep(1.0);
6696 f_ctrs_bsc_and_bts_init();
6697 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6698 vc_conn.done;
6699
6700 /* f_tc_ho_neighbor_config_start() */
6701 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6702 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6703
6704 /* 5 */
6705 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6706 * handover quickly by timing out after the Handover Required message */
6707 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6708 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6709 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6710 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6711
6712 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006713 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006714}
6715
Neels Hofmeyr91401012019-07-11 00:42:35 +02006716private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6717 f_tc_ho_neighbor_config_start();
6718
6719 /*
6720 * bts 0 ARFCN 871 BSIC 10
6721 * bts 1 ARFCN 871 BSIC 11
6722 * bts 2 ARFCN 871 BSIC 12
6723 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6724 */
6725
6726 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6727 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006728 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006729 f_sleep(0.5);
6730
6731 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6732 "handover any to arfcn 871 bsic 12",
6733 false);
6734}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006735testcase TC_ho_neighbor_config_6() runs on test_CT {
6736 var MSC_ConnHdlr vc_conn;
6737 f_init(3, true);
6738 f_sleep(1.0);
6739 f_ctrs_bsc_and_bts_init();
6740 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6741 vc_conn.done;
6742
6743 /* f_tc_ho_neighbor_config_start() */
6744 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6745 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6746
6747 /* 6.a */
6748 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6749 * handover quickly by timing out after the Handover Required message */
6750 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6751 f_ctrs_bsc_and_bts_add(0, "handover:error");
6752
6753 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006754 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006755}
6756
Neels Hofmeyr91401012019-07-11 00:42:35 +02006757private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6758 f_tc_ho_neighbor_config_start();
6759
6760 /*
6761 * bts 0 ARFCN 871 BSIC 10
6762 * bts 1 ARFCN 871 BSIC 11
6763 * bts 2 ARFCN 871 BSIC 12
6764 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6765 */
6766
6767 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6768 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006769 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006770 f_sleep(0.5);
6771
6772 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6773 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006774 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006775 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6776 "handover any to arfcn 123 bsic 45",
6777 true, true);
6778}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006779testcase TC_ho_neighbor_config_7() runs on test_CT {
6780 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006781 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006782 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006783 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006784 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6785 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006786
6787 /* f_tc_ho_neighbor_config_start() */
6788 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6789 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6790
6791 /* 7.a */
6792 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6793 * handover quickly by sending a Handover Failure message. */
6794 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6795 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6796 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6797 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6798
6799 /* 7.b */
6800 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6801 * handover quickly by timing out after the Handover Required message */
6802 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6803 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6804 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6805 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6806
6807 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006808 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006809}
6810
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006811/* OS#3041: Open and close N connections in a normal fashion, and expect no
6812 * BSSMAP Reset just because of that. */
6813testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6814 var default d;
6815 var integer i;
6816 var DchanTuple dt;
6817
6818 f_init();
6819
6820 /* Wait for initial BSSMAP Reset to pass */
6821 f_sleep(4.0);
6822
6823 d := activate(no_bssmap_reset());
6824
6825 /* Setup up a number of connections and RLSD them again from the MSC
6826 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6827 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006828 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006829 /* Since we're doing a lot of runs, give each one a fresh
6830 * T_guard from the top. */
6831 T_guard.start;
6832
6833 /* Setup a BSSAP connection and clear it right away. This is
6834 * the MSC telling the BSC about a planned release, it's not an
6835 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006836 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006837
6838 /* MSC disconnects (RLSD). */
6839 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6840 }
6841
6842 /* In the buggy behavior, a timeout of 2 seconds happens between above
6843 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6844 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6845 f_sleep(4.0);
6846
6847 deactivate(d);
6848 f_shutdown_helper();
6849}
Harald Welte552620d2017-12-16 23:21:36 +01006850
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006851/* OS#3041: Open and close N connections in a normal fashion, and expect no
6852 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6853 * the MSC. */
6854testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6855 var default d;
6856 var integer i;
6857 var DchanTuple dt;
6858 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006859 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6860 var BssmapCause cause := enum2int(cause_val);
6861
6862 f_init();
6863
6864 /* Wait for initial BSSMAP Reset to pass */
6865 f_sleep(4.0);
6866
6867 d := activate(no_bssmap_reset());
6868
6869 /* Setup up a number of connections and RLSD them again from the MSC
6870 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6871 * Let's do it some more times for good measure. */
6872 for (i := 0; i < 8; i := i+1) {
6873 /* Since we're doing a lot of runs, give each one a fresh
6874 * T_guard from the top. */
6875 T_guard.start;
6876
6877 /* Setup a BSSAP connection and clear it right away. This is
6878 * the MSC telling the BSC about a planned release, it's not an
6879 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006880 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006881
6882 /* Instruct BSC to clear channel */
6883 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6884
6885 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006886 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006887 }
6888
6889 /* In the buggy behavior, a timeout of 2 seconds happens between above
6890 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6891 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6892 f_sleep(4.0);
6893
6894 deactivate(d);
6895 f_shutdown_helper();
6896}
6897
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006898/* OS#3041: Open and close N connections in a normal fashion, and expect no
6899 * BSSMAP Reset just because of that. Close connections from the MS side with a
6900 * Release Ind on RSL. */
6901testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6902 var default d;
6903 var integer i;
6904 var DchanTuple dt;
6905 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006906 var integer j;
6907
6908 f_init();
6909
6910 /* Wait for initial BSSMAP Reset to pass */
6911 f_sleep(4.0);
6912
6913 d := activate(no_bssmap_reset());
6914
6915 /* Setup up a number of connections and RLSD them again from the MSC
6916 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6917 * Let's do it some more times for good measure. */
6918 for (i := 0; i < 8; i := i+1) {
6919 /* Since we're doing a lot of runs, give each one a fresh
6920 * T_guard from the top. */
6921 T_guard.start;
6922
6923 /* Setup a BSSAP connection and clear it right away. This is
6924 * the MSC telling the BSC about a planned release, it's not an
6925 * erratic loss of a connection. */
6926 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6927
6928 /* simulate RLL REL IND */
6929 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6930
6931 /* expect Clear Request on MSC side */
6932 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6933
6934 /* Instruct BSC to clear channel */
6935 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6936 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6937
6938 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006939 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006940 }
6941
6942 /* In the buggy behavior, a timeout of 2 seconds happens between above
6943 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6944 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6945 f_sleep(4.0);
6946
6947 deactivate(d);
6948 f_shutdown_helper();
6949}
6950
Harald Welte94e0c342018-04-07 11:33:23 +02006951/***********************************************************************
6952 * IPA style dynamic PDCH
6953 ***********************************************************************/
6954
6955private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6956 template (omit) RSL_Cause nack := omit)
6957runs on test_CT {
6958 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6959 var RSL_Message rsl_unused;
6960 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6961 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6962 /* expect the BSC to issue the related RSL command */
6963 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6964 if (istemplatekind(nack, "omit")) {
6965 /* respond with a related acknowledgement */
6966 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6967 } else {
6968 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6969 }
6970}
6971
6972private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6973 template (omit) RSL_Cause nack := omit)
6974runs on test_CT {
6975 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6976 var RSL_Message rsl_unused;
6977 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6978 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6979 /* expect the BSC to issue the related RSL command */
6980 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6981 if (istemplatekind(nack, "omit")) {
6982 /* respond with a related acknowledgement */
6983 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6984 } else {
6985 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6986 }
6987}
6988
6989private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6990runs on test_CT return charstring {
6991 var charstring cmd, resp;
6992 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006993 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006994}
6995
6996private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6997 template charstring exp)
6998runs on test_CT {
6999 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7000 if (not match(mode, exp)) {
7001 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007002 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007003 }
7004}
7005
7006private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7007runs on test_CT {
7008 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7009 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7010 f_vty_transceive(BSCVTY, "end");
7011}
7012
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007013
7014private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7015 var integer i;
7016 for (i := 0; i < 8; i := i + 1) {
7017 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7018 }
7019}
7020
Harald Welte94e0c342018-04-07 11:33:23 +02007021private const charstring TCHF_MODE := "TCH/F mode";
7022private const charstring TCHH_MODE := "TCH/H mode";
7023private const charstring PDCH_MODE := "PDCH mode";
7024private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007025private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007026
7027/* Test IPA PDCH activation / deactivation triggered by VTY */
7028testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7029 var RSL_Message rsl_unused;
7030
7031 /* change Timeslot 6 before f_init() starts RSL */
7032 f_init_vty();
7033 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7034 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7035
7036 f_init(1, false);
7037 f_sleep(1.0);
7038
7039 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7040
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007041 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007042 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7043 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7044 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7045 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7046 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007047 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007048 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7049
7050 /* De-activate it via VTY */
7051 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7052 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007053 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007054 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7055
7056 /* re-activate it via VTY */
7057 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7058 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007059 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007060 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7061
7062 /* and finally de-activate it again */
7063 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7064 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007065 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007066 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7067
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007068 /* clean up config */
7069 f_ts_set_chcomb(0, 0, 6, "PDCH");
7070
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007071 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007072}
7073
7074/* Test IPA PDCH activation NACK */
7075testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7076 var RSL_Message rsl_unused;
7077
7078 /* change Timeslot 6 before f_init() starts RSL */
7079 f_init_vty();
7080 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7081 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7082
7083 f_init(1, false);
7084 f_sleep(1.0);
7085
7086 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7087
7088 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7089 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7090 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7091 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7092 f_sleep(1.0);
7093 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7094
7095 /* De-activate it via VTY */
7096 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7097 f_sleep(1.0);
7098 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7099
7100 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7101 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7102 f_sleep(1.0);
7103 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7104
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007105 /* clean up config */
7106 f_ts_set_chcomb(0, 0, 6, "PDCH");
7107
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007108 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007109}
7110
7111
7112/***********************************************************************
7113 * Osmocom style dynamic PDCH
7114 ***********************************************************************/
7115
7116private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7117 template (omit) RSL_Cause nack := omit)
7118runs on test_CT {
7119 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7120 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007121 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007122 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7123 /* expect the BSC to issue the related RSL command */
7124 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7125 if (istemplatekind(nack, "omit")) {
7126 /* respond with a related acknowledgement */
7127 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7128 } else {
7129 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7130 }
7131}
7132
7133private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7134 template (omit) RSL_Cause nack := omit)
7135runs on test_CT {
7136 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7137 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007138 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007139 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7140 /* expect the BSC to issue the related RSL command */
7141 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7142 if (istemplatekind(nack, "omit")) {
7143 /* respond with a related acknowledgement */
7144 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7145 } else {
7146 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7147 }
7148}
7149
7150/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7151testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7152 var RSL_Message rsl_unused;
7153
7154 /* change Timeslot 6 before f_init() starts RSL */
7155 f_init_vty();
7156 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7157 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7158
7159 f_init(1, false);
7160 f_sleep(1.0);
7161
7162 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7163
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007164 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007165 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7166 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7167 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7168
7169 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7170 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007171 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 +02007172 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7173
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007174 /* clean up config */
7175 f_ts_set_chcomb(0, 0, 6, "PDCH");
7176
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007177 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007178}
7179
7180/* Test Osmocom dyn PDCH activation NACK behavior */
7181testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7182 var RSL_Message rsl_unused;
7183
7184 /* change Timeslot 6 before f_init() starts RSL */
7185 f_init_vty();
7186 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7187 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7188
7189 f_init(1, false);
7190 f_sleep(1.0);
7191
7192 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7193
7194 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7195 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7196 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7197
7198 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7199 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7200 f_sleep(1.0);
7201 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7202
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007203 /* clean up config */
7204 f_ts_set_chcomb(0, 0, 6, "PDCH");
7205
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007206 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007207}
7208
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007209/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7210testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7211 var RSL_Message rsl_unused, rsl_msg;
7212 var DchanTuple dt;
7213 var BSSAP_N_CONNECT_ind rx_c_ind;
7214
7215 /* change Timeslot 6 before f_init() starts RSL */
7216 f_init_vty();
7217 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7218 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7219
7220 f_init(1, false);
7221 f_sleep(1.0);
7222
7223 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7224
7225 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7226 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7227 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7228 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7229
7230 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7231 f_sleep(1.0);
7232 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7233 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7234
7235 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7236 * on CCCH+SDCCH4+CBCH) */
7237 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007238 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007239 dt := f_est_dchan('23'O, i, '00010203040506'O);
7240 }
7241
7242 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7243 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7244 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7245 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7246
7247 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7248 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7249
7250 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7251 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7252 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7253 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7254
7255 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7256 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7257 dt.sccp_conn_id := rx_c_ind.connectionId;
7258 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7259
7260 /* Instruct BSC to clear channel */
7261 var BssmapCause cause := 0;
7262 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7263 f_exp_chan_rel_and_clear(dt, 0);
7264
7265 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7266 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7267 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7268 f_sleep(1.0);
7269 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7270
7271 /* clean up config */
7272 f_ts_set_chcomb(0, 0, 6, "PDCH");
7273
7274 f_shutdown_helper();
7275}
7276
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007277/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7278testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7279 var ASP_RSL_Unitdata rsl_ud;
7280 var integer i;
7281 var integer chreq_total, chreq_nochan;
7282
7283 f_init_vty();
7284 for (i := 1; i < 8; i := i + 1) {
7285 if (i == 2) {
7286 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7287 } else {
7288 f_ts_set_chcomb(0, 0, i, "PDCH");
7289 }
7290 }
7291 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7292
7293 f_init(1);
7294
7295 /* The dyn TS want to activate PDCH mode, ACK that. */
7296 var RslChannelNr chan_nr;
7297 chan_nr := valueof(t_RslChanNr_PDCH(2));
7298 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7299 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7300
7301 f_sleep(1.0);
7302
7303 /* Exhaust all dedicated SDCCH lchans.
7304 /* GSM 44.018 Table 9.1.8.2:
7305 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7306 */
7307 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
7308 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7309 }
7310
7311 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
7312 f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7313 /* Also occupy the seven other SDCCH of the dyn TS */
7314 for (i := 0; i < 7; i := i+1) {
7315 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
7316 }
7317
7318 /* clean up config */
7319 f_ts_reset_chcomb(0);
7320
7321 f_shutdown_helper();
7322}
7323
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007324/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7325 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7326 it as TCH directly instead. SYS#5309. */
7327testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7328 var RSL_Message rsl_unused, rsl_msg;
7329 var DchanTuple dt;
7330 var BSSAP_N_CONNECT_ind rx_c_ind;
7331 var integer i;
7332
7333 /* change Timeslot 6 before f_init() starts RSL */
7334 f_init_vty();
7335 for (i := 1; i < 8; i := i + 1) {
7336 if (i == 6) {
7337 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7338 } else {
7339 f_ts_set_chcomb(0, 0, i, "PDCH");
7340 }
7341 }
7342 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7343
7344 f_init(1, false);
7345 f_sleep(1.0);
7346
7347 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7348
7349 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7350 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7351 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7352 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7353
7354 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7355 f_sleep(1.0);
7356 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7357 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7358
7359 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7360 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007361 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007362 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007363 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007364 }
7365
7366 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007367 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007368 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7369 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7370
7371 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7372 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7373
7374 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7375 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7376 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7377 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7378
7379 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7380 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7381 dt.sccp_conn_id := rx_c_ind.connectionId;
7382 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7383
7384 /* Instruct BSC to clear channel */
7385 var BssmapCause cause := 0;
7386 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7387 f_exp_chan_rel_and_clear(dt, 0);
7388
7389 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7390 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7391 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7392 f_sleep(1.0);
7393 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7394
7395 /* clean up config */
7396 f_ts_reset_chcomb(0);
7397 /* TODO: clean up other channels? */
7398
7399 f_shutdown_helper();
7400}
7401
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007402/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7403testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7404 var RSL_Message rsl_unused, rsl_msg;
7405 var DchanTuple dt;
7406 var BSSAP_N_CONNECT_ind rx_c_ind;
7407 var GsmRrMessage rr;
7408
7409 /* change Timeslot 6 before f_init() starts RSL */
7410 f_init_vty();
7411 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7412 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7413
7414 f_init(1, false);
7415 f_sleep(1.0);
7416
7417 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7418
7419 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7420 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7421 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7422 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7423
7424 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7425 f_sleep(1.0);
7426 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7427 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7428
7429 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7430 * on CCCH+SDCCH4+CBCH) */
7431 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007432 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007433 dt := f_est_dchan('23'O, i, '00010203040506'O);
7434 }
7435
7436 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7437 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7438 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7439 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7440
7441 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7442 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7443
7444 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7445 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7446 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7447 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7448 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7449 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7450 }
7451
7452 /* FIXME? Currently the TS stays in state BORKEN: */
7453
7454 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7455 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7456 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7457 * f_sleep(1.0);
7458 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7459 */
7460
7461 /* clean up config */
7462 f_ts_set_chcomb(0, 0, 6, "PDCH");
7463
7464 f_shutdown_helper();
7465}
7466
Stefan Sperling0796a822018-10-05 13:01:39 +02007467testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007468 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007469 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7470 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7471 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007472 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007473}
7474
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007475testcase TC_chopped_ipa_payload() runs on test_CT {
7476 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7477 /* TODO: mp_bsc_ctrl_port does not work yet */};
7478 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7479 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7480 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007481 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007482}
7483
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007484/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7485 the BTS does autonomous MS power control loop */
7486testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7487 var MSC_ConnHdlr vc_conn;
7488 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7489 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7490 pars.exp_ms_power_params := true;
7491
7492 f_init(1, true);
7493 f_sleep(1.0);
7494 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7495 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007496 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007497}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007498
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007499/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7500testcase TC_c0_power_red_mode() runs on test_CT {
7501 f_init(1);
7502
7503 for (var integer red := 6; red >= 0; red := red - 2) {
7504 /* Configure BCCH carrier power reduction mode via the VTY */
7505 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7506
7507 /* Expect Osmocom specific BS Power Control message on the RSL */
7508 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7509 chan_nr := t_RslChanNr_BCCH(0),
7510 bs_power := tr_RSL_IE_BS_Power(red / 2));
7511 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7512 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7513
7514 /* Additionally verify the applied value over the CTRL interface */
7515 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7516 if (cred != int2str(red)) {
7517 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7518 cred, " (expected ", red, ")");
7519 }
7520 }
7521
7522 f_shutdown_helper();
7523}
7524
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007525/***********************************************************************
7526 * MSC Pooling
7527 ***********************************************************************/
7528
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007529template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007530 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 +02007531
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007532private 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 +02007533runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007534 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007535 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007536 f_logp(BSCVTY, "Got RSL RR Release");
7537 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007538 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007539 f_logp(BSCVTY, "Got RSL Deact SACCH");
7540 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007541 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007542 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007543 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7544 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007545 break;
7546 }
7547 }
7548}
7549
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007550friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7551 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007552runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007553 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007554 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7555 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007556 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007557 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007558 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007559 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007560 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007561 }
7562 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007563 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007564 /* Also drop the SCCP connection */
7565 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7566 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007567 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007568 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007569 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7570 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007571 }
7572 }
7573}
7574
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007575private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7576 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007577runs on MSC_ConnHdlr {
7578 timer T := 10.0;
7579 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7580
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007581 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007582 f_create_bssmap_exp(l3_enc);
7583
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007584 /* RSL_Emulation.f_chan_est() on rsl_pt:
7585 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007586 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7587 */
7588 var RSL_Message rx_rsl;
7589 var GsmRrMessage rr;
7590
7591 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007592 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007593 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007594 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007595 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7596 */
7597 timer Tt := 10.0;
7598
7599 /* request a channel to be established */
7600 Tt.start;
7601 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007602 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007603 Tt.stop;
7604 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007605 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007606 setverdict(fail, "Unexpected RSL message on DCHAN");
7607 mtc.stop;
7608 }
7609 [] Tt.timeout {
7610 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7611 mtc.stop;
7612 }
7613 }
7614 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7615 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007616 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007617
7618
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007619 if (expect_bssmap_l3) {
7620 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7621 var template PDU_BSSAP exp_l3_compl;
7622 exp_l3_compl := tr_BSSMAP_ComplL3()
7623 if (g_pars.aoip == false) {
7624 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7625 } else {
7626 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7627 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007628
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007629 var PDU_BSSAP bssap;
7630 T.start;
7631 alt {
7632 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7633 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7634 log("rx exp_l3_compl = ", bssap);
7635 }
7636 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7637 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7638 }
7639 [] T.timeout {
7640 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7641 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007642 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007643
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007644 /* start ciphering, if requested */
7645 if (ispresent(g_pars.encr)) {
7646 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007647 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007648 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007649 }
7650
7651 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007652 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007653 }
7654 setverdict(pass);
7655 f_sleep(1.0);
7656}
7657
7658private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7659 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7660 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007661 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007662 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007663 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007664 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007665 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007666 }
7667}
7668
7669/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7670private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7671 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007672 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7673 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7674 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7675 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 +02007676}
7677testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7678
7679 f_init(1, true);
7680 f_sleep(1.0);
7681 var MSC_ConnHdlr vc_conn;
7682 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007683
7684 f_ctrs_msc_init();
7685
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007686 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7687 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007688
7689 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007690 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007691}
7692
7693/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7694/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7695 * just as well using only RSL. */
7696testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7697
7698 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7699 f_sleep(1.0);
7700
7701 /* Control which MSC gets chosen next by the round-robin, otherwise
7702 * would be randomly affected by which other tests ran before this. */
7703 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7704
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007705 f_ctrs_msc_init();
7706
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007707 var MSC_ConnHdlr vc_conn1;
7708 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7709 pars1.mscpool.rsl_idx := 0;
7710 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7711 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7712 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007713 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007714
7715 var MSC_ConnHdlr vc_conn2;
7716 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7717 pars2.mscpool.rsl_idx := 1;
7718 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7719 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7720 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007721 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007722
7723 /* Test round-robin wrap to the first MSC */
7724 var MSC_ConnHdlr vc_conn3;
7725 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7726 pars3.mscpool.rsl_idx := 2;
7727 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7728 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7729 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007730 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007731 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007732}
7733
7734/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7735 * (configured in osmo-bsc.cfg). */
7736/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7737 * just as well using only RSL. */
7738testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7739
7740 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7741 f_sleep(1.0);
7742
7743 /* Control which MSC gets chosen next by the round-robin, otherwise
7744 * would be randomly affected by which other tests ran before this. */
7745 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7746
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007747 f_ctrs_msc_init();
7748
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007749 var MSC_ConnHdlr vc_conn1;
7750 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7751 pars1.mscpool.rsl_idx := 0;
7752 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7753 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7754 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007755 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007756
7757 var MSC_ConnHdlr vc_conn2;
7758 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7759 pars2.mscpool.rsl_idx := 1;
7760 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7761 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7762 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007763 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007764
7765 /* Test round-robin wrap to the first MSC */
7766 var MSC_ConnHdlr vc_conn3;
7767 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7768 pars3.mscpool.rsl_idx := 2;
7769 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7770 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7771 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007772 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007773 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007774}
7775
7776/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7777 * (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
7778 * NULL-NRI setting is stronger than that. */
7779/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7780 * just as well using only RSL. */
7781testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7782
7783 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7784 f_sleep(1.0);
7785
7786 /* Control which MSC gets chosen next by the round-robin, otherwise
7787 * would be randomly affected by which other tests ran before this. */
7788 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7789
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007790 f_ctrs_msc_init();
7791
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007792 var MSC_ConnHdlr vc_conn1;
7793 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7794 pars1.mscpool.rsl_idx := 0;
7795 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7796 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7797 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007798 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007799
7800 var MSC_ConnHdlr vc_conn2;
7801 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7802 pars2.mscpool.rsl_idx := 1;
7803 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7804 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7805 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007806 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007807
7808 /* Test round-robin wrap to the first MSC */
7809 var MSC_ConnHdlr vc_conn3;
7810 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7811 pars3.mscpool.rsl_idx := 2;
7812 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7813 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7814 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007815 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007816 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007817}
7818
7819/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7820 * assigned to any MSC (configured in osmo-bsc.cfg). */
7821/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7822 * just as well using only RSL. */
7823testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7824
7825 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7826 f_sleep(1.0);
7827
7828 /* Control which MSC gets chosen next by the round-robin, otherwise
7829 * would be randomly affected by which other tests ran before this. */
7830 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7831
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007832 f_ctrs_msc_init();
7833
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007834 var MSC_ConnHdlr vc_conn1;
7835 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7836 pars1.mscpool.rsl_idx := 0;
7837 /* An NRI that is not assigned to any MSC */
7838 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7839 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7840 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007841 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007842
7843 var MSC_ConnHdlr vc_conn2;
7844 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7845 pars2.mscpool.rsl_idx := 1;
7846 /* An NRI that is not assigned to any MSC */
7847 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7848 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7849 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007850 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007851
7852 /* Test round-robin wrap to the first MSC */
7853 var MSC_ConnHdlr vc_conn3;
7854 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7855 pars3.mscpool.rsl_idx := 2;
7856 /* An NRI that is not assigned to any MSC */
7857 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7858 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7859 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007860 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007861 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007862}
7863
7864/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7865 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7866/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7867 * just as well using only RSL. */
7868testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7869
7870 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7871 f_sleep(1.0);
7872
7873 /* Control which MSC gets chosen next by the round-robin, otherwise
7874 * would be randomly affected by which other tests ran before this. */
7875 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7876
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007877 f_ctrs_msc_init();
7878
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007879 var MSC_ConnHdlr vc_conn1;
7880 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7881 pars1.mscpool.rsl_idx := 0;
7882 /* An NRI that is assigned to an unconnected MSC */
7883 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7884 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7885 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007886 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7887 f_ctrs_msc_add(0, "mscpool:subscr:new");
7888 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007889
7890 var MSC_ConnHdlr vc_conn2;
7891 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7892 pars2.mscpool.rsl_idx := 1;
7893 /* An NRI that is assigned to an unconnected MSC */
7894 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7895 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7896 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007897 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7898 f_ctrs_msc_add(1, "mscpool:subscr:new");
7899 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007900
7901 /* Test round-robin wrap to the first MSC */
7902 var MSC_ConnHdlr vc_conn3;
7903 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7904 pars3.mscpool.rsl_idx := 2;
7905 /* An NRI that is assigned to an unconnected MSC */
7906 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7907 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7908 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007909 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7910 f_ctrs_msc_add(0, "mscpool:subscr:new");
7911 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007912 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007913}
7914
7915/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7916 * osmo-bsc.cfg). */
7917/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7918 * just as well using only RSL. */
7919testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7920
7921 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7922 f_sleep(1.0);
7923
7924 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7925 * this is not using round-robin. */
7926 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7927
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007928 f_ctrs_msc_init();
7929
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007930 var MSC_ConnHdlr vc_conn1;
7931 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7932 pars1.mscpool.rsl_idx := 0;
7933 /* An NRI of the second MSC's range (256-511) */
7934 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7935 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7936 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007937 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007938
7939 var MSC_ConnHdlr vc_conn2;
7940 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7941 pars2.mscpool.rsl_idx := 1;
7942 /* An NRI of the second MSC's range (256-511) */
7943 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7944 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7945 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007946 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007947
7948 var MSC_ConnHdlr vc_conn3;
7949 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7950 pars3.mscpool.rsl_idx := 2;
7951 /* An NRI of the second MSC's range (256-511) */
7952 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7953 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7954 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007955 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007956 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007957}
7958
7959/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7960 * while a round-robin remains unaffected by that. */
7961/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7962 * just as well using only RSL. */
7963testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7964
7965 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7966 f_sleep(1.0);
7967
7968 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7969 * this is not using round-robin. */
7970 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7971
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007972 f_ctrs_msc_init();
7973
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007974 var MSC_ConnHdlr vc_conn1;
7975 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7976 pars1.mscpool.rsl_idx := 0;
7977 /* An NRI of the third MSC's range (512-767) */
7978 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7979 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7980 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007981 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007982
7983 var MSC_ConnHdlr vc_conn2;
7984 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7985 pars2.mscpool.rsl_idx := 1;
7986 /* An NRI of the third MSC's range (512-767) */
7987 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7988 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7989 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007990 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007991
7992 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7993 var MSC_ConnHdlr vc_conn3;
7994 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7995 pars3.mscpool.rsl_idx := 2;
7996 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7997 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7998 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007999 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008000 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008001}
8002
8003/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8004/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8005 * just as well using only RSL. */
8006testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8007
8008 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8009 f_sleep(1.0);
8010
8011 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8012 * instead, and hits msc 0. */
8013 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8014
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008015 f_ctrs_msc_init();
8016
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008017 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8018 var MSC_ConnHdlr vc_conn1;
8019 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8020 pars1.mscpool.rsl_idx := 0;
8021 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8022 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8023 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008024 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008025
8026 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8027 var MSC_ConnHdlr vc_conn2;
8028 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8029 pars2.mscpool.rsl_idx := 1;
8030 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8031 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8032 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008033 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008034 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008035}
8036
8037/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8038 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8039private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8040 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8041 //cid_list := { cIl_allInBSS := ''O };
8042 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8043 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8044 var BSSAP_N_UNITDATA_req paging;
8045 var hexstring imsi := '001010000000123'H;
8046
8047 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8048
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008049 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008050 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8051 BSSAP.send(paging);
8052
8053 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8054 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8055 * channel number is picked here. */
8056 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8057 f_rslem_register(0, new_chan_nr);
8058 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8059 f_rslem_unregister(0, new_chan_nr);
8060
8061 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8062 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008063 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008064 f_sleep(1.0);
8065}
8066testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8067 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8068 f_sleep(1.0);
8069
8070 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8071 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8072 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8073
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008074 f_ctrs_msc_init();
8075
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008076 var MSC_ConnHdlr vc_conn1;
8077 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8078 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008079 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8080 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008081 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8082 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008083 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008084 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008085}
8086
8087/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8088 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8089private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8090 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8091 //cid_list := { cIl_allInBSS := ''O };
8092 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8093 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8094 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008095 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008096 var BSSAP_N_UNITDATA_req paging;
8097
8098 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8099
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008100 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008101 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8102 BSSAP.send(paging);
8103
8104 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8105 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8106 * channel number is picked here. */
8107 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8108 f_rslem_register(0, new_chan_nr);
8109 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8110 f_rslem_unregister(0, new_chan_nr);
8111
8112 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8113 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8114 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008115 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 +02008116 f_sleep(1.0);
8117}
8118testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8119 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8120 f_sleep(1.0);
8121
8122 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8123 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8124 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8125
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008126 f_ctrs_msc_init();
8127
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008128 var MSC_ConnHdlr vc_conn1;
8129 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8130 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008131 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8132 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008133 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8134 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008135 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008136 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008137}
8138
8139/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8140/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8141 * just as well using only RSL. */
8142testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8143
8144 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8145 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008146 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8147 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008148
8149 /* Control which MSC gets chosen next by the round-robin, otherwise
8150 * would be randomly affected by which other tests ran before this. */
8151 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8152
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008153 f_ctrs_msc_init();
8154
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008155 var MSC_ConnHdlr vc_conn1;
8156 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8157 pars1.mscpool.rsl_idx := 0;
8158 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8159 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8160 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008161 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008162
8163 var MSC_ConnHdlr vc_conn2;
8164 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8165 pars2.mscpool.rsl_idx := 1;
8166 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8167 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8168 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008169 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008170
8171 var MSC_ConnHdlr vc_conn3;
8172 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8173 pars3.mscpool.rsl_idx := 2;
8174 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8175 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8176 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008177 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008178 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008179}
8180
8181/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8182 * TMSI NRI. */
8183testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8184
8185 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8186 f_sleep(1.0);
8187
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008188 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8189 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8190
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008191 /* Control which MSC gets chosen next by the round-robin, otherwise
8192 * would be randomly affected by which other tests ran before this. */
8193 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8194
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008195 f_ctrs_msc_init();
8196
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008197 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8198 var MSC_ConnHdlr vc_conn1;
8199 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8200 pars1.mscpool.rsl_idx := 0;
8201 /* An NRI of the second MSC's range (256-511) */
8202 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8203 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8204 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008205 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008206
8207 var MSC_ConnHdlr vc_conn2;
8208 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8209 pars2.mscpool.rsl_idx := 1;
8210 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8211 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8212 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008213 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008214
8215 var MSC_ConnHdlr vc_conn3;
8216 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8217 pars3.mscpool.rsl_idx := 2;
8218 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8219 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8220 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008221 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008222 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008223}
8224
Philipp Maier783681c2020-07-16 16:47:06 +02008225/* Allow/Deny emergency calls globally via VTY */
8226private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8227 f_vty_enter_cfg_msc(BSCVTY, 0);
8228 if (allow) {
8229 f_vty_transceive(BSCVTY, "allow-emergency allow");
8230 } else {
8231 f_vty_transceive(BSCVTY, "allow-emergency deny");
8232 }
8233 f_vty_transceive(BSCVTY, "exit");
8234 f_vty_transceive(BSCVTY, "exit");
8235}
8236
8237/* Allow/Deny emergency calls per BTS via VTY */
8238private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8239 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8240 if (allow) {
8241 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8242 } else {
8243 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8244 }
8245 f_vty_transceive(BSCVTY, "exit");
8246 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008247 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008248}
8249
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008250/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8251private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8252 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8253 if (allow) {
8254 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8255 } else {
8256 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8257 }
8258 f_vty_transceive(BSCVTY, "exit");
8259 f_vty_transceive(BSCVTY, "exit");
8260 f_vty_transceive(BSCVTY, "exit");
8261}
8262
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008263/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8264private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8265 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8266 if (allow) {
8267 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8268 } else {
8269 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8270 }
8271 f_vty_transceive(BSCVTY, "exit");
8272 f_vty_transceive(BSCVTY, "exit");
8273 f_vty_transceive(BSCVTY, "exit");
8274}
8275
Philipp Maier783681c2020-07-16 16:47:06 +02008276/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8277private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8278 var PDU_ML3_MS_NW emerg_setup;
8279 var octetstring emerg_setup_enc;
8280 var RSL_Message emerg_setup_data_ind;
8281
8282 f_establish_fully(omit, omit);
8283
8284 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8285 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8286 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8287
8288 RSL.send(emerg_setup_data_ind);
8289}
8290
8291/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8292 * CALLS are permitted by the BSC config. */
8293private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8294 var PDU_BSSAP emerg_setup_data_ind_bssap;
8295 var PDU_ML3_MS_NW emerg_setup;
8296 timer T := 3.0;
8297
8298 f_assignment_emerg_setup()
8299
8300 T.start;
8301 alt {
8302 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8303 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8304 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8305 setverdict(fail, "no emergency setup");
8306 }
8307 }
8308 [] BSSAP.receive {
8309 setverdict(fail, "unexpected BSSAP message!");
8310 }
8311 [] T.timeout {
8312 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8313 }
8314 }
8315
8316 setverdict(pass);
8317}
8318
8319/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8320 * forbidden by the BSC config. */
8321private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8322 var PDU_BSSAP emerg_setup_data_ind_bssap;
8323 timer T := 3.0;
8324
8325 f_assignment_emerg_setup()
8326
8327 T.start;
8328 alt {
8329 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8330 setverdict(pass);
8331 }
8332 [] RSL.receive {
8333 setverdict(fail, "unexpected RSL message!");
8334 }
8335 [] T.timeout {
8336 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8337 }
8338 }
8339}
8340
8341/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8342testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8343 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8344 var MSC_ConnHdlr vc_conn;
8345
8346 f_init(1, true);
8347 f_sleep(1.0);
8348
8349 f_vty_allow_emerg_msc(true);
8350 f_vty_allow_emerg_bts(true, 0);
8351 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8352 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008353 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008354}
8355
8356/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8357testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8358 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8359 var MSC_ConnHdlr vc_conn;
8360
8361 f_init(1, true);
8362 f_sleep(1.0);
8363
8364 f_vty_allow_emerg_msc(false);
8365 f_vty_allow_emerg_bts(true, 0);
8366 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8367 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008368 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008369}
8370
8371/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8372testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8373 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8374 var MSC_ConnHdlr vc_conn;
8375
8376 /* Note: This simulates a spec violation by the MS, correct MS
8377 * implementations would not try to establish an emergency call because
8378 * the system information tells in advance that emergency calls are
8379 * not forbidden */
8380
8381 f_init(1, true);
8382 f_sleep(1.0);
8383
8384 f_vty_allow_emerg_msc(true);
8385 f_vty_allow_emerg_bts(false, 0);
8386 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8387 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008388 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008389}
8390
Philipp Maier82812002020-08-13 18:48:27 +02008391/* Test what happens when an emergency call arrives while all TCH channels are
8392 * busy, the BSC is expected to terminate one call in favor of the incoming
8393 * emergency call */
8394testcase TC_emerg_premption() runs on test_CT {
8395 var ASP_RSL_Unitdata rsl_ud;
8396 var integer i;
8397 var integer chreq_total, chreq_nochan;
8398 var RSL_Message rx_rsl;
8399 var RslChannelNr chan_nr;
8400
8401 f_init(1);
8402 f_sleep(1.0);
8403
8404 f_vty_allow_emerg_msc(true);
8405 f_vty_allow_emerg_bts(true, 0);
8406
8407 /* Fill up all channels on the BTS */
8408 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8409 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8410 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8411 chan_nr := f_chreq_act_ack('33'O, i);
8412 }
8413 IPA_RSL[0].clear;
8414 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8415 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8416
8417 /* Send Channel request for emegergency call */
8418 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8419
8420 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8421 chan_nr := valueof(t_RslChanNr_Bm(1));
8422 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8423
8424 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8425 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8426 chan_nr := rx_rsl.ies[0].body.chan_nr;
8427 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8428 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008429
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008430 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008431}
8432
8433/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008434private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008435private type record FHParamsTs {
8436 boolean enabled,
8437 uint6_t hsn,
8438 uint6_t maio,
8439 ArfcnList ma
8440};
8441
8442/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008443private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02008444 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008445 FHParamsTs ts[8]
8446};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008447
8448/* Randomly generate the hopping parameters for the given timeslot numbers */
8449private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8450runs on test_CT return FHParamsTrx {
8451 var FHParamsTrx fhp;
8452
Philipp Maier798d8952021-10-19 14:43:19 +02008453 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
8454 * fall in the GSM900 band. */
8455 fhp.arfcn.arfcn := f_rnd_int(3);
8456 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008457
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008458 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8459 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008460 fhp.ts[tn].enabled := false;
8461 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008462 continue;
8463 }
8464
8465 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008466 fhp.ts[tn].hsn := f_rnd_int(64);
8467 fhp.ts[tn].maio := f_rnd_int(64);
8468 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008469
8470 /* Random Mobile Allocation (hopping channels) */
8471 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8472 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8473 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008474 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008475 }
8476
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008477 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008478 }
8479
8480 log("f_TC_fh_params_gen(): ", fhp);
8481 return fhp;
8482}
8483
8484/* Make sure that the given Channel Description IE matches the hopping configuration */
8485private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8486{
8487 var template (present) ChannelDescription tr_cd;
8488 var template (present) MaioHsn tr_maio_hsn;
8489 var uint3_t tn := cd.chan_nr.tn;
8490
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008491 if (fhp.ts[tn].enabled) {
8492 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008493 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8494 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02008495 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008496 }
8497
8498 if (not match(cd, tr_cd)) {
8499 setverdict(fail, "Channel Description IE does not match: ",
8500 cd, " vs expected ", tr_cd);
8501 }
8502}
8503
8504/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8505private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8506 in MobileAllocationLV ma)
8507{
8508 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8509
8510 if (not match(ma, tr_ma)) {
8511 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8512 tn, "): ", ma, " vs expected: ", tr_ma);
8513 } else {
8514 setverdict(pass);
8515 }
8516}
8517
8518private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8519 in MobileAllocationLV ma)
8520return template MobileAllocationLV {
8521 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008522 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008523 return { len := 0, ma := ''B };
8524 }
8525
8526 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8527 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8528 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008529
8530 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008531 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8532 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8533 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008534 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008535 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008536 }
8537 }
8538
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008539 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02008540 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008541
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008542 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008543 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8544 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008545 }
8546
8547 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008548 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008549 if (full_mask[i] != '1'B)
8550 { continue; }
8551
8552 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8553 if (slot_mask[i] == '1'B) {
8554 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008555 } else {
8556 ma_mask := ma_mask & '0'B;
8557 }
8558 }
8559
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008560 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8561 if (full_mask[0] == '1'B) {
8562 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8563 if (slot_mask[0] == '1'B) {
8564 ma_mask := ma_mask & '1'B;
8565 } else {
8566 ma_mask := ma_mask & '0'B;
8567 }
8568 }
8569
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008570 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008571 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008572 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8573
8574 return { len := ma_mask_len, ma := ma_mask };
8575}
8576
Philipp Maier798d8952021-10-19 14:43:19 +02008577/* Configure the appropriate band for a given arfcn, exc */
8578private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
8579{
8580 var charstring band;
8581 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
8582
8583 select (arfcn_) {
8584 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
8585 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
8586 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
8587 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
8588 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
8589 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
8590 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
8591 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
8592 case else { return; }
8593 }
8594
8595 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8596 f_vty_transceive(BSCVTY, "band " & band);
8597 f_vty_transceive(BSCVTY, "end");
8598}
8599
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008600/* Configure the hopping parameters in accordance with the given record */
8601private function f_TC_fh_params_set(in FHParamsTrx fhp,
8602 uint8_t bts_nr := 0,
8603 uint8_t trx_nr := 0)
8604runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008605
8606 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
8607
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008608 /* Enter the configuration node for the given BTS/TRX numbers */
8609 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8610
Philipp Maier798d8952021-10-19 14:43:19 +02008611 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008612
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008613 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008614 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8615
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008616 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008617 f_vty_transceive(BSCVTY, "hopping enabled 0");
8618 f_vty_transceive(BSCVTY, "exit"); /* go back */
8619 continue;
8620 }
8621
8622 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008623 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8624 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008625
8626 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008627 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8628 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008629 }
8630
8631 f_vty_transceive(BSCVTY, "hopping enabled 1");
8632 f_vty_transceive(BSCVTY, "exit"); /* go back */
8633 }
8634
8635 f_vty_transceive(BSCVTY, "end");
8636}
8637
8638/* Disable frequency hopping on all timeslots */
8639private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8640 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008641 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02008642 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008643runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02008644
8645 f_TC_set_band_by_arfcn(bts_nr, arfcn);
8646
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008647 /* Enter the configuration node for the given BTS/TRX numbers */
8648 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8649
Philipp Maier798d8952021-10-19 14:43:19 +02008650 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008651
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008652 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008653 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8654
8655 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008656 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8657 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008658 }
8659
8660 f_vty_transceive(BSCVTY, "hopping enabled 0");
8661 f_vty_transceive(BSCVTY, "exit"); /* go back */
8662 }
8663
8664 f_vty_transceive(BSCVTY, "end");
8665 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8666}
8667
8668/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8669 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8670testcase TC_fh_params_chan_activ() runs on test_CT {
8671 var FHParamsTrx fhp := f_TC_fh_params_gen();
8672 var RSL_Message rsl_msg;
8673 var RSL_IE_Body ie;
8674
8675 f_init_vty();
8676
8677 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8678 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8679
8680 f_init(1);
8681
8682 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8683 for (var integer i := 0; i < 9; i := i + 1) {
8684 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8685 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8686
8687 /* Make sure that Channel Identification IE is present */
8688 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8689 setverdict(fail, "RSL Channel Identification IE is absent");
8690 continue;
8691 }
8692
8693 /* Make sure that hopping parameters (HSN/MAIO) match */
8694 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8695
8696 /* "Mobile Allocation shall be included but empty" - let's check this */
8697 if (ie.chan_ident.ma.v.len != 0) {
8698 setverdict(fail, "Mobile Allocation IE is not empty: ",
8699 ie.chan_ident.ma, ", despite it shall be");
8700 continue;
8701 }
8702 }
8703
8704 /* Disable frequency hopping */
8705 f_TC_fh_params_unset(fhp);
8706
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008707 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008708}
8709
8710/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8711testcase TC_fh_params_imm_ass() runs on test_CT {
8712 var FHParamsTrx fhp := f_TC_fh_params_gen();
8713 var RSL_Message rsl_msg;
8714 var RSL_IE_Body ie;
8715
8716 f_init_vty();
8717
8718 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8719 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8720
8721 f_init(1);
8722
8723 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8724 for (var integer i := 0; i < 9; i := i + 1) {
8725 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8726 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8727
8728 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8729 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8730
8731 /* Make sure that Full Immediate Assign Info IE is present */
8732 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8733 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8734 continue;
8735 }
8736
8737 /* Decode the actual Immediate Assignment message */
8738 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8739 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8740 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8741 continue;
8742 }
8743
8744 /* Make sure that hopping parameters (HSN/MAIO) match */
8745 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8746
8747 /* Make sure that the Mobile Allocation IE matches */
8748 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8749 rr_msg.payload.imm_ass.mobile_allocation);
8750 }
8751
8752 /* Disable frequency hopping */
8753 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008754
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008755 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008756}
8757
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008758/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8759testcase TC_fh_params_assignment_cmd() runs on test_CT {
8760 var FHParamsTrx fhp := f_TC_fh_params_gen();
8761 var RSL_Message rsl_msg;
8762 var RSL_IE_Body ie;
8763
8764 f_init_vty();
8765
8766 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8767 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8768
8769 f_init(1);
8770
8771 /* HACK: work around "Couldn't find Expect for CRCX" */
8772 vc_MGCP.stop;
8773
8774 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8775 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8776
8777 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8778 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8779 for (var integer i := 0; i < 3; i := i + 1) {
8780 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8781 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8782
8783 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8784 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8785 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8786
8787 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8788 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8789 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8790
8791 /* Make sure that L3 Information IE is present */
8792 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8793 setverdict(fail, "RSL L3 Information IE is absent");
8794 continue;
8795 }
8796
8797 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8798 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8799 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8800 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8801 continue;
8802 }
8803
8804 /* Make sure that hopping parameters (HSN/MAIO) match */
8805 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8806 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8807
8808 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8809 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008810 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008811 continue;
8812 }
8813
8814 /* Make sure that the Mobile Allocation IE matches (if present) */
8815 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8816 if (chan_desc.h and ma_present) {
8817 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8818 l3_msg.payload.ass_cmd.mobile_allocation.v);
8819 } else if (chan_desc.h and not ma_present) {
8820 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8821 continue;
8822 } else if (not chan_desc.h and ma_present) {
8823 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8824 continue;
8825 }
8826 }
8827
8828 /* Give the IUT some time to release all channels */
8829 f_sleep(3.0);
8830
8831 /* Disable frequency hopping */
8832 f_TC_fh_params_unset(fhp);
8833
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008834 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008835}
8836
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008837/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8838private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8839runs on test_CT {
8840 var RSL_Message rsl_msg;
8841 var RSL_IE_Body ie;
8842 var DchanTuple dt;
8843
8844 /* Establish a dedicated channel, so we can trigger handover */
8845 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8846
8847 /* Trigger handover from BTS0 to BTS1 */
8848 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8849 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8850
8851 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8852 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8853
8854 /* ACKnowledge channel activation and expect (RR) Handover Command */
8855 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8856 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8857
8858 /* Make sure that L3 Information IE is present */
8859 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8860 setverdict(fail, "RSL L3 Information IE is absent");
8861 return;
8862 }
8863
8864 /* Decode the L3 message and make sure it is (RR) Handover Command */
8865 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8866 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8867 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8868 return;
8869 }
8870
8871 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8872 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8873 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8874 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8875 return;
8876 }
8877
8878 /* Make sure that hopping parameters (HSN/MAIO) match */
8879 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8880
8881 /* Make sure that Cell Channel Description IE is present */
8882 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8883 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8884 return;
8885 }
8886
8887 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8888 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8889 if (ma_present) {
8890 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8891 l3_msg.payload.ho_cmd.mobile_allocation.v);
8892 } else {
8893 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8894 return;
8895 }
8896}
8897testcase TC_fh_params_handover_cmd() runs on test_CT {
8898 var FHParamsTrx fhp := f_TC_fh_params_gen();
8899
8900 f_init_vty();
8901
8902 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8903 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8904
8905 f_vty_transceive(BSCVTY, "timeslot 0");
8906 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8907 f_vty_transceive(BSCVTY, "exit"); /* go back */
8908
8909 f_vty_transceive(BSCVTY, "timeslot 1");
8910 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8911 f_vty_transceive(BSCVTY, "end"); /* we're done */
8912
8913 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8914 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8915
8916 f_init(2);
8917
8918 f_TC_fh_params_handover_cmd(fhp);
8919
8920 /* Disable frequency hopping on BTS1 */
8921 f_TC_fh_params_unset(fhp, 1);
8922
8923 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8924 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8925
8926 f_vty_transceive(BSCVTY, "timeslot 0");
8927 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8928 f_vty_transceive(BSCVTY, "exit"); /* go back */
8929
8930 f_vty_transceive(BSCVTY, "timeslot 1");
8931 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8932 f_vty_transceive(BSCVTY, "end"); /* we're done */
8933
8934 f_shutdown_helper();
8935}
8936
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008937/* Verify the hopping parameters in System Information Type 4 */
8938testcase TC_fh_params_si4_cbch() runs on test_CT {
8939 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8940 var ASP_RSL_Unitdata rx_rsl_ud;
8941 timer T := 5.0;
8942
8943 f_init_vty();
8944
8945 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
8946 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8947
8948 f_vty_transceive(BSCVTY, "timeslot 0");
8949 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8950 f_vty_transceive(BSCVTY, "exit"); /* go back */
8951
8952 f_vty_transceive(BSCVTY, "timeslot 1");
8953 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
8954 f_vty_transceive(BSCVTY, "end"); /* we're done */
8955
8956 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8957 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8958
8959 f_init(1);
8960
8961 T.start;
8962 alt {
8963 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
8964 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
8965 var SystemInformation si := dec_SystemInformation(ie.other.payload);
8966
8967 /* Make sure that what we decoded is System Information Type 4 */
8968 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
8969 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
8970 repeat;
8971 }
8972
8973 /* Make sure that CBCH Channel Description IE is present */
8974 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
8975 setverdict(fail, "CBCH Channel Description IE is absent");
8976 break;
8977 }
8978
8979 /* Finally, check the hopping parameters (HSN, MAIO) */
8980 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
8981 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8982
8983 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
8984 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
8985 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
8986 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8987 break;
8988 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
8989 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8990 si.payload.si4.cbch_mobile_alloc.v);
8991 }
8992 }
8993 [] IPA_RSL[0].receive { repeat; }
8994 [] T.timeout {
8995 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
8996 }
8997 }
8998
8999 /* Disable frequency hopping */
9000 f_TC_fh_params_unset(fhp);
9001
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009002 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009003 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9004
9005 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009006 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009007 f_vty_transceive(BSCVTY, "exit"); /* go back */
9008
9009 f_vty_transceive(BSCVTY, "timeslot 1");
9010 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9011 f_vty_transceive(BSCVTY, "end"); /* we're done */
9012
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009013 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009014}
9015
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009016template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9017 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9018
9019private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9020 template (present) BSSLAP_PDU expect_bsslap)
9021{
9022 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9023 if (not match(bsslap, expect_bsslap)) {
9024 log("EXPECTING BSSLAP: ", expect_bsslap);
9025 log("GOT BSSLAP: ", bsslap);
9026 setverdict(fail, "BSSLAP is not as expected");
9027 mtc.stop;
9028 }
9029 setverdict(pass);
9030}
9031
9032/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9033const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9034
9035private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9036 var PDU_BSSAP_LE rx_bsslap;
9037 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9038 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9039}
9040
9041/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9042 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9043private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9044 f_sleep(1.0);
9045
9046 f_establish_fully(omit, omit);
9047 f_bssap_le_register_imsi(g_pars.imsi, omit);
9048
9049 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9050 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9051
9052 var PDU_BSSAP_LE plr;
9053 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9054
9055 if (not do_ta_request) {
9056 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9057 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9058 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9059 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9060 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9061 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9062 mtc.stop;
9063 }
9064 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9065 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9066 if (not match(bsslap, expect_ta_layer3)) {
9067 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9068 log("GOT BSSLAP: ", bsslap);
9069 setverdict(fail, "BSSLAP is not as expected");
9070 mtc.stop;
9071 }
9072 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9073 * has no need to request the TA from the BSC and directly responds. */
9074 } else {
9075 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9076 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9077 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9078 }
9079
9080 /* SMLC got the TA from the BSC, now responds with geo information data. */
9081 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9082 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9083 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9084
9085 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9086 f_mo_l3_transceive();
9087
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009088 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009089
9090 f_sleep(2.0);
9091 setverdict(pass);
9092}
9093
9094/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9095 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9096private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9097 f_lcs_loc_req_for_active_ms(false);
9098}
9099testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9100 var MSC_ConnHdlr vc_conn;
9101 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9102
9103 f_init(1, true);
9104 f_sleep(1.0);
9105 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9106 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009107 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009108}
9109
9110/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9111 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9112private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9113 f_lcs_loc_req_for_active_ms(true);
9114}
9115testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9116 var MSC_ConnHdlr vc_conn;
9117 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9118
9119 f_init(1, true);
9120 f_sleep(1.0);
9121 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9122 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009123 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009124}
9125
9126/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9127 * conn without an active lchan. */
9128private function f_clear_A_conn() runs on MSC_ConnHdlr
9129{
9130 var BssmapCause cause := 0;
9131 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9132 BSSAP.receive(tr_BSSMAP_ClearComplete);
9133 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9134
9135 timer no_more_bssap := 5.0;
9136 no_more_bssap.start;
9137 alt {
9138 [] no_more_bssap.timeout { break; }
9139 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9140 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9141 mtc.stop;
9142 }
9143 }
9144 setverdict(pass);
9145}
9146
9147/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9148 * for LCS, for cases where there is only an A conn without an active lchan. */
9149private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9150{
9151 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9152
9153 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9154 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9155 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9156 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9157 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9158 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9159
9160 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9161 f_clear_A_conn();
9162 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9163 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9164}
9165
9166/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9167 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9168 */
9169private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9170 f_sleep(1.0);
9171
9172 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9173 f_bssap_le_register_imsi(g_pars.imsi, omit);
9174
9175 /* Register to receive the Paging Command */
9176 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9177 g_chan_nr := new_chan_nr;
9178 f_rslem_register(0, g_chan_nr);
9179
9180 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9181 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9182 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9183 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9184
9185 var PDU_BSSAP_LE plr;
9186 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9187
9188 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9189 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9190
9191 /* OsmoBSC needs to Page */
9192 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9193 f_logp(BSCVTY, "got Paging Command");
9194
9195 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9196 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009197 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);
9198 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009199
9200 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9201
9202 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9203
9204 /* SMLC got the TA from the BSC, now responds with geo information data. */
9205 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9206 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9207
9208 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9209
9210 /* The lchan is gone, the A-interface conn was created for the LCS only.
9211 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9212 f_verify_active_A_conn_and_clear();
9213
9214 f_sleep(2.0);
9215 setverdict(pass);
9216}
9217testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9218 var MSC_ConnHdlr vc_conn;
9219 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9220
9221 f_init(1, true);
9222 f_sleep(1.0);
9223
9224 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9225 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9226
9227 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9228 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009229 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009230}
9231
9232/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9233 */
9234private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9235 f_sleep(1.0);
9236
9237 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9238 f_bssap_le_register_imsi(g_pars.imsi, omit);
9239
9240 /* provoke an abort by omitting both IMSI and IMEI */
9241 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9242 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9243 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9244 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9245
9246 /* BSC tells MSC about failure */
9247 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9248 locationEstimate := omit, positioningData := omit,
9249 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9250
9251 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9252 f_verify_active_A_conn_and_clear();
9253
9254 f_sleep(2.0);
9255 setverdict(pass);
9256}
9257testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9258 var MSC_ConnHdlr vc_conn;
9259 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9260
9261 f_init(1, true);
9262 f_sleep(1.0);
9263
9264 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9265 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9266
9267 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9268 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009269 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009270}
9271
9272/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9273 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9274private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9275 f_sleep(1.0);
9276
9277 f_establish_fully(omit, omit);
9278 f_bssap_le_register_imsi(g_pars.imsi, omit);
9279
9280 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9281 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9282
9283 var PDU_BSSAP_LE plr;
9284 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9285
9286 if (do_ta) {
9287 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9288 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9289 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9290 }
9291
9292 /* SMLC fails to respond, BSC runs into timeout */
9293 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9294 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9295
9296 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9297 locationEstimate := omit, positioningData := omit,
9298 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9299
9300 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9301 f_verify_active_A_conn_and_clear();
9302
9303 f_sleep(2.0);
9304 setverdict(pass);
9305}
9306
9307/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9308 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9309private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9310 f_lcs_loc_req_for_active_ms_le_timeout(false);
9311}
9312
9313testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9314 var MSC_ConnHdlr vc_conn;
9315 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9316
9317 f_init(1, true);
9318 f_sleep(1.0);
9319 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9320 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009321 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009322}
9323
9324/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9325 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9326private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9327 f_lcs_loc_req_for_active_ms_le_timeout(true);
9328}
9329
9330testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9331 var MSC_ConnHdlr vc_conn;
9332 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9333
9334 f_init(1, true);
9335 f_sleep(1.0);
9336 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9337 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009338 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009339}
9340
9341/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9342private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9343 f_sleep(1.0);
9344
9345 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9346 f_bssap_le_register_imsi(g_pars.imsi, omit);
9347
9348 /* Register to receive the Paging Command */
9349 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9350 g_chan_nr := new_chan_nr;
9351 f_rslem_register(0, g_chan_nr);
9352
9353 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9354 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9355 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9356 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9357
9358 var PDU_BSSAP_LE plr;
9359 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9360
9361 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9362 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9363
9364 /* OsmoBSC needs to Page */
9365 var PDU_BSSAP_LE rx_bsslap;
9366 alt {
9367 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9368 f_logp(BSCVTY, "got Paging Command");
9369 repeat;
9370 }
9371 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9372 /* MS does not respond to Paging, TA Req runs into timeout. */
9373 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9374 }
9375 }
9376
9377 /* SMLC responds with failure */
9378 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9379 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9380
9381 /* BSC tells MSC about failure */
9382 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9383 locationEstimate := omit, positioningData := omit,
9384 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9385
9386 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9387 f_verify_active_A_conn_and_clear();
9388
9389 f_sleep(2.0);
9390 setverdict(pass);
9391}
9392testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9393 var MSC_ConnHdlr vc_conn;
9394 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9395
9396 f_init(1, true);
9397 f_sleep(1.0);
9398
9399 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9400 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9401
9402 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9403 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009404 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009405}
9406
9407/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9408 * over. */
9409private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9410 f_sleep(1.0);
9411
9412 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9413 f_bssap_le_register_imsi(g_pars.imsi, omit);
9414
9415 /* Register to receive the Paging Command */
9416 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9417 g_chan_nr := new_chan_nr;
9418 f_rslem_register(0, g_chan_nr);
9419
9420 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9421 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9422 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9423 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9424
9425 var PDU_BSSAP_LE plr;
9426 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9427
9428 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9429 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009430 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 +02009431 do_clear := false, expect_bssmap_l3 := true);
9432
9433 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9434 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9435
9436 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9437 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9438
9439 /* SMLC got the TA from the BSC, now responds with geo information data. */
9440 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9441 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9442 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9443
9444 /* The lchan should still exist, it was from a CM Service Request. */
9445 f_mo_l3_transceive();
9446
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009447 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009448
9449 f_sleep(2.0);
9450 setverdict(pass);
9451}
9452testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9453 var MSC_ConnHdlr vc_conn;
9454 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9455
9456 f_init(1, true);
9457 f_sleep(1.0);
9458
9459 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9460 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9461
9462 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9463 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009464 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009465}
9466
9467/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9468 * the new lchan after handover. */
9469private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9470 f_sleep(1.0);
9471
9472 f_establish_fully(omit, omit);
9473 f_bssap_le_register_imsi(g_pars.imsi, omit);
9474
9475 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9476 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9477
9478 var PDU_BSSAP_LE plr;
9479 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9480
9481 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9482 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9483
9484 var HandoverState hs := {
9485 rr_ho_cmpl_seen := false,
9486 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02009487 old_chan_nr := -,
9488 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009489 };
9490 /* issue hand-over command on VTY */
9491 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9492 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9493 f_rslem_suspend(RSL1_PROC);
9494
9495 /* From the MGW perspective, a handover is is characterized by
9496 * performing one MDCX operation with the MGW. So we expect to see
9497 * one more MDCX during handover. */
9498 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9499
9500 alt {
9501 [] as_handover(hs);
9502 }
9503
9504 var PDU_BSSAP_LE rx_bsslap;
9505
9506 interleave {
9507 /* Expect the BSC to inform the MSC about the handover */
9508 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9509
9510 /* Expect the BSC to inform the SMLC about the handover */
9511 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9512 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9513 }
9514 }
9515
9516 /* SMLC now responds with geo information data. */
9517 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9518 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9519 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9520
9521 /* lchan still active */
9522 f_mo_l3_transceive(RSL1);
9523
9524 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009525 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009526
9527 f_sleep(2.0);
9528 setverdict(pass);
9529}
9530testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9531 var MSC_ConnHdlr vc_conn;
9532 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9533
9534 f_init(2, true);
9535 f_sleep(1.0);
9536 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9537 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009538 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009539}
9540
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009541/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9542private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9543 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9544
9545 /* Also disable attach for the single connected MSC */
9546 f_vty_msc_allow_attach(BSCVTY, { false });
9547
9548 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) ));
9549 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9550
9551 /* No MSC is found, expecting a proper release on RSL */
9552 interleave {
9553 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9554 f_logp(BSCVTY, "Got RSL RR Release");
9555 }
9556 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9557 f_logp(BSCVTY, "Got RSL Deact SACCH");
9558 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009559 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009560 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9561 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009562 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009563 }
9564 }
9565 setverdict(pass);
9566}
9567testcase TC_no_msc() runs on test_CT {
9568
9569 f_init(1, true);
9570 f_sleep(1.0);
9571 var MSC_ConnHdlr vc_conn;
9572 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9573
9574 f_ctrs_bsc_init(counternames_bsc_mscpool);
9575
9576 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9577 vc_conn.done;
9578
9579 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9580 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009581 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009582}
9583
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009584/* Dyn PDCH todo:
9585 * activate OSMO as TCH/F
9586 * activate OSMO as TCH/H
9587 * does the BSC-located PCU socket get the updated INFO?
9588 * what if no PCU is connected at the time?
9589 * is the info correct on delayed PCU (re)connect?
9590 */
Harald Welte94e0c342018-04-07 11:33:23 +02009591
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009592private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9593 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9594 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9595
9596 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9597 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9598 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9599 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9600 g_pars.ass_codec_list.codecElements[0];
9601 if (isvalue(g_pars.expect_mr_s0_s7)) {
9602 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9603 g_pars.expect_mr_s0_s7;
9604 }
9605 }
9606 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9607 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9608 log("expecting ASS COMPL like this: ", exp_compl);
9609
9610 f_establish_fully(ass_cmd, exp_compl);
9611
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009612 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 +00009613
9614 var RSL_Message rsl;
9615
9616 timer T := 5.0;
9617 T.start;
9618 alt {
9619 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9620 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9621 log("Rx L3 from net: ", l3);
9622 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9623 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9624 mtc.stop;
9625 }
9626 }
9627 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9628 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9629 mtc.stop;
9630 }
9631 [] T.timeout {
9632 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9633 setverdict(pass);
9634 }
9635 }
9636 T.stop;
9637}
9638
9639/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9640 * osmo-bsc. */
9641testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9642 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9643 var MSC_ConnHdlr vc_conn;
9644
9645 f_init(1, true);
9646 f_sleep(1.0);
9647
9648 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9649 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9650 vc_conn.done;
9651 f_shutdown_helper();
9652}
9653
9654/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9655 */
9656testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9657 f_init_vty();
9658
9659 f_init(1, false);
9660 f_sleep(1.0);
9661
9662 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9663
9664 var ASP_RSL_Unitdata rx_rsl_ud;
9665 timer T := 5.0;
9666
9667 T.start;
9668 alt {
9669 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9670 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9671 T.stop;
9672 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9673 mtc.stop;
9674 }
9675 repeat;
9676 }
9677 [] T.timeout {
9678 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9679 setverdict(pass);
9680 }
9681 }
9682}
9683
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009684private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9685 /* First fully set up a speech lchan */
9686 f_TC_assignment_codec(id);
9687
9688 /* Trigger re-assignment to another lchan */
9689 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9690
9691 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9692 * one MDCX on MGCP. */
9693 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9694
9695 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9696 * as the old lchan used. */
9697 g_media.bts.ipa_crcx_seen := false;
9698 g_media.bts.ipa_mdcx_seen := false;
9699
9700 /* Send different BTS side RTP port number for the new lchan */
9701 g_media.bts.bts.port_nr := 4223;
9702
9703 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9704
9705 /* Trigger re-assignment. */
9706 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9707
9708 timer T := 5.0;
9709 T.start;
9710 alt {
9711 [] as_assignment(assignment_st);
9712 [] as_Media();
9713 [] T.timeout {
9714 break;
9715 }
9716 }
9717
9718 if (not assignment_st.assignment_done) {
9719 setverdict(fail, "Assignment did not complete");
9720 mtc.stop;
9721 }
9722
9723 f_check_mgcp_expectations()
9724 setverdict(pass);
9725
9726 f_sleep(2.0);
9727 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9728
9729 /* Instruct BSC to clear channel */
9730 var BssmapCause cause := 0;
9731 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9732 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009733 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9734 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009735 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009736 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009737 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009738 }
9739 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9740 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9741 }
9742 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +02009743 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009744
9745 f_sleep(0.5);
9746}
9747
9748testcase TC_reassignment_fr() runs on test_CT {
9749 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9750 var MSC_ConnHdlr vc_conn;
9751
9752 f_init(1, true);
9753 f_sleep(1.0);
9754
9755 f_ctrs_bsc_and_bts_init();
9756
9757 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9758 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9759 vc_conn.done;
9760
9761 /* from f_establish_fully() */
9762 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9763 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9764 /* from re-assignment */
9765 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9766 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9767 f_ctrs_bsc_and_bts_verify();
9768 f_shutdown_helper();
9769}
9770
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009771const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9772const charstring REEST_CLEAR := "REEST_CLEAR";
9773const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9774
9775/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9776 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9777 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9778 * the MSC as the CM Re-Establishment is handled.
9779 *
9780 * MS bts0 bts1 bsc msc test-component
9781 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9782 * | | _1 wait a bit, to settle down
9783 * |<-x x--| | _1 "lose connection"
9784 * | | REEST_LOST_CONNECTION
9785 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9786 * | | REEST_CLEAR
9787 * | |<-0---| _1 Clear Command on first A-conn
9788 * | |--0-->| _1 Clear Complete
9789 * | |<----------------->| | _1 Release first channel
9790 * | | REEST_CLEAR_DONE
9791 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9792 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9793 *
9794 */
9795private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9796 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9797 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9798
9799 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9800 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9801
9802 f_establish_fully(ass_cmd, exp_compl);
9803
9804 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9805 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9806 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9807 f_sleep(2.0);
9808 COORD.send(REEST_LOST_CONNECTION);
9809
9810 alt {
9811 [] COORD.receive(REEST_CLEAR);
9812 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9813 setverdict(fail, "Unexpected channel release");
9814 mtc.stop;
9815 }
9816 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9817 setverdict(fail, "Unexpected channel release");
9818 mtc.stop;
9819 }
9820 }
9821 f_perform_clear()
9822 f_expect_dlcx_conns();
Neels Hofmeyr969abd02021-09-23 22:24:08 +02009823 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009824 COORD.send(REEST_CLEAR_DONE);
9825}
9826
9827private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9828 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9829
9830 /* The MS lost the connection on the first channel, now establishes another one */
9831 COORD.receive(REEST_LOST_CONNECTION);
9832
9833 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9834 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9835 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9836
9837 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009838 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 +02009839 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9840
9841 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9842 COORD.send(REEST_CLEAR);
9843 COORD.receive(REEST_CLEAR_DONE);
9844
9845 f_sleep(2.0);
9846
9847 /* Answer the CM Re-Establishment with an Assignment Command. */
9848 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9849 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9850 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9851 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9852
9853 var AssignmentState st := valueof(ts_AssignmentStateInit);
9854 st.voice_call := true;
9855 st.is_assignment := true;
9856
9857 var ExpectCriteria mgcpcrit := {
9858 connid := omit,
9859 endpoint := omit,
9860 transid := omit
9861 };
9862 f_create_mgcp_expect(mgcpcrit);
9863
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009864 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009865
9866 BSSAP.send(ass_cmd);
9867
9868 var PDU_BSSAP bssap;
9869
9870 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009871 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9872 [] as_Media_ipacc(RSL1, RSL2);
9873 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009874 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9875 break;
9876 }
9877 }
9878
9879 f_sleep(3.0);
9880
9881 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009882 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009883 f_expect_dlcx_conns();
9884}
9885
9886testcase TC_cm_reestablishment() runs on test_CT {
9887 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9888 var MSC_ConnHdlr vc_conn1;
9889
9890 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9891 var MSC_ConnHdlr vc_conn2;
9892 pars2.imsi := pars1.imsi;
9893 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +02009894 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009895
9896 f_init(2, true, guard_timeout := 40.0);
9897 f_sleep(1.0);
9898
9899 vc_conn1 := f_start_handler_create(pars1);
9900 vc_conn2 := f_start_handler_create(pars2);
9901 connect(vc_conn1:COORD, vc_conn2:COORD);
9902 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9903 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9904 vc_conn1.done;
9905 vc_conn2.done;
9906
9907 f_shutdown_helper();
9908}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009909
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009910function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9911 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9912runs on test_CT return template (omit) RSL_Message {
9913 var ASP_RSL_Unitdata rx_rsl_ud;
9914 timer T := t_secs;
9915
9916 T.start;
9917 alt {
9918 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9919 T.stop;
9920 }
9921 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9922 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9923 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9924 T.stop;
9925 return omit;
9926 }
9927 [] T.timeout {
9928 return omit;
9929 }
9930 }
9931 return rx_rsl_ud.rsl;
9932}
9933
9934private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9935 f_vty_enter_cfg_bts(pt, bts_nr);
9936 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9937 f_vty_transceive(pt, "exit");
9938 f_vty_transceive(pt, "exit");
9939 f_vty_transceive(pt, "exit");
9940}
9941
9942private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009943 template RslChannelNr chan_nr := ?,
9944 template (present) uint12_t arfcn := ?,
9945 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009946{
9947 var RSL_IE_Body full_imm_ass_info;
9948 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
9949 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9950 mtc.stop;
9951 }
9952
9953 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
9954 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
9955 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009956 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009957 page_mode := ?);
9958 if (not match(rr_imm_ass, expect_imm_ass)) {
9959 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
9960 setverdict(fail, "Failed to match Immediate Assignment");
9961 mtc.stop;
9962 }
9963}
9964
9965testcase TC_imm_ass_post_chan_ack() runs on test_CT {
9966 var RSL_Message chan_act;
9967 var RSL_Message imm_ass;
9968
9969 f_init(1, false);
9970 f_sleep(1.0);
9971
9972 /* (should be the default anyway, just to make things clear) */
9973 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
9974
9975 /* RA containing reason=LU */
9976 var GsmFrameNumber fn := 2342;
9977 var uint8_t ra := 2;
9978 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9979
9980 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9981
9982 /* First send the Chan Act ACK */
9983 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009984 var RSL_IE_Body chan_ident_ie;
9985 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9986 setverdict(fail, "RSL Channel Identification IE is absent");
9987 mtc.stop;
9988 }
9989
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009990 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
9991
9992 /* Then expect the Immediate Assignment, after we ACKed the chan act */
9993 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9994
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009995 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9996 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009997
9998 /* Check that the lchan is working */
9999 var octetstring l3 := '00010203040506'O;
10000 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10001
10002 var BSSAP_N_CONNECT_ind rx_c_ind;
10003 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10004 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10005
10006 f_sleep(1.0);
10007 f_shutdown_helper();
10008}
10009
10010testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10011 var RSL_Message chan_act;
10012 var RSL_Message imm_ass;
10013
10014 f_init(1, false);
10015 f_sleep(1.0);
10016
10017 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10018
10019 /* RA containing reason=LU */
10020 var GsmFrameNumber fn := 2342;
10021 var uint8_t ra := 2;
10022 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10023
10024 /* (set bts 0 cfg back to default) */
10025 f_vty_set_imm_ass(BSCVTY);
10026
10027 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10028 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010029 var RSL_IE_Body chan_ident_ie;
10030 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10031 setverdict(fail, "RSL Channel Identification IE is absent");
10032 mtc.stop;
10033 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010034
10035 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10036 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010037 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10038 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010039
10040 /* Only now send the Chan Act ACK */
10041 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10042
10043 /* Check that the lchan is working */
10044 var octetstring l3 := '00010203040506'O;
10045 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10046
10047 var BSSAP_N_CONNECT_ind rx_c_ind;
10048 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10049 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10050
10051 f_sleep(1.0);
10052 f_shutdown_helper();
10053}
10054
Neels Hofmeyr23158742021-09-07 19:08:07 +020010055testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10056 var RSL_Message chan_act;
10057 var RSL_Message imm_ass;
10058
10059 f_init(1, false);
10060 f_sleep(1.0);
10061
10062 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10063
10064 /* RA containing reason=LU */
10065 var GsmFrameNumber fn := 2342;
10066 var uint8_t ra := 2;
10067 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10068
10069 /* (set bts 0 cfg back to default) */
10070 f_vty_set_imm_ass(BSCVTY);
10071
10072 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10073 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
10074 var RSL_IE_Body chan_ident_ie;
10075 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10076 setverdict(fail, "RSL Channel Identification IE is absent");
10077 mtc.stop;
10078 }
10079
10080 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10081 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10082 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10083 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10084
10085 /* Only now send the Chan Act ACK */
10086 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10087
10088 /* Check that the lchan is working */
10089 var octetstring l3 := '00010203040506'O;
10090 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10091
10092 var BSSAP_N_CONNECT_ind rx_c_ind;
10093 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10094 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10095
10096 f_sleep(1.0);
10097 f_shutdown_helper();
10098}
10099
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010100testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10101 /* change Timeslot 6 before f_init() starts RSL */
10102 f_init_vty();
10103 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10104 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10105
10106 f_init(1, false);
10107 f_sleep(1.0);
10108
10109 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10110 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10111 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10112 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10113
10114 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10115 f_ts_set_chcomb(0, 0, 6, "PDCH");
10116
10117 /* block all static timeslots so that the dyn TS will be used */
10118 f_disable_all_tch_f();
10119 f_disable_all_tch_h();
10120 f_disable_all_sdcch();
10121
10122 var RSL_Message chan_act;
10123 var RSL_Message imm_ass;
10124
10125 f_init(1, false);
10126 f_sleep(1.0);
10127
10128 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10129
10130 /* RA containing reason=LU */
10131 var GsmFrameNumber fn := 2342;
10132 var uint8_t ra := 2;
10133 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10134
10135 /* (set bts 0 cfg back to default) */
10136 f_vty_set_imm_ass(BSCVTY);
10137
10138 /* Expect the dyn TS to deactivate PDCH first */
10139 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10140 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10141
10142 /* Now activation as SDCCH8 */
10143 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10144
10145 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010146 var RSL_IE_Body chan_ident_ie;
10147 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10148 setverdict(fail, "RSL Channel Identification IE is absent");
10149 mtc.stop;
10150 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010151
10152 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10153 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010154 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10155 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010156
10157 /* Only now send the Chan Act ACK */
10158 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10159
10160 /* Check that the lchan is working */
10161 var octetstring l3 := '00010203040506'O;
10162 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10163
10164 var BSSAP_N_CONNECT_ind rx_c_ind;
10165 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10166 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10167
10168 f_sleep(1.0);
10169 f_shutdown_helper();
10170}
10171
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010172testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10173 /* change Timeslot 6 before f_init() starts RSL */
10174 f_init_vty();
10175 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10176 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10177
10178 f_init(1, false);
10179 f_sleep(1.0);
10180
10181 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10182 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10183 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10184 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10185
10186 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10187 f_ts_set_chcomb(0, 0, 6, "PDCH");
10188
10189 /* block all static timeslots so that the dyn TS will be used */
10190 f_disable_all_tch_f();
10191 f_disable_all_tch_h();
10192 f_disable_all_sdcch();
10193
10194 var RSL_Message chan_act;
10195 var RSL_Message imm_ass;
10196
10197 f_init(1, false);
10198 f_sleep(1.0);
10199
10200 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10201
10202 /* RA containing reason=LU */
10203 var GsmFrameNumber fn := 2342;
10204 var uint8_t ra := 2;
10205 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10206
10207 /* (set bts 0 cfg back to default) */
10208 f_vty_set_imm_ass(BSCVTY);
10209
10210 /* Expect the dyn TS to deactivate PDCH first */
10211 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10212
10213 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10214 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10215
10216 /* continue the Osmo style PDCH Deact (usual chan rel) */
10217 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10218
10219 /* Now activation as SDCCH8 */
10220 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10221
10222 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010223 var RSL_IE_Body chan_ident_ie;
10224 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10225 setverdict(fail, "RSL Channel Identification IE is absent");
10226 mtc.stop;
10227 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010228 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10229
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010230 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10231 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010232
10233 /* Check that the lchan is working */
10234 var octetstring l3 := '00010203040506'O;
10235 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10236
10237 var BSSAP_N_CONNECT_ind rx_c_ind;
10238 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10239 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10240
10241 f_sleep(1.0);
10242 f_shutdown_helper();
10243}
10244
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010245/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10246testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10247 var MSC_ConnHdlr vc_conn;
10248
10249 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10250 f_sleep(1.0);
10251
10252 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10253 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10254 "0,0,operational,unlocked,on,rsl-up;" &
10255 "1,0,operational,unlocked,on,rsl-up;" &
10256 "2,0,operational,unlocked,on,rsl-down;" &
10257 "3,0,inoperational,locked,on,rsl-down;");
10258
10259 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10260 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10261 /* give it a moment to settle the FSM status */
10262 f_sleep(1.0);
10263
10264 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10265 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10266 * of "off"? But that's for a future patch if at all. */
10267 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10268 "0,0,operational,unlocked,on,rsl-up;" &
10269 "1,0,operational,locked,on,rsl-up;" &
10270 "2,0,operational,unlocked,on,rsl-down;" &
10271 "3,0,inoperational,locked,on,rsl-down;");
10272
10273 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10274 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10275 f_sleep(1.0);
10276 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10277 "0,0,operational,unlocked,on,rsl-up;" &
10278 "1,0,operational,locked,on,rsl-up;" &
10279 "2,0,operational,unlocked,on,rsl-down;" &
10280 "3,0,inoperational,locked,on,rsl-down;");
10281
10282 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10283 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10284 f_sleep(1.0);
10285 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10286 "0,0,operational,unlocked,on,rsl-up;" &
10287 "1,0,operational,unlocked,on,rsl-up;" &
10288 "2,0,operational,unlocked,on,rsl-down;" &
10289 "3,0,inoperational,locked,on,rsl-down;");
10290
10291 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10292 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10293 f_sleep(1.0);
10294 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10295 "0,0,operational,unlocked,on,rsl-up;" &
10296 "1,0,operational,unlocked,on,rsl-up;" &
10297 "2,0,operational,unlocked,on,rsl-down;" &
10298 "3,0,inoperational,locked,on,rsl-down;");
10299
10300 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10301 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10302 f_sleep(1.0);
10303 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10304 "0,0,operational,unlocked,on,rsl-up;" &
10305 "1,0,operational,unlocked,on,rsl-up;" &
10306 "2,0,operational,unlocked,on,rsl-down;" &
10307 "3,0,inoperational,locked,on,rsl-down;");
10308
10309 f_shutdown_helper();
10310}
10311
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010312/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10313 * Activ Ack (SYS#5627). */
10314private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10315 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030010316
10317 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10318 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010319
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
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010392 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
10393 vc_conn.done;
10394
10395 f_shutdown_helper();
10396}
10397
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010398const CounterNameVals counternames_bsc_bts_all_available_allocated := {
10399 { "all_allocated:sdcch", 0 },
10400 { "all_allocated:static_sdcch", 0 },
10401 { "all_allocated:tch", 0 },
10402 { "all_allocated:static_tch", 0 }
10403}
10404
10405private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
10406{
10407 /* Make sure counters settle first */
10408 f_sleep(1.0);
10409
10410 /* Take a baseline of counters */
10411 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
10412
10413 /* Elapse some time so that we see changes in counters, hopefully where expected */
10414 f_sleep(2.0);
10415
10416 /* Get new counters */
10417 var charstring_list all_changed := {};
10418 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
10419 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
10420
10421 /* Compare with expectations */
10422 var charstring_list all_expect_changed := {};
10423 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
10424 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
10425 }
10426 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
10427}
10428
10429testcase TC_ratectr_all_available_allocated() runs on test_CT {
10430 var ASP_RSL_Unitdata rsl_ud;
10431 var integer i;
10432 var integer chreq_total, chreq_nochan;
10433
10434 f_init(1);
10435 f_sleep(1.0);
10436
10437 /* Exhaust all dedicated SDCCH lchans.
10438 /* GSM 44.018 Table 9.1.8.2:
10439 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10440 */
10441 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10442 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10443 }
10444
10445 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
10446 * level.
10447 * All SDCCH are now occupied. */
10448 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10449
10450 /* Also fill up all remaining (TCH) channels */
10451 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
10452 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10453 }
10454
10455 /* All TCH are now also occupied */
10456 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10457 "all_allocated:tch", "all_allocated:static_tch"});
10458
10459 f_shutdown_helper();
10460}
10461
10462testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
10463 var ASP_RSL_Unitdata rsl_ud;
10464 var integer i;
10465 var integer chreq_total, chreq_nochan;
10466
10467 f_init_vty();
10468 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
10469 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10470 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
10471
10472 f_init(1, guard_timeout := 60.0);
10473 f_sleep(1.0);
10474
10475 /* The dyn TS wants to activate PDCH mode, ACK that. */
10476 var RslChannelNr chan_nr;
10477 chan_nr := valueof(t_RslChanNr_PDCH(2));
10478 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10479 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10480
10481 /* Exhaust all dedicated SDCCH lchans.
10482 /* GSM 44.018 Table 9.1.8.2:
10483 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
10484 */
10485 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
10486 f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10487 }
10488
10489 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
10490 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
10491 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
10492
10493 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
10494 * Will release them later, so remember all the DchanTuples. */
10495 var DchanTuples dyn_sddch := {};
10496 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10497
10498 /* Also occupy the seven other SDCCH of the dyn TS */
10499 for (i := 0; i < 7; i := i+1) {
10500 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
10501 }
10502
10503 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
10504 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
10505
10506 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
10507 for (i := 0; i < 5; i := i+1) {
10508 f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
10509 }
10510
10511 /* All TCH lchans are now also occupied, both static and dynamic */
10512 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
10513 "all_allocated:tch", "all_allocated:static_tch"});
10514
10515 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
10516 * incrementing. */
10517 var BssmapCause cause := 0;
10518 var DchanTuple dt := dyn_sddch[0];
10519 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10520 f_exp_chan_rel_and_clear(dt, 0);
10521
10522 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
10523 * count as occupied, so those still both increment. */
10524 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
10525 "all_allocated:tch", "all_allocated:static_tch"});
10526
10527 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
10528 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
10529 dt := dyn_sddch[i];
10530 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
10531 f_exp_chan_rel_and_clear(dt, 0);
10532 }
10533
10534 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
10535 chan_nr := valueof(t_RslChanNr_PDCH(2));
10536 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10537 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
10538
10539 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
10540 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
10541
10542 /* clean up config */
10543 f_ts_reset_chcomb(0);
10544
10545 f_shutdown_helper();
10546}
10547
Harald Welte28d943e2017-11-25 15:00:50 +010010548control {
Harald Welte898113b2018-01-31 18:32:21 +010010549 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010550 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010551 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020010552 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
10553 * these in the AoIP test suite. */
10554 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10555 execute( TC_stat_num_msc_connected_1() );
10556 execute( TC_stat_num_msc_connected_2() );
10557 execute( TC_stat_num_msc_connected_3() );
10558 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020010559 execute( TC_stat_num_bts_connected_1() );
10560 execute( TC_stat_num_bts_connected_2() );
10561 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010562 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010563 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010564 execute( TC_ctrl_location() );
10565 }
Harald Welte898113b2018-01-31 18:32:21 +010010566
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010567 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010568 execute( TC_si2quater_2_earfcns() );
10569 execute( TC_si2quater_3_earfcns() );
10570 execute( TC_si2quater_4_earfcns() );
10571 execute( TC_si2quater_5_earfcns() );
10572 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010573 execute( TC_si2quater_12_earfcns() );
10574 execute( TC_si2quater_23_earfcns() );
10575 execute( TC_si2quater_32_earfcns() );
10576 execute( TC_si2quater_33_earfcns() );
10577 execute( TC_si2quater_42_earfcns() );
10578 execute( TC_si2quater_48_earfcns() );
10579 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010580 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010581 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010582
Harald Welte898113b2018-01-31 18:32:21 +010010583 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010584 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010585 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010586 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010587 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010588 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010589 execute( TC_chan_act_ack_est_ind_noreply() );
10590 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010591 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010592 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010593 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010594 execute( TC_chan_rel_rll_rel_ind() );
10595 execute( TC_chan_rel_conn_fail() );
10596 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010597 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10598 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010599 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010600 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010601 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010602 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010603 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010604 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010605
Harald Weltecfe2c962017-12-15 12:09:32 +010010606 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010607
10608 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010609 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010610 execute( TC_assignment_csd() );
10611 execute( TC_assignment_ctm() );
10612 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010613 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10614 execute( TC_assignment_aoip_tla_v6() );
10615 }
Harald Welte235ebf12017-12-15 14:18:16 +010010616 execute( TC_assignment_fr_a5_0() );
10617 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010618 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010619 execute( TC_assignment_fr_a5_1_codec_missing() );
10620 }
Harald Welte235ebf12017-12-15 14:18:16 +010010621 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010622 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010623 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010624 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010625 execute( TC_ciph_mode_a5_0() );
10626 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010627 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010628 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010629 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010630 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010631
Harald Welte60aa5762018-03-21 19:33:13 +010010632 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010633 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010634 execute( TC_assignment_codec_hr() );
10635 execute( TC_assignment_codec_efr() );
10636 execute( TC_assignment_codec_amr_f() );
10637 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010638
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010639 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010640 execute( TC_assignment_codec_amr_f_S1() );
10641 execute( TC_assignment_codec_amr_h_S1() );
10642 execute( TC_assignment_codec_amr_f_S124() );
10643 execute( TC_assignment_codec_amr_h_S124() );
10644 execute( TC_assignment_codec_amr_f_S0() );
10645 execute( TC_assignment_codec_amr_f_S02() );
10646 execute( TC_assignment_codec_amr_f_S024() );
10647 execute( TC_assignment_codec_amr_f_S0247() );
10648 execute( TC_assignment_codec_amr_h_S0() );
10649 execute( TC_assignment_codec_amr_h_S02() );
10650 execute( TC_assignment_codec_amr_h_S024() );
10651 execute( TC_assignment_codec_amr_h_S0247() );
10652 execute( TC_assignment_codec_amr_f_S01234567() );
10653 execute( TC_assignment_codec_amr_f_S0234567() );
10654 execute( TC_assignment_codec_amr_f_zero() );
10655 execute( TC_assignment_codec_amr_f_unsupp() );
10656 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010657 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10658 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010659 execute( TC_assignment_codec_amr_f_start_mode_4() );
10660 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010661 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010662 }
Harald Welte60aa5762018-03-21 19:33:13 +010010663
Philipp Maierac09bfc2019-01-08 13:41:39 +010010664 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10665 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10666 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10667 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10668 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10669 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10670 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10671 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10672 execute( TC_assignment_codec_req_hr_fr() );
10673 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010674 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10675 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10676 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010677
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010678 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010679
Harald Welte898113b2018-01-31 18:32:21 +010010680 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010681 execute( TC_rll_est_ind_inact_lchan() );
10682 execute( TC_rll_est_ind_inval_sapi1() );
10683 execute( TC_rll_est_ind_inval_sapi3() );
10684 execute( TC_rll_est_ind_inval_sacch() );
10685
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010686 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10687 execute( TC_tch_dlci_link_id_sapi() );
10688
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010689 /* SAPI N Reject triggered by RLL establishment failures */
10690 execute( TC_rll_rel_ind_sapi_n_reject() );
10691 execute( TC_rll_err_ind_sapi_n_reject() );
10692 execute( TC_rll_timeout_sapi_n_reject() );
10693
Harald Welte898113b2018-01-31 18:32:21 +010010694 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010695 execute( TC_paging_imsi_nochan() );
10696 execute( TC_paging_tmsi_nochan() );
10697 execute( TC_paging_tmsi_any() );
10698 execute( TC_paging_tmsi_sdcch() );
10699 execute( TC_paging_tmsi_tch_f() );
10700 execute( TC_paging_tmsi_tch_hf() );
10701 execute( TC_paging_imsi_nochan_cgi() );
10702 execute( TC_paging_imsi_nochan_lac_ci() );
10703 execute( TC_paging_imsi_nochan_ci() );
10704 execute( TC_paging_imsi_nochan_lai() );
10705 execute( TC_paging_imsi_nochan_lac() );
10706 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010707 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10708 execute( TC_paging_imsi_nochan_rnc() );
10709 execute( TC_paging_imsi_nochan_lac_rnc() );
10710 execute( TC_paging_imsi_nochan_lacs() );
10711 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010712 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010713 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010714 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010715 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010716 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010717
10718 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010719 execute( TC_rsl_unknown_unit_id() );
10720
10721 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010722
10723 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010724 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010725 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010726 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010727 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010728 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010729 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010730
Harald Welte261af4b2018-02-12 21:20:39 +010010731 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010732 execute( TC_ho_int_a5_0() );
10733 execute( TC_ho_int_a5_1() );
10734 execute( TC_ho_int_a5_3() );
10735 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010736 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010737
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010738 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010739 execute( TC_ho_out_fail_no_msc_response() );
10740 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010741 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010742
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010743 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010744 execute( TC_ho_into_this_bsc_a5_0() );
10745 execute( TC_ho_into_this_bsc_a5_1() );
10746 execute( TC_ho_into_this_bsc_a5_3() );
10747 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010748 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10749 execute( TC_ho_into_this_bsc_tla_v6() );
10750 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010751 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010752 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010753 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10754 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010755 execute( TC_ho_in_fail_msc_clears() );
10756 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10757 execute( TC_ho_in_fail_no_detect() );
10758 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010759
Neels Hofmeyr91401012019-07-11 00:42:35 +020010760 execute( TC_ho_neighbor_config_1() );
10761 execute( TC_ho_neighbor_config_2() );
10762 execute( TC_ho_neighbor_config_3() );
10763 execute( TC_ho_neighbor_config_4() );
10764 execute( TC_ho_neighbor_config_5() );
10765 execute( TC_ho_neighbor_config_6() );
10766 execute( TC_ho_neighbor_config_7() );
10767
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010768 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010769 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010770 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010771
10772 execute( TC_dyn_pdch_ipa_act_deact() );
10773 execute( TC_dyn_pdch_ipa_act_nack() );
10774 execute( TC_dyn_pdch_osmo_act_deact() );
10775 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010776 if (mp_enable_dyn_sdcch8_test) {
10777 execute( TC_dyn_ts_sdcch8_act_deact() );
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +020010778 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
Vadim Yanitskiy07e4b632021-10-12 14:04:45 +030010779 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010780 execute( TC_dyn_ts_sdcch8_act_nack() );
10781 }
Harald Welte99f3ca02018-06-14 13:40:29 +020010782
Stefan Sperling0796a822018-10-05 13:01:39 +020010783 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010784 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010785
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010786 /* Power control related */
10787 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010788 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010789
10790 /* MSC pooling */
10791 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10792 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10793 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10794 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10795 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10796 execute( TC_mscpool_L3Compl_on_1_msc() );
10797 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10798 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10799 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10800 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10801 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10802 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10803 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10804 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10805 execute( TC_mscpool_paging_and_response_imsi() );
10806 execute( TC_mscpool_paging_and_response_tmsi() );
10807 execute( TC_mscpool_no_allow_attach_round_robin() );
10808 execute( TC_mscpool_no_allow_attach_valid_nri() );
10809 }
10810
Harald Welte99f3ca02018-06-14 13:40:29 +020010811 execute( TC_early_conn_fail() );
10812 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010813 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010814
Philipp Maier783681c2020-07-16 16:47:06 +020010815 /* Emergency call handling (deny / allow) */
10816 execute( TC_assignment_emerg_setup_allow() );
10817 execute( TC_assignment_emerg_setup_deny_msc() );
10818 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010819 execute( TC_emerg_premption() );
10820
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010821 /* Frequency hopping parameters handling */
10822 execute( TC_fh_params_chan_activ() );
10823 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010824 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010825 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010826 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010827
10828 if (mp_enable_lcs_tests) {
10829 execute( TC_lcs_loc_req_for_active_ms() );
10830 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10831 execute( TC_lcs_loc_req_for_idle_ms() );
10832 execute( TC_lcs_loc_req_no_subscriber() );
10833 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10834 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10835 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10836 execute( TC_cm_service_during_lcs_loc_req() );
10837 execute( TC_ho_during_lcs_loc_req() );
10838 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010839
10840 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010841
10842 execute( TC_refuse_chan_act_to_vamos() );
10843 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010844
10845 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010846
10847 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010848
10849 execute( TC_imm_ass_post_chan_ack() );
10850 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010851 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010852 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010853 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010854
10855 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010856
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020010857 execute( TC_ratectr_all_available_allocated() );
10858 execute( TC_ratectr_all_available_allocated_dyn() );
10859
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010860 execute( TC_lost_sdcch_during_assignment() );
Harald Welte28d943e2017-11-25 15:00:50 +010010861}
10862
10863}