blob: 2b3703fb2eff597a3afd520f28550d752e7ab568 [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 Hofmeyr4f118412020-06-04 15:25:10 +020023import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010024import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010025import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010026import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010027import from IPL4asp_Types all;
28
Harald Welte6f521d82017-12-11 19:52:02 +010029import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020030import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020031import from BSSAP_LE_Adapter all;
32import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020033import from BSSAP_LE_Types all;
34import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010035import from BSSAP_CodecPort all;
36import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010037import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010038import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010039import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020040import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010041import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010042import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010043import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010044import from MGCP_Templates all;
45import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020046import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010047
Harald Welte96c94412017-12-09 03:12:45 +010048import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010049import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010050import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010051
Daniel Willmannebdecc02020-08-12 15:30:17 +020052import from StatsD_Types all;
53import from StatsD_CodecPort all;
54import from StatsD_CodecPort_CtrlFunct all;
55import from StatsD_Checker all;
56
Harald Weltebc03c762018-02-12 18:09:38 +010057import from Osmocom_VTY_Functions all;
58import from TELNETasp_PortType all;
59
Harald Welte6f521d82017-12-11 19:52:02 +010060import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010061import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010062import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010063import from L3_Templates all;
64import from GSM_RR_Types all;
65
Stefan Sperlingc307e682018-06-14 15:15:46 +020066import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010067import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020068import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010069
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010070import from SCCPasp_Types all;
71
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020072import from GSM_SystemInformation all;
73import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020074import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020075
Harald Welte5d1a2202017-12-13 19:51:29 +010076const integer NUM_BTS := 3;
Neels Hofmeyrf246a922020-05-13 02:27:10 +020077const integer NUM_MSC := 3;
Harald Welteae026692017-12-09 01:03:01 +010078const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010079
Harald Welte799c97b2017-12-14 17:50:30 +010080/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020081const integer NUM_TCHH_PER_BTS := 2;
82const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020083const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010084
Harald Welte4003d112017-12-09 22:35:39 +010085
Harald Welte21b46bd2017-12-17 19:46:32 +010086/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +010087type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +010088 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +010089 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +010090}
91
Neels Hofmeyr22c3f792020-06-17 02:49:28 +020092/* Default list of counters for an 'msc' entity. */
93const CounterNameVals counternames_msc_mscpool := {
94 { "mscpool:subscr:new", 0 },
95 { "mscpool:subscr:known", 0 },
96 { "mscpool:subscr:reattach", 0 },
97 { "mscpool:subscr:attach_lost", 0 },
98 { "mscpool:subscr:paged", 0 }
99};
100
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000101/* List of global mscpool counters, not related to a specific 'msc' entity. */
102const CounterNameVals counternames_bsc_mscpool := {
103 { "mscpool:subscr:no_msc", 0 }
104};
105
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000106/* Default list of counters for 'bsc' and 'bts' entities. */
107const CounterNameVals counternames_bsc_bts_handover := {
108 { "assignment:attempted", 0 },
109 { "assignment:completed", 0 },
110 { "assignment:stopped", 0 },
111 { "assignment:no_channel", 0 },
112 { "assignment:timeout", 0 },
113 { "assignment:failed", 0 },
114 { "assignment:error", 0 },
115
116 { "handover:attempted", 0 },
117 { "handover:completed", 0 },
118 { "handover:stopped", 0 },
119 { "handover:no_channel", 0 },
120 { "handover:timeout", 0 },
121 { "handover:failed", 0 },
122 { "handover:error", 0 },
123
124 { "intra_cell_ho:attempted", 0 },
125 { "intra_cell_ho:completed", 0 },
126 { "intra_cell_ho:stopped", 0 },
127 { "intra_cell_ho:no_channel", 0 },
128 { "intra_cell_ho:timeout", 0 },
129 { "intra_cell_ho:failed", 0 },
130 { "intra_cell_ho:error", 0 },
131
132 { "intra_bsc_ho:attempted", 0 },
133 { "intra_bsc_ho:completed", 0 },
134 { "intra_bsc_ho:stopped", 0 },
135 { "intra_bsc_ho:no_channel", 0 },
136 { "intra_bsc_ho:timeout", 0 },
137 { "intra_bsc_ho:failed", 0 },
138 { "intra_bsc_ho:error", 0 },
139
140 { "interbsc_ho_out:attempted", 0 },
141 { "interbsc_ho_out:completed", 0 },
142 { "interbsc_ho_out:stopped", 0 },
143 { "interbsc_ho_out:timeout", 0 },
144 { "interbsc_ho_out:failed", 0 },
145 { "interbsc_ho_out:error", 0 },
146
147 { "interbsc_ho_in:attempted", 0 },
148 { "interbsc_ho_in:completed", 0 },
149 { "interbsc_ho_in:stopped", 0 },
150 { "interbsc_ho_in:no_channel", 0 },
151 { "interbsc_ho_in:timeout", 0 },
152 { "interbsc_ho_in:failed", 0 },
153 { "interbsc_ho_in:error", 0 }
154};
155
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200156/* Set of all System Information received during one RSL port's startup.
157 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
158 * broadcast that SI type. That will be reflected as 'omit' here.
159 */
160type record SystemInformationConfig {
161 SystemInformationType1 si1 optional,
162 SystemInformationType2 si2 optional,
163 SystemInformationType2bis si2bis optional,
164 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200165 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200166 SystemInformationType3 si3 optional,
167 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100168 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200169 SystemInformationType5 si5 optional,
170 SystemInformationType5bis si5bis optional,
171 SystemInformationType5ter si5ter optional,
172 SystemInformationType6 si6 optional
173};
174
175const SystemInformationConfig SystemInformationConfig_omit := {
176 si1 := omit,
177 si2 := omit,
178 si2bis := omit,
179 si2ter := omit,
180 si2quater := omit,
181 si3 := omit,
182 si4 := omit,
183 si13 := omit,
184 si5 := omit,
185 si5bis := omit,
186 si5ter := omit,
187 si6 := omit
188};
189
190/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
191template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
192 template uint3_t meas_bw := 3)
193:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
194 meas_bw_presence := '1'B,
195 meas_bw := meas_bw);
196
197/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200198template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200199 template uint3_t prio := 3,
200 template (present) uint5_t thresh_high := 20,
201 template uint5_t thresh_low := 10,
202 template uint5_t qrxlevmin := 22)
203:= tr_EUTRAN_NeighbourCells(
204 cell_desc_list := cell_desc_list,
205 prio_presence := '1'B,
206 prio := prio,
207 thresh_high := thresh_high,
208 thresh_low_presence := '1'B,
209 thresh_low := thresh_low,
210 qrxlevmin_presence := '1'B,
211 qrxlevmin := qrxlevmin);
212
213template SystemInformationConfig SystemInformationConfig_default := {
214 si1 := {
215 cell_chan_desc := '8FB38000000000000000000000000000'O,
216 rach_control := {
217 max_retrans := RACH_MAX_RETRANS_7,
218 tx_integer := '1001'B,
219 cell_barr_access := false,
220 re_not_allowed := true,
221 acc := '0000010000000000'B
222 },
223 rest_octets := ?
224 },
225 si2 := {
226 bcch_freq_list := '00000000000000000000000000000000'O,
227 ncc_permitted := '11111111'B,
228 rach_control := {
229 max_retrans := RACH_MAX_RETRANS_7,
230 tx_integer := '1001'B,
231 cell_barr_access := false,
232 re_not_allowed := true,
233 acc := '0000010000000000'B
234 }
235 },
236 si2bis := omit,
237 si2ter := {
238 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
239 rest_octets := ?
240 },
241 si2quater := {
242 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
243 },
244 si3 := {
245 cell_id := 0,
246 lai := {
247 mcc_mnc := '001F01'H,
248 lac := 1
249 },
250 ctrl_chan_desc := {
251 msc_r99 := true,
252 att := true,
253 bs_ag_blks_res := 1,
254 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
255 si22ind := false,
256 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
257 spare := '00'B,
258 bs_pa_mfrms := 3,
259 t3212 := 30
260 },
261 cell_options := {
262 dn_ind := false,
263 pwrc := false,
264 dtx := MS_SHALL_USE_UL_DTX,
265 radio_link_tout_div4 := 7
266 },
267 cell_sel_par := {
268 cell_resel_hyst_2dB := 2,
269 ms_txpwr_max_cch := 7,
270 acs := '0'B,
271 neci := true,
272 rxlev_access_min := 0
273 },
274 rach_control := {
275 max_retrans := RACH_MAX_RETRANS_7,
276 tx_integer := '1001'B,
277 cell_barr_access := false,
278 re_not_allowed := true,
279 acc := '0000010000000000'B
280 },
281 rest_octets := {
282 sel_params := {
283 presence := '0'B,
284 params := omit
285 },
286 pwr_offset := {
287 presence := '0'B,
288 offset := omit
289 },
290 si_2ter_ind := '1'B,
291 early_cm_ind := '0'B,
292 sched_where := {
293 presence := '0'B,
294 where := omit
295 },
296 gprs_ind := {
297 presence := '1'B,
298 ind := {
299 ra_colour := 0,
300 si13_pos := '0'B
301 }
302 },
303 umts_early_cm_ind := '1'B,
304 si2_quater_ind := {
305 presence := '1'B,
306 ind := '0'B
307 },
308 iu_mode_ind := omit,
309 si21_ind := {
310 presence := '0'B,
311 pos := omit
312 }
313 }
314 },
315 si4 := {
316 lai := {
317 mcc_mnc := '001F01'H,
318 lac := 1
319 },
320 cell_sel_par := {
321 cell_resel_hyst_2dB := 2,
322 ms_txpwr_max_cch := 7,
323 acs := '0'B,
324 neci := true,
325 rxlev_access_min := 0
326 },
327 rach_control := {
328 max_retrans := RACH_MAX_RETRANS_7,
329 tx_integer := '1001'B,
330 cell_barr_access := false,
331 re_not_allowed := true,
332 acc := '0000010000000000'B
333 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200334 cbch_chan_desc := {
335 iei := '64'O,
336 v := {
337 chan_nr := {
338 u := {
339 sdcch4 := {
340 tag := '001'B,
341 sub_chan := 2
342 }
343 },
344 tn := 0
345 },
346 tsc := 2,
347 h := false,
348 arfcn := 871,
349 maio_hsn := omit
350 }
351 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200352 cbch_mobile_alloc := omit,
353 rest_octets := {
354 sel_params := {
355 presence := '0'B,
356 params := omit
357 },
358 pwr_offset := {
359 presence := '0'B,
360 offset := omit
361 },
362 gprs_ind := {
363 presence := '1'B,
364 ind := {
365 ra_colour := 0,
366 si13_pos := '0'B
367 }
368 },
369 s_presence := '0'B,
370 s := omit
371 }
372 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100373 si13 := {
374 rest_octets := {
375 presence := '1'B,
376 bcch_change_mark := ?,
377 si_change_field := '0000'B,
378 presence2 := '0'B,
379 si13_change_mark := omit,
380 gprs_ma := omit,
381 zero := '0'B, /* PBCCH not present in cell */
382 rac := 0,
383 spgc_ccch_sup := '0'B,
384 priority_access_thr := '110'B,
385 network_control_order := '00'B,
386 gprs_cell_opts := {
387 nmo := '01'B,
388 t3168 := '011'B,
389 t3192 := '010'B,
390 drx_timer_max := '011'B,
391 access_burst_type := '0'B,
392 control_ack_type := '1'B,
393 bs_cv_max := 15,
394 pan_presence := '1'B,
395 pan_dec := 1,
396 pan_inc := 1,
397 pan_max := '111'B,
398 ext_info_presence := ?,
399 ext_info_length := *,
400 ext_info := *
401 },
402 gprs_pwr_ctrl_params := {
403 alpha := 0,
404 t_avg_w := '10000'B,
405 t_avg_t := '10000'B,
406 pc_meas_chan := '0'B,
407 n_avg_i := '1000'B
408 }
409 }
410 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200411 si5 := {
412 bcch_freq_list := '10000000000000000000000000000000'O
413 },
414 si5bis := omit,
415 si5ter := {
416 extd_bcch_freq_list := '9E050020000000000000000000000000'O
417 },
418 si6 := {
419 cell_id := 0,
420 lai := {
421 mcc_mnc := '001F01'H,
422 lac := 1
423 },
424 cell_options := {
425 dtx_ext := '1'B,
426 pwrc := false,
427 dtx := '01'B,
428 radio_link_timeout := '0111'B
429 },
430 ncc_permitted := '11111111'B,
431 rest_octets := ?
432 }
433 };
434
435
436/* List of all the System Information received on all RSL ports */
437type record of SystemInformationConfig SystemInformationConfig_list;
438
439function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
440{
441 var RSL_IE_Body sysinfo_type_ie;
442 var RSL_IE_SysinfoType si_type;
443 var octetstring data;
444
445 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
446 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
447 mtc.stop;
448 }
449 si_type := sysinfo_type_ie.sysinfo_type;
450
451 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
452 var RSL_IE_Body bcch_ie;
453 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
454 data := bcch_ie.other.payload;
455 }
456 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
457 var RSL_IE_Body l3_ie;
458 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
459 data := l3_ie.l3_info.payload;
460 }
461 } else {
462 setverdict(fail, "Don't understand this System Information message");
463 mtc.stop;
464 }
465
466 var boolean handled := false;
467
468 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
469 handled := true;
470
471 if (si_type == RSL_SYSTEM_INFO_1) {
472 if (not isbound(data)) {
473 si.si1 := omit;
474 } else {
475 si.si1 := dec_SystemInformation(data).payload.si1;
476 }
477 } else if (si_type == RSL_SYSTEM_INFO_2) {
478 if (not isbound(data)) {
479 si.si2 := omit;
480 } else {
481 si.si2 := dec_SystemInformation(data).payload.si2;
482 }
483 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
484 if (not isbound(data)) {
485 si.si2bis := omit;
486 } else {
487 si.si2bis := dec_SystemInformation(data).payload.si2bis;
488 }
489 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
490 if (not isbound(data)) {
491 si.si2ter := omit;
492 } else {
493 si.si2ter := dec_SystemInformation(data).payload.si2ter;
494 }
495 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
496 if (not isbound(data)) {
497 si.si2quater := {};
498 } else {
499 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
500 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
501 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
502 }
503 } else if (si_type == RSL_SYSTEM_INFO_3) {
504 if (not isbound(data)) {
505 si.si3 := omit;
506 } else {
507 si.si3 := dec_SystemInformation(data).payload.si3;
508 }
509 } else if (si_type == RSL_SYSTEM_INFO_4) {
510 if (not isbound(data)) {
511 si.si4 := omit;
512 } else {
513 si.si4 := dec_SystemInformation(data).payload.si4;
514 }
515 } else if (si_type == RSL_SYSTEM_INFO_13) {
516 if (not isbound(data)) {
517 si.si13 := omit;
518 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100519 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200520 }
521 } else {
522 handled := false;
523 }
524 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
525 handled := true;
526
527 if (si_type == RSL_SYSTEM_INFO_5) {
528 if (not isbound(data)) {
529 si.si5 := omit;
530 } else {
531 si.si5 := dec_SystemInformation(data).payload.si5;
532 }
533 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
534 if (not isbound(data)) {
535 si.si5bis := omit;
536 } else {
537 si.si5bis := dec_SystemInformation(data).payload.si5bis;
538 }
539 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
540 if (not isbound(data)) {
541 si.si5ter := omit;
542 } else {
543 si.si5ter := dec_SystemInformation(data).payload.si5ter;
544 }
545 } else if (si_type == RSL_SYSTEM_INFO_6) {
546 if (not isbound(data)) {
547 si.si6 := omit;
548 } else {
549 si.si6 := dec_SystemInformation(data).payload.si6;
550 }
551 } else {
552 handled := false;
553 }
554 }
555
556 if (not handled) {
557 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
558 }
559}
560
Harald Weltea4ca4462018-02-09 00:17:14 +0100561type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100562 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100563 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100564 /* RSL common Channel Port (for RSL_Emulation) */
565 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100566 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100567 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100568 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200569 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
570 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100571
Daniel Willmann191e0d92018-01-17 12:44:35 +0100572 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100573 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100574
Daniel Willmannebdecc02020-08-12 15:30:17 +0200575 /* StatsD */
576 var StatsD_Checker_CT vc_STATSD;
577
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200578 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200579 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100580 /* for old legacy-tests only */
581 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200582 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100583
Harald Welte21b46bd2017-12-17 19:46:32 +0100584 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100585 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100586
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200587 /* Osmux is enabled through VTY */
588 var boolean g_osmux_enabled := false;
589
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100590 /*Configure T(tias) over VTY, seconds */
591 var integer g_bsc_sccp_timer_ias := 7 * 60;
592 /*Configure T(tiar) over VTY, seconds */
593 var integer g_bsc_sccp_timer_iar := 15 * 60;
594
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200595 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100596 timer T_guard := 30.0;
597
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200598 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000599 var CounterNameValsList g_ctr_bsc;
600 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200601
602 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
603 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100604}
605
606modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100607 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100608 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100609 /* port number to which to establish the IPA OML connections */
610 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100611 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100612 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100613 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100614 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200615 /* port number to which to listen for STATSD metrics */
616 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100617 /* IP address at which the test binds */
618 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100619
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200620 RAN_Configurations mp_bssap_cfg := {
621 {
622 transport := BSSAP_TRANSPORT_AoIP,
623 sccp_service_type := "mtp3_itu",
624 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
625 own_pc := 185, /* 0.23.1 first MSC emulation */
626 own_ssn := 254,
627 peer_pc := 187, /* 0.23.3 osmo-bsc */
628 peer_ssn := 254,
629 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200630 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200631 },
632 {
633 transport := BSSAP_TRANSPORT_AoIP,
634 sccp_service_type := "mtp3_itu",
635 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
636 own_pc := 2, /* 0.0.2 second MSC emulation */
637 own_ssn := 254,
638 peer_pc := 187, /* 0.23.3 osmo-bsc */
639 peer_ssn := 254,
640 sio := '83'O,
641 rctx := 2
642 },
643 {
644 transport := BSSAP_TRANSPORT_AoIP,
645 sccp_service_type := "mtp3_itu",
646 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
647 own_pc := 3, /* 0.0.3 third MSC emulation */
648 own_ssn := 254,
649 peer_pc := 187, /* 0.23.3 osmo-bsc */
650 peer_ssn := 254,
651 sio := '83'O,
652 rctx := 3
653 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100654 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200655
Harald Welte47cd0e32020-08-21 12:39:11 +0200656 BSSAP_LE_Configuration mp_bssap_le_cfg := {
657 sccp_service_type := "mtp3_itu",
658 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200659 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200660 own_ssn := 252, /* SMLC side SSN */
661 peer_pc := 187, /* 0.23.3 osmo-bsc */
662 peer_ssn := 250, /* BSC side SSN */
663 sio := '83'O,
664 rctx := 6
665 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200666 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200667
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200668 /* Whether to enable osmux tests. Can be dropped completely and enable
669 unconditionally once new version of osmo-bsc is released (current
670 version: 1.4.1) */
671 boolean mp_enable_osmux_test := true;
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100672 /* Value set in osmo-bsc.cfg "ms max power" */
673 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100674}
675
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200676private function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200677
678 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200679 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200680 pars.aoip := true;
681 } else {
682 pars.aoip := false;
683 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100684 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200685 pars.mscpool.bssap_idx := bssap_idx;
Philipp Maier48604732018-10-09 15:00:37 +0200686
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200687 /* BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2 */
688 pars.expect_tsc := 2;
689
Philipp Maier48604732018-10-09 15:00:37 +0200690 return pars;
691}
692
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200693/* Convenience functions for rate counters using g_ctr_msc. */
694
695private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
696 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
697 log("initial msc rate counters: ", g_ctr_msc);
698}
699
700private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200701 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200702}
703
704/* f_ctrs_msc_init();
705 * f_do_thing(on_msc := 0);
706 * f_do_thing(on_msc := 0);
707 * f_do_other(on_msc := 1);
708 * f_ctrs_msc_add(0, "thing", 2);
709 * f_ctrs_msc_add(1, "other");
710 * f_ctrs_msc_verify();
711 */
712private function f_ctrs_msc_verify() runs on test_CT {
713 log("verifying msc rate counters: ", g_ctr_msc);
714 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
715}
716
717/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
718 * f_ctrs_msc_init();
719 * f_do_thing(on_msc := 0);
720 * f_do_thing(on_msc := 0);
721 * f_do_thing(on_msc := 0);
722 * f_ctrs_msc_expect(0, "thing", 3);
723 */
724private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
725 f_ctrs_msc_add(msc_nr, countername, val);
726 f_ctrs_msc_verify();
727}
728
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000729/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
730
731private function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
732 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
733 log("initial bts rate counters: ", g_ctr_bts);
734 f_ctrs_bsc_init(counternames);
735}
736
737private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
738 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
739 f_ctrs_bsc_add(countername, val);
740}
741
742/* f_ctrs_bsc_and_bts_init();
743 * f_do_thing(on_bts := 0);
744 * f_do_thing(on_bts := 0);
745 * f_do_other(on_bts := 1);
746 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
747 * f_ctrs_bsc_and_bts_add(1, "other");
748 * f_ctrs_bsc_and_bts_verify();
749 */
750private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
751 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
752 f_ctrs_bsc_verify();
753}
754
755/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
756 * f_ctrs_bsc_and_bts_init();
757 * f_do_thing(on_bts := 0);
758 * f_do_thing(on_bts := 0);
759 * f_do_thing(on_bts := 0);
760 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
761 */
762private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
763 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
764 f_ctrs_bsc_and_bts_verify();
765}
766
767
768/* Convenience functions for rate counters using g_ctr_bsc. */
769
770private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
771 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
772 log("initial bsc rate counters: ", g_ctr_bsc);
773}
774
775private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
776 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
777}
778
779/* f_ctrs_bsc_init();
780 * f_do_thing();
781 * f_do_thing();
782 * f_do_other();
783 * f_ctrs_bsc_add("thing", 2);
784 * f_ctrs_bsc_add("other");
785 * f_ctrs_bsc_verify();
786 */
787private function f_ctrs_bsc_verify() runs on test_CT {
788 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
789}
790
791/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
792 * f_ctrs_bsc_init();
793 * f_do_thing();
794 * f_ctrs_bsc_expect("thing", 1);
795 */
796private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
797 f_ctrs_bsc_add(countername, val);
798 f_ctrs_bsc_verify();
799}
800
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200801
Philipp Maier282ca4b2018-02-27 17:17:00 +0100802private function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200803 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100804 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200805 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100806}
807
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200808private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100809 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200810 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100811 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200812 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
813 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100814 T.start;
815 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200816 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
817 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200818 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100819 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200820 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200821 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100822 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200823 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200824 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100825 repeat;
826 }
827 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200828 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200829 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200830 /* If we received a RESET after ours was sent, it
831 may be a race condition where the other peer beacame
832 available after we sent it, but we are in a desired
833 state anyway, so go forward. */
834 if (not reset_received) {
835 setverdict(fail);
836 }
837 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100838 }
Harald Welte28d943e2017-11-25 15:00:50 +0100839}
840
Harald Welteae026692017-12-09 01:03:01 +0100841type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100842 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100843 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100844 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100845 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100846 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100847 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100848 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100849 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100850}
851
Harald Welte21b46bd2017-12-17 19:46:32 +0100852/*! Start the IPA/RSL related bits for one IPA_Client.
853 * \param clnt IPA_Client for which to establish
854 * \param bsc_host IP address / hostname of the BSC
855 * \param bsc_port TCP port number of the BSC
856 * \param i number identifying this BTS
857 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100858function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
859 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100860runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100861 timer T := 10.0;
862
Harald Welte96c94412017-12-09 03:12:45 +0100863 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100864 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
865 clnt.ccm_pars := c_IPA_default_ccm_pars;
866 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
867 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100868 if (handler_mode) {
869 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100870 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100871 }
Harald Welteae026692017-12-09 01:03:01 +0100872
873 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100874 if (handler_mode) {
875 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
876 } else {
877 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
878 }
Harald Welteae026692017-12-09 01:03:01 +0100879
Harald Welte5d1a2202017-12-13 19:51:29 +0100880 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100881 if (handler_mode) {
882 clnt.vc_RSL.start(RSL_Emulation.main());
883 return;
884 }
Harald Welteae026692017-12-09 01:03:01 +0100885
886 /* wait for IPA RSL link to connect and send ID ACK */
887 T.start;
888 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700889 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100890 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700891 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100892 }
Harald Welte60e823a2017-12-10 14:10:59 +0100893 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100894 [] IPA_RSL[i].receive { repeat }
895 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100896 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200897 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100898 }
899 }
900}
901
Harald Welte12055472018-03-17 20:10:08 +0100902function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
903 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
904 return;
905 }
906 clnt.vc_IPA.stop;
907 if (isbound(clnt.vc_RSL)) {
908 clnt.vc_RSL.stop;
909 }
910}
911
Harald Welte21b46bd2017-12-17 19:46:32 +0100912/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100913function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
914 timer T := secs_max;
915 T.start;
916 while (true) {
917 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
918 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100919 /* the 'degraded' state exists from OML connection time, and we have to wait
920 * until all MO's are initialized */
921 T.start(1.0);
922 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100923 return;
924 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100925 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100926 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100927 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200928 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100929 }
930 }
931}
932
Harald Welte21b46bd2017-12-17 19:46:32 +0100933/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100934altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100935 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100936 [] T_guard.timeout {
937 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200938 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100939 }
Harald Welte60e823a2017-12-10 14:10:59 +0100940 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200941 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100942 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200943 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100944 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100945 }
Harald Welte28d943e2017-11-25 15:00:50 +0100946}
947
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100948altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200949 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100950 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +0200951 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100952 }
953}
954
Daniel Willmann191e0d92018-01-17 12:44:35 +0100955function f_init_mgcp(charstring id) runs on test_CT {
956 id := id & "-MGCP";
957
958 var MGCPOps ops := {
959 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
960 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
961 };
962 var MGCP_conn_parameters mgcp_pars := {
963 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +0100964 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +0100965 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200966 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +0200967 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
968 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200969 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +0100970 };
971
972 vc_MGCP := MGCP_Emulation_CT.create(id);
973 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
974}
975
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200976/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
977 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
978 * OsmuxCID IE.
979 */
980private function f_vty_allow_osmux(boolean allow) runs on test_CT {
981 f_vty_enter_cfg_msc(BSCVTY, 0);
982 if (allow) {
983 f_vty_transceive(BSCVTY, "osmux on");
984 } else {
985 f_vty_transceive(BSCVTY, "osmux off");
986 }
987 f_vty_transceive(BSCVTY, "exit");
988 f_vty_transceive(BSCVTY, "exit");
989 g_osmux_enabled := allow;
990}
991
Max2253c0b2018-11-06 19:28:05 +0100992function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +0200993 if (BSCVTY.checkstate("Mapped")) {
994 /* skip initialization if already executed once */
995 return;
996 }
Harald Weltebc03c762018-02-12 18:09:38 +0100997 map(self:BSCVTY, system:BSCVTY);
998 f_vty_set_prompts(BSCVTY);
999 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001000 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1001 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001002}
1003
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001004private function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001005{
1006 // log on TTCN3 log output
1007 log(log_msg);
1008 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001009 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001010}
1011
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001012private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1013{
1014 if (rsl_idx >= lengthof(g_system_information)) {
1015 g_system_information[rsl_idx] := SystemInformationConfig_omit
1016 }
1017 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1018}
1019
1020altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1021 var ASP_RSL_Unitdata rx_rsl_ud;
1022
1023 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1024 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1025 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1026 repeat;
1027 }
1028 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1029 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1030 repeat;
1031 }
1032 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1033 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1034 repeat;
1035 }
1036 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1037 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1038 repeat;
1039 }
1040
1041 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1042 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1043 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1044 repeat;
1045 }
1046 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1047 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1048 repeat;
1049 }
1050 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1051 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1052 repeat;
1053 }
1054 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1055 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1056 repeat;
1057 }
1058}
1059
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001060/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1061private type record of boolean my_BooleanList;
1062
1063private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1064{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001065 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1066
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001067 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001068 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1069 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1070 * stepping into that config node. */
1071 log("msc ", msc_nr, " is not configured, skipping");
1072 continue;
1073 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001074 f_vty_enter_cfg_msc(pt, msc_nr);
1075 if (allow_attach_list[msc_nr]) {
1076 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1077 f_vty_transceive(pt, "allow-attach", strict := false);
1078 } else {
1079 f_vty_transceive(pt, "no allow-attach", strict := false);
1080 }
1081 f_vty_transceive(pt, "exit");
1082 f_vty_transceive(pt, "exit");
1083 }
1084}
1085
Harald Welte21b46bd2017-12-17 19:46:32 +01001086/* global initialization function
1087 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001088 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1089 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1090 */
1091function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001092 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001093 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001094
Harald Welteae026692017-12-09 01:03:01 +01001095 if (g_initialized) {
1096 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001097 }
Harald Welteae026692017-12-09 01:03:01 +01001098 g_initialized := true;
1099
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001100 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001101 activate(as_Tguard());
1102
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001103 f_init_vty("VirtMSC");
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +02001104 if (mp_enable_osmux_test) {
1105 f_vty_allow_osmux(allow_osmux);
1106 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001107
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001108 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001109 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1110
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001111 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001112 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001113 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1114 * MSC-side BSSAP emulation */
1115 if (handler_mode) {
1116 var RanOps ranops := MSC_RanOps;
1117 ranops.use_osmux := g_osmux_enabled;
1118 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1119 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1120 f_ran_adapter_start(g_bssap[bssap_idx]);
1121 } else {
1122 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1123 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1124 f_ran_adapter_start(g_bssap[bssap_idx]);
1125 f_legacy_bssap_reset();
1126 }
Harald Welte67089ee2018-01-17 22:19:03 +01001127 }
Harald Welted5833a82018-05-27 16:52:56 +02001128
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001129 if (mp_enable_lcs_tests) {
1130 if (handler_mode) {
1131 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1132 } else {
1133 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1134 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1135 }
1136 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001137 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001138
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001139 /* start the test with exactly all enabled MSCs allowed to attach */
1140 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1141
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001142 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001143
Daniel Willmann191e0d92018-01-17 12:44:35 +01001144 f_init_mgcp("VirtMSC");
1145
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001146 for (var integer i := 0; i < nr_bts; i := i+1) {
1147 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001148 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001149}
Harald Welte696ddb62017-12-08 14:01:43 +01001150
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001151function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1152runs on test_CT {
1153 /* wait until osmo-bts-omldummy has respawned */
1154 f_wait_oml(bts_idx, "degraded", 5.0);
1155
1156 /* start RSL connection */
1157 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1158 /* wait until BSC tells us "connected" */
1159 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001160}
1161
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001162function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1163 template SystemInformationConfig expect_si)
1164runs on test_CT {
1165 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1166
1167 f_init_bts(bts_idx, handler_mode);
1168
1169 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1170 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1171 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1172 */
1173 f_sleep(5.0);
1174 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1175
1176 deactivate(sysinfo);
1177
1178 if (match(g_system_information[bts_idx], expect_si)) {
1179 setverdict(pass);
1180 } else {
1181 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1182 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1183 setverdict(fail, "received SI does not match expectations");
1184 return;
1185 }
1186}
1187
Maxd4e56962018-10-31 19:08:25 +01001188/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001189function 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 +01001190runs on test_CT return RSL_Message {
1191 var ASP_RSL_Unitdata rx_rsl_ud;
1192 timer T := t_secs;
1193
1194 T.start;
1195 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001196 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001197 T.stop;
1198 }
1199 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001200 [] T.timeout {
1201 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001202 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001203 }
Harald Welteae026692017-12-09 01:03:01 +01001204 }
1205 return rx_rsl_ud.rsl;
1206}
1207
Harald Welte21b46bd2017-12-17 19:46:32 +01001208/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001209function 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 +01001210runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001211 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001212}
1213
1214
Harald Welte4003d112017-12-09 22:35:39 +01001215/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001216testcase TC_chan_act_noreply() runs on test_CT {
1217 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001218 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001219
Harald Welte89d42e82017-12-17 16:42:41 +01001220 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001221
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001222 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001223 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001224 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001225}
1226
Harald Welte4003d112017-12-09 22:35:39 +01001227/* verify if the "chreq:total" counter increments as expected */
1228testcase TC_chan_act_counter() runs on test_CT {
1229 var BSSAP_N_UNITDATA_ind ud_ind;
1230 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001231 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001232
Harald Welte89d42e82017-12-17 16:42:41 +01001233 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001234
1235 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001236 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001237 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001238 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1239
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001240 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001241}
1242
Harald Welteae026692017-12-09 01:03:01 +01001243/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001244private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001245 var RSL_Message rx_rsl;
1246
Harald Welteae026692017-12-09 01:03:01 +01001247 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001248 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001249
1250 /* expect BSC to disable the channel again if there's no RLL EST IND */
1251 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1252
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001253 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001254}
1255
Philipp Maier9c60a622020-07-09 15:08:46 +02001256/* Normal variant */
1257testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001258 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001259 f_TC_chan_act_ack_noest();
1260}
1261
1262/* Emergency call variant */
1263testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1264 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001265 f_init(1);
1266 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001267 f_TC_chan_act_ack_noest(ra := 'A5'O);
1268}
1269
Philipp Maier606f07d2020-08-12 17:21:58 +02001270/* Emergency call variant, but emergency calls are not allowed */
1271testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1272 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1273
1274 var RSL_Message rx_rsl;
1275 var GsmRrMessage rr;
1276
1277 f_init(1);
1278 f_vty_allow_emerg_bts(false, 0);
1279
1280 IPA_RSL[0].clear;
1281 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1282
1283 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1284 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1285 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1286 setverdict(pass);
1287 } else {
1288 setverdict(fail, "immediate assignment not rejected");
1289 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001290
1291 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001292}
1293
Harald Welteae026692017-12-09 01:03:01 +01001294/* Test behavior if MSC never answers to CR */
1295testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001296 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1297 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001298 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001299 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001300
Harald Welte89d42e82017-12-17 16:42:41 +01001301 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001302
1303 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001304 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001305
1306 var octetstring l3 := '00010203040506'O
1307 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1308
1309 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1310
1311 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001312 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001313 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001314 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001315}
1316
1317/* Test behavior if MSC answers with CREF to CR */
1318testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1319 var BSSAP_N_CONNECT_ind rx_c_ind;
1320 var RSL_Message rx_rsl;
1321
Harald Welte89d42e82017-12-17 16:42:41 +01001322 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001323
1324 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001325 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001326
1327 var octetstring l3 := '00010203040506'O
1328 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1329
1330 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1331 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1332
1333 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001334 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001335 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001336}
1337
Harald Welte618ef642017-12-14 14:58:20 +01001338/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1339testcase TC_chan_act_nack() runs on test_CT {
1340 var RSL_Message rx_rsl;
1341 var integer chact_nack;
1342
Harald Welte89d42e82017-12-17 16:42:41 +01001343 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001344
1345 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1346
1347 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1348 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1349 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1350
1351 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1352
1353 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1354 f_sleep(0.5);
1355
1356 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1357
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001358 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001359}
1360
Harald Welte799c97b2017-12-14 17:50:30 +01001361/* Test for channel exhaustion due to RACH overload */
1362testcase TC_chan_exhaustion() runs on test_CT {
1363 var ASP_RSL_Unitdata rsl_ud;
1364 var integer i;
1365 var integer chreq_total, chreq_nochan;
1366
Harald Welte89d42e82017-12-17 16:42:41 +01001367 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001368
1369 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1370 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1371
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001372 /* GSM 04.08 Table 9.9a:
1373 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1374 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001375 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 +01001376 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001377 }
1378
1379 IPA_RSL[0].clear;
1380
Harald Weltedd8cbf32018-01-28 12:07:52 +01001381 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001382 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001383
1384 /* now expect additional channel activations to fail */
1385 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1386
1387 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001388 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001389 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1390 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001391 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001392 var GsmRrMessage rr;
1393 /* match on IMM ASS REJ */
1394 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1395 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1396 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001397 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001398 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1399 chreq_nochan+1);
1400 setverdict(pass);
1401 } else {
1402 repeat;
1403 }
1404 }
1405 [] IPA_RSL[0].receive { repeat; }
1406 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001407 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001408}
1409
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001410/* Test channel deactivation due to silence from MS */
1411testcase TC_chan_deact_silence() runs on test_CT {
1412 var RslChannelNr chan_nr;
1413
1414 f_init(1);
1415
1416 /* Request for a dedicated channel */
1417 chan_nr := f_chreq_act_ack('23'O);
1418
1419 /* Wait some time until the channel is released */
1420 f_sleep(2.0);
1421
1422 /* Expect CHANnel RELease */
1423 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001424 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001425 log("Received CHANnel RELease");
1426 setverdict(pass);
1427 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001428 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001429 /* See OS#3709, OsmoBSC should not send Immediate
1430 * Assignment Reject since a dedicated channel was
1431 * already allocated, and Immediate Assignment was
1432 * already sent. */
1433 setverdict(fail, "Unexpected Immediate Assignment!");
1434 }
1435 [] IPA_RSL[0].receive {
1436 setverdict(fail, "Unexpected RSL message!");
1437 }
1438 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001439 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001440}
1441
Harald Weltecfe2c962017-12-15 12:09:32 +01001442/***********************************************************************
1443 * Assignment Testing
1444 ***********************************************************************/
1445
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001446/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1447 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001448testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001449 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001450
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001451 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1452 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001453 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001454 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001455}
1456
Harald Welte16a4adf2017-12-14 18:54:01 +01001457/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001458testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001459 var BSSAP_N_CONNECT_ind rx_c_ind;
1460 var RSL_Message rx_rsl;
1461 var DchanTuple dt;
1462
Harald Welte89d42e82017-12-17 16:42:41 +01001463 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001464
1465 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001466 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001467 /* send assignment without AoIP IEs */
1468 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1469 } else {
1470 /* Send assignmetn without CIC in IPA case */
1471 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1472 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1473 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1474 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001475 alt {
1476 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1477 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1478 }
Harald Welte235ebf12017-12-15 14:18:16 +01001479 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001480 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1481 setverdict(pass);
1482 }
1483 [] BSSAP.receive { repeat; }
1484 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001485 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001486}
1487
Harald Welteed848512018-05-24 22:27:58 +02001488/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001489function 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 +02001490 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001491 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001492 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001493 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001494 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001495 if (osmux_enabled) {
1496 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1497 } else {
1498 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1499 }
Harald Welteed848512018-05-24 22:27:58 +02001500 } else {
1501 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001502 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001503 }
1504 return ass_cmd;
1505}
1506
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001507function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
1508 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001509 var PDU_BSSAP ho_req;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001510 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001511 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001512 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001513 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001514 } else {
1515 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001516 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001517 }
1518 return ho_req;
1519}
1520
Harald Welteed848512018-05-24 22:27:58 +02001521/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001522function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001523 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001524 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001525 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001526 if (expect_osmux) {
1527 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1528 } else {
1529 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1530 }
Harald Welteed848512018-05-24 22:27:58 +02001531 } else {
1532 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001533 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001534 }
1535 return exp_compl;
1536}
1537
Harald Welte235ebf12017-12-15 14:18:16 +01001538/* Run everything required up to sending a caller-specified assignment command and expect response */
1539function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1540runs on test_CT {
1541 var BSSAP_N_CONNECT_ind rx_c_ind;
1542 var RSL_Message rx_rsl;
1543 var DchanTuple dt;
1544
Harald Welte89d42e82017-12-17 16:42:41 +01001545 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001546
1547 dt := f_est_dchan('23'O, 23, '00000000'O);
1548 /* send assignment without AoIP IEs */
1549 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1550 alt {
1551 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1552 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1553 setverdict(pass);
1554 } else {
1555 setverdict(fail, fail_text);
1556 }
1557 }
1558 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1559 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1560 setverdict(pass);
1561 } else {
1562 setverdict(fail, fail_text);
1563 }
1564 }
1565 [] BSSAP.receive { repeat; }
1566 }
1567}
1568testcase TC_assignment_csd() runs on test_CT {
1569 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001570 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001571 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1572 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1573 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001574 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001575}
1576
1577testcase TC_assignment_ctm() runs on test_CT {
1578 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001579 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001580 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1581 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1582 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001583 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001584}
1585
Harald Welte4003d112017-12-09 22:35:39 +01001586type record DchanTuple {
1587 integer sccp_conn_id,
1588 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001589}
1590
Harald Welted6939652017-12-13 21:02:46 +01001591/* Send CHAN RQD and wait for allocation; acknowledge it */
1592private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1593runs on test_CT return RslChannelNr {
1594 var RSL_Message rx_rsl;
1595 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1596 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1597 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1598 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001599 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001600 return chan_nr;
1601}
1602
Harald Welte4003d112017-12-09 22:35:39 +01001603/* helper function to establish a dedicated channel via BTS and MSC */
1604function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1605runs on test_CT return DchanTuple {
1606 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001607 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001608
Harald Welte4003d112017-12-09 22:35:39 +01001609 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001610 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001611
1612 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1613
1614 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1615 dt.sccp_conn_id := rx_c_ind.connectionId;
1616 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1617
1618 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001619}
1620
Harald Welte641fcbe2018-06-14 10:58:35 +02001621/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1622private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1623 var RSL_Message rx_rsl;
1624 /* expect BSC to disable the channel */
1625 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1626 /* respond with CHAN REL ACK */
1627 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1628
1629 /* expect Clear Complete from BSC */
1630 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1631
1632 /* MSC disconnects as instructed. */
1633 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1634}
1635
Harald Welte4003d112017-12-09 22:35:39 +01001636/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1637testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001638 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001639 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001640
Harald Welte89d42e82017-12-17 16:42:41 +01001641 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001642
Harald Welte4003d112017-12-09 22:35:39 +01001643 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1644
1645 /* simulate RLL REL IND */
1646 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1647
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001648 /* expect Clear Request on MSC side */
1649 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1650
1651 /* Instruct BSC to clear channel */
1652 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1653 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1654
Harald Welte4003d112017-12-09 22:35:39 +01001655 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001656 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001657
1658 /* wait for SCCP emulation to do its job */
1659 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001660
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001661 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001662}
1663
1664/* Test behavior of channel release after CONN FAIL IND from BTS */
1665testcase TC_chan_rel_conn_fail() runs on test_CT {
1666 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001667 var DchanTuple dt;
1668
Harald Welte89d42e82017-12-17 16:42:41 +01001669 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001670
1671 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1672
1673 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001674 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 +01001675 /* TODO: different cause values? */
1676
Harald Welte4003d112017-12-09 22:35:39 +01001677 /* expect Clear Request from BSC */
1678 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1679
1680 /* Instruct BSC to clear channel */
1681 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1682 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1683
Harald Welte6ff76ea2018-01-28 13:08:01 +01001684 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001685 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001686
1687 /* wait for SCCP emulation to do its job */
1688 f_sleep(1.0);
1689
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001690 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001691}
1692
Harald Welte99f3ca02018-06-14 13:40:29 +02001693/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1694/* See also https://www.osmocom.org/issues/3182 */
1695testcase TC_early_conn_fail() runs on test_CT {
1696 var RSL_Message rx_rsl;
1697 var DchanTuple dt;
1698
1699 f_init(1);
1700
1701 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001702 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001703
1704 /* BTS->BSC: simulate CONN FAIL IND */
1705 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1706
1707 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1708 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1709
1710 /* BTS<-BSC: respond with CHAN REL ACK */
1711 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1712
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001713 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001714}
1715
1716/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1717/* See also https://www.osmocom.org/issues/3182 */
1718testcase TC_late_conn_fail() runs on test_CT {
1719 var RSL_Message rx_rsl;
1720 var DchanTuple dt;
1721
1722 f_init(1);
1723
1724 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1725
1726 /* BSC<-MSC: Instruct BSC to clear connection */
1727 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1728
1729 /* BTS->BSC: expect BSC to deactivate SACCH */
1730 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1731
1732 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1733 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1734
1735 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1736 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1737 /* BTS->BSC: respond with CHAN REL ACK */
1738 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1739
1740 /* BSC->MSC: expect Clear Complete from BSC */
1741 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1742
1743 /* BSC<-MSC: MSC disconnects as requested. */
1744 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1745
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001746 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001747}
1748
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001749function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001750 boolean expect_deact_sacch := true,
1751 boolean expect_rr_chan_rel := true,
1752 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001753 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001754 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001755 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001756 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001757
1758 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001759 var boolean got_deact_sacch := false;
1760 var boolean got_rr_chan_rel := false;
1761 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001762 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001763 var RSL_IE_Body l3_ie;
1764 var PDU_ML3_NW_MS l3;
1765 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001766 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1767 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001768 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001769 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001770 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001771 repeat;
1772 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001773 [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 +01001774 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001775
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001776 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1777 setverdict(fail, "cannot find L3");
1778 mtc.stop;
1779 }
1780 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1781
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001782 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001783 var CellSelIndValue cells := dec_CellSelIndValue(
1784 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1785
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001786 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1787 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001788 setverdict(pass);
1789 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001790 log("EXPECTED CELLS: ", expect_cells);
1791 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001792 }
1793 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001794
1795 if (not istemplatekind(expect_rr_cause, "omit")) {
1796 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1797 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1798 if (match(got_cause, expect_rr_cause)) {
1799 setverdict(pass);
1800 } else {
1801 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1802 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1803 }
1804 }
Harald Welte99787102019-02-04 10:41:36 +01001805 repeat;
1806 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001807 [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 +01001808 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001809
1810 if (not istemplatekind(expect_rr_cause, "omit")) {
1811 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1812 setverdict(fail, "cannot find L3");
1813 mtc.stop;
1814 }
1815 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1816
1817 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1818 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1819 if (match(got_cause, expect_rr_cause)) {
1820 setverdict(pass);
1821 } else {
1822 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1823 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1824 }
1825 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001826 repeat;
1827 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001828 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001829 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001830 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001831 if (handle_rll_rel) {
1832 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1833 }
Harald Welte91d54a52018-01-28 15:35:07 +01001834 repeat;
1835 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001836 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001837 /* respond with CHAN REL ACK */
1838 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1839 }
1840 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001841 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001842 repeat;
1843 }
1844 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001845
1846 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
1847 " got_rll_rel_req=", got_rll_rel_req);
1848
1849 if (expect_deact_sacch != got_deact_sacch) {
1850 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
1851 }
1852 if (expect_rr_chan_rel != got_rr_chan_rel) {
1853 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
1854 }
1855 if (expect_rll_rel_req != got_rll_rel_req) {
1856 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
1857 }
Harald Welte91d54a52018-01-28 15:35:07 +01001858}
1859
Harald Welte4003d112017-12-09 22:35:39 +01001860/* Test behavior of channel release after hard Clear Command from MSC */
1861testcase TC_chan_rel_hard_clear() runs on test_CT {
1862 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001863 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01001864
Harald Welte89d42e82017-12-17 16:42:41 +01001865 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001866
1867 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1868
1869 /* Instruct BSC to clear channel */
1870 var BssmapCause cause := 0;
1871 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1872
1873 /* expect Clear Complete from BSC on A */
1874 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1875 /* release the SCCP connection */
1876 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1877 }
1878
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001879 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001880 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001881}
1882
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001883function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
1884 var BSSAP_N_DATA_ind rx_di;
1885 var DchanTuple dt;
1886
1887 f_init(1);
1888
1889 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1890 /* Send CommonID with some random PLMN (BSC doesn't take it into account
1891 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
1892 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
1893
1894 /* Instruct BSC to clear channel */
1895 var BssmapCause cause := 0;
1896 if (tx_csfb_ind) {
1897 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
1898 } else {
1899 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1900 }
1901
1902 /* expect Clear Complete from BSC on A */
1903 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1904 /* release the SCCP connection */
1905 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1906 }
1907
1908 /* 1 neighbor is added by default in osmo-bts.cfg and
1909 SystemInformationConfig_default, use that: */
1910 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
1911
1912 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
1913 f_shutdown_helper();
1914}
1915
1916/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
1917 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
1918 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
1919 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
1920 Indicator or not shouldn't matter at all. */
1921testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
1922 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
1923}
1924
1925/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
1926 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
1927 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
1928 EUTRAN neighbor list sent later on by BSC in RR Channel. */
1929testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
1930 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
1931}
1932
1933/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
1934 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
1935 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
1936 CSFB Indicator should not be used anymore, and hence, there should be no
1937 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
1938 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01001939testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
1940 var BSSAP_N_DATA_ind rx_di;
1941 var DchanTuple dt;
1942
1943 f_init(1);
1944
1945 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1946
1947 /* Instruct BSC to clear channel */
1948 var BssmapCause cause := 0;
1949 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
1950
1951 /* expect Clear Complete from BSC on A */
1952 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1953 /* release the SCCP connection */
1954 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1955 }
1956
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001957 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001958 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01001959}
1960
Harald Welted8c36cd2017-12-09 23:05:31 +01001961/* Test behavior of channel release after hard RLSD from MSC */
1962testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01001963 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01001964
Harald Welte89d42e82017-12-17 16:42:41 +01001965 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01001966
1967 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1968
1969 /* release the SCCP connection */
1970 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1971
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001972 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001973 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01001974}
1975
Harald Welte550daf92018-06-11 19:22:13 +02001976/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
1977testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
1978 var DchanTuple dt;
1979
1980 f_init(1);
1981
1982 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1983
1984 /* release the SCCP connection */
1985 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1986
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001987 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001988 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02001989}
1990
Harald Welte85804d42017-12-10 14:11:58 +01001991/* Test behavior of channel release after BSSMAP RESET from MSC */
1992testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01001993 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01001994
Harald Welte89d42e82017-12-17 16:42:41 +01001995 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01001996
1997 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1998
1999 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2000 IPA_RSL[0].clear;
2001
2002 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002003 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 +01002004 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002005 [] 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 +01002006 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2007 }
2008
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002009 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002010 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002011}
2012
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002013/* Verify T(iar) triggers and releases the channel */
2014testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2015 var DchanTuple dt;
2016
2017 /* Set T(iar) in BSC low enough that it will trigger before other side
2018 has time to keep alive with a T(ias). Keep recommended ratio of
2019 T(iar) >= T(ias)*2 */
2020 g_bsc_sccp_timer_ias := 2;
2021 g_bsc_sccp_timer_iar := 5;
2022
2023 f_init(1);
2024
2025 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2026 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002027 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002028}
2029
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002030private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2031runs on test_CT
2032{
2033 var DchanTuple dt;
2034
2035 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2036 var BssmapCause cause := 0;
2037 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2038 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2039 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2040 }
2041
2042 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 +02002043}
2044
2045/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2046testcase TC_chan_rel_rr_cause() runs on test_CT {
2047 f_init(1);
2048
2049 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2050 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2051 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2052 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2053 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2054 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002055
2056 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002057}
2058
Harald Welte5cd20ed2017-12-13 21:03:20 +01002059/* Test behavior if RSL EST IND for non-active channel */
2060testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2061 timer T := 2.0;
2062
Harald Welte89d42e82017-12-17 16:42:41 +01002063 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002064
2065 var octetstring l3 := '00010203040506'O;
2066 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2067 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2068
2069 T.start;
2070 alt {
2071 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2072 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2073 }
2074 [] BSSAP.receive {}
2075 [] IPA_RSL[0].receive {}
2076 [] T.timeout {}
2077 }
2078
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002079 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002080}
2081
2082/* Test behavior if RSL EST IND for invalid SAPI */
2083testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2084 var RslChannelNr chan_nr;
2085
Harald Welte89d42e82017-12-17 16:42:41 +01002086 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002087
2088 chan_nr := f_chreq_act_ack()
2089
2090 var octetstring l3 := '00010203040506'O;
2091 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2092
2093 timer T := 2.0;
2094 T.start;
2095 alt {
2096 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2097 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2098 }
2099 [] BSSAP.receive { repeat; }
2100 [] IPA_RSL[0].receive { repeat; }
2101 [] T.timeout {}
2102 }
2103
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002104 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002105}
2106
2107/* Test behavior if RSL EST IND for invalid SAPI */
2108testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2109 timer T := 2.0;
2110
Harald Welte89d42e82017-12-17 16:42:41 +01002111 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002112
2113 var RslChannelNr chan_nr := f_chreq_act_ack();
2114
2115 var octetstring l3 := '00010203040506'O;
2116 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2117
2118 T.start;
2119 alt {
2120 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2121 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2122 }
2123 [] BSSAP.receive { repeat; }
2124 [] IPA_RSL[0].receive { repeat; }
2125 [] T.timeout {}
2126 }
2127
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002128 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002129}
2130
2131/* Test behavior if RSL EST IND for invalid SACCH */
2132testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2133 timer T := 2.0;
2134
Harald Welte89d42e82017-12-17 16:42:41 +01002135 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002136
2137 var RslChannelNr chan_nr := f_chreq_act_ack();
2138
2139 var octetstring l3 := '00010203040506'O;
2140 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2141
2142 T.start;
2143 alt {
2144 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2145 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2146 }
2147 [] BSSAP.receive { repeat; }
2148 [] IPA_RSL[0].receive { repeat; }
2149 [] T.timeout {}
2150 }
2151
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002152 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002153}
2154
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002155/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2156private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2157 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2158 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2159
2160 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2161 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2162
2163 f_establish_fully(ass_cmd, exp_compl);
2164
2165 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2166 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2167 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2168 BSSAP.receive(PDU_BSSAP:{
2169 discriminator := '1'B,
2170 spare := '0000000'B,
2171 dlci := 'C3'O,
2172 lengthIndicator := ?,
2173 pdu := { dtap := '0904'O }
2174 });
2175
2176 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2177 for (var integer i := 0; i < 32; i := i + 1) {
2178 var octetstring l3 := '09'O & f_rnd_octstring(14);
2179 var template (value) RslLinkId link_id;
2180 var template (value) OCT1 dlci;
2181
2182 if (i mod 2 == 0) {
2183 /* SAPI0 on FACCH or SDCCH */
2184 link_id := ts_RslLinkID_DCCH(0);
2185 dlci := '80'O;
2186 } else {
2187 /* SAPI3 on SACCH */
2188 link_id := ts_RslLinkID_SACCH(3);
2189 dlci := 'C3'O;
2190 }
2191
2192 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002193 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002194 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002195 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002196 }
2197}
2198testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2199 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2200 var MSC_ConnHdlr vc_conn;
2201
2202 f_init(1, true);
2203 f_sleep(1.0);
2204
2205 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2206 vc_conn.done;
2207
2208 f_shutdown_helper();
2209}
2210
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002211private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2212 template myBSSMAP_Cause cause := ?,
2213 float T_val := 2.0)
2214runs on test_CT {
2215 var BSSAP_N_DATA_ind rx_di;
2216 timer T;
2217
2218 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2219 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2220
2221 T.start(T_val);
2222 alt {
2223 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2224 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2225 if (not match(rx_cause, tr_cause)) {
2226 setverdict(fail, "Rx unexpected Cause IE: ",
2227 rx_cause, " vs expected ", tr_cause);
2228 }
2229 setverdict(pass);
2230 }
2231 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2232 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2233 }
2234 [] T.timeout {
2235 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2236 }
2237 }
2238}
2239
2240/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2241testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2242 var octetstring rnd_data := f_rnd_octstring(16);
2243 var RSL_Message rx_rsl;
2244 var DchanTuple dt;
2245
2246 f_init(1);
2247
2248 /* MS establishes a SAPI=0 link on DCCH */
2249 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2250
2251 /* MSC sends some data on (not yet established) SAPI=3 link */
2252 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2253 /* BSC attempts to establish a SAPI=3 link on DCCH */
2254 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2255
2256 /* MS sends unexpected RELease INDication on SAPI=3 */
2257 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2258 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2259 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2260
2261 /* Clean up the connection */
2262 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2263 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2264
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002265 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002266}
2267
2268/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2269testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2270 var octetstring rnd_data := f_rnd_octstring(16);
2271 var RSL_Message rx_rsl;
2272 var DchanTuple dt;
2273
2274 f_init(1);
2275
2276 /* MS establishes a SAPI=0 link on DCCH */
2277 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2278
2279 /* MSC sends some data on (not yet established) SAPI=3 link */
2280 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2281 /* BSC attempts to establish a SAPI=3 link on DCCH */
2282 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2283
2284 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2285 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2286 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2287 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2288
2289 /* Clean up the connection */
2290 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2291 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2292
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002293 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002294}
2295
2296/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2297testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2298 var octetstring rnd_data := f_rnd_octstring(16);
2299 var RSL_Message rx_rsl;
2300 var DchanTuple dt;
2301
2302 f_init(1);
2303
2304 /* MS establishes a SAPI=0 link on DCCH */
2305 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2306
2307 /* MSC sends some data on (not yet established) SAPI=3 link */
2308 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2309 /* BSC attempts to establish a SAPI=3 link on DCCH */
2310 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2311
2312 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2313 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2314
2315 /* Clean up the connection */
2316 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2317 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2318
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002319 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002320}
2321
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002322testcase TC_si_default() runs on test_CT {
2323 f_init(0);
2324 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002325 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002326}
Harald Welte4003d112017-12-09 22:35:39 +01002327
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002328/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2329 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2330private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2331{
2332 select (earfcn_index) {
2333 case (0) {
2334 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2335 return 111;
2336 }
2337 case (1) {
2338 return 1;
2339 }
2340 case (2) {
2341 return 0;
2342 }
2343 case (3) {
2344 return 65535;
2345 }
2346 case else {
2347 return 23 * (earfcn_index - 3);
2348 }
2349 }
2350}
2351
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002352function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2353 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002354
2355 f_init(0);
2356
2357 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2358 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002359 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2360 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002361 }
2362
2363 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2364
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002365 if (not istemplatekind(expect_cells, "omit")) {
2366 /* Also check that RR Channel Release contains these EARFCNs.
2367 * (copied code from TC_chan_rel_hard_clear_csfb) */
2368 var BSSAP_N_DATA_ind rx_di;
2369 var DchanTuple dt;
2370
2371 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002372 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2373 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2374 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002375
2376 /* Instruct BSC to clear channel */
2377 var BssmapCause cause := 0;
2378 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2379
2380 /* expect Clear Complete from BSC on A */
2381 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2382 /* release the SCCP connection */
2383 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2384 }
2385
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002386 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 +02002387 }
2388
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002389 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002390 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 +02002391 }
2392}
2393
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002394private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2395{
2396 var template SI2quaterRestOctetsList si2quater := {};
2397 var integer si2quater_count := (count + 2) / 3;
2398
2399 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002400 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002401 var integer index := i / 3;
2402 var integer earfcn_index := i mod 3;
2403 if (index >= lengthof(si2quater)) {
2404 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2405 }
2406 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);
2407 }
2408
2409 return si2quater;
2410}
2411
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002412private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2413{
2414 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2415
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002416 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002417 for (var integer i := 0; i < count; i := i + 1) {
2418 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002419 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002420 }
2421
2422 return tr_CellSelIndValue_EUTRAN(cells);
2423}
2424
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002425private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2426{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002427 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002428 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002429 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2430 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002431}
2432
2433testcase TC_si2quater_2_earfcns() runs on test_CT {
2434 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002435 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002436}
2437
2438testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002439 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002440 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002441}
2442
2443testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002444 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002445 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002446}
2447
2448testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002449 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002450 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002451}
2452
2453testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002454 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002455 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002456}
2457
2458testcase TC_si2quater_12_earfcns() runs on test_CT {
2459 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002460 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002461}
2462
2463testcase TC_si2quater_23_earfcns() runs on test_CT {
2464 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002465 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002466}
2467
2468testcase TC_si2quater_32_earfcns() runs on test_CT {
2469 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002470 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002471}
2472
2473testcase TC_si2quater_33_earfcns() runs on test_CT {
2474 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002475 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002476}
2477
2478testcase TC_si2quater_42_earfcns() runs on test_CT {
2479 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002480 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002481}
2482
2483testcase TC_si2quater_48_earfcns() runs on test_CT {
2484 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002485 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002486}
2487
2488/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2489 * 48 EARFCNs. */
2490testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002491 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002492 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2493 f_init(0);
2494
2495 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002496 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2497 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002498 }
2499
2500 /* The 49th EARFCN no longer fits, expect VTY error */
2501 f_vty_enter_cfg_bts(BSCVTY, 0);
2502 var charstring vty_error;
2503 vty_error := f_vty_transceive_ret(BSCVTY,
2504 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2505 f_vty_transceive(BSCVTY, "end");
2506
2507 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2508 log("Got expected VTY error: ", vty_error);
2509 setverdict(pass);
2510 } else {
2511 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2512 }
2513
2514 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2515
2516 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002517 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 +02002518 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002519 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002520}
2521
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002522private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2523{
2524 var uint8_t count := 0;
2525 for (var integer i := 5; i < 16; i := i + 1) {
2526 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2527 count := count + 1;
2528 }
2529 }
2530 return count;
2531}
2532
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002533private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2534{
2535 var ASP_RSL_Unitdata rx_rsl_ud;
2536 var SystemInformationType1 last_si1;
2537
2538 timer T := 30.0;
2539 T.start;
2540 alt {
2541 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2542 tr_RSL_BCCH_INFO,
2543 tr_RSL_NO_SACCH_FILL,
2544 tr_RSL_SACCH_FILL))
2545 ) -> value rx_rsl_ud {
2546 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2547 if (g_system_information[rsl_idx].si1 == omit) {
2548 repeat;
2549 }
2550 last_si1 := g_system_information[rsl_idx].si1;
2551 g_system_information[rsl_idx].si1 := omit;
2552 T.stop;
2553 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002554 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002555 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2556 }
2557 return last_si1;
2558}
2559
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002560/* verify ACC rotate feature */
2561testcase TC_si_acc_rotate() runs on test_CT {
2562 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002563 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002564 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002565 var uint8_t count;
2566 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2567
2568 f_init(0, guard_timeout := 60.0);
2569
2570 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2571 "access-control-class-rotate 3",
2572 "access-control-class-rotate-quantum 1"});
2573
2574 /* Init and get first sysinfo */
2575 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2576
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002577 for (var integer i:= 0; i < 20; i := i + 1) {
2578 last_si1 := f_recv_next_si1(0);
2579 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002580 count := f_acc09_count_allowed(acc);
2581 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2582
2583 if (count != 3) {
2584 log("RSL: EXPECTED SI ACC len=3");
2585 setverdict(fail, "received SI does not match expectations");
2586 break;
2587 }
2588
2589 for (var integer j := 0; j < 10; j := j + 1) {
2590 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2591 times_allowed[j] := times_allowed[j] + 1;
2592 }
2593 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002594 }
2595
2596 for (var integer j := 0; j < 10; j := j + 1) {
2597 log("ACC", j, " allowed ", times_allowed[j], " times" );
2598 if (j != 5 and times_allowed[j] < 3) {
2599 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2600 } else if (j == 5 and times_allowed[j] > 0) {
2601 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2602 }
2603 }
2604
2605 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2606 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002607 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002608}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002609
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002610/* verify ACC startup ramp+rotate feature */
2611testcase TC_si_acc_ramp_rotate() runs on test_CT {
2612 var template SystemInformationConfig sic := SystemInformationConfig_default;
2613 var SystemInformationType1 last_si1;
2614 var AccessControlClass acc;
2615 var ASP_RSL_Unitdata rx_rsl_ud;
2616 var uint8_t count;
2617 var uint8_t prev_count;
2618 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2619
2620 f_init(0, guard_timeout := 80.0);
2621
2622 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2623 "access-control-class-rotate 0",
2624 "access-control-class-rotate-quantum 1",
2625 "access-control-class-ramping",
2626 "access-control-class-ramping-step-interval 5",
2627 "access-control-class-ramping-step-size 5"});
2628
2629 /* Init and get first sysinfo */
2630 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2631 last_si1 := g_system_information[0].si1;
2632 acc := last_si1.rach_control.acc;
2633 count := f_acc09_count_allowed(acc);
2634 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2635 while (count > 0) {
2636 last_si1 := f_recv_next_si1(0);
2637 acc := last_si1.rach_control.acc;
2638 count := f_acc09_count_allowed(acc);
2639 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2640 }
2641
2642 /* Increase adm subset size, we should see ramping start up */
2643 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2644 prev_count := 0;
2645 while (true) {
2646 last_si1 := f_recv_next_si1(0);
2647 acc := last_si1.rach_control.acc;
2648 count := f_acc09_count_allowed(acc);
2649 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2650
2651 if (prev_count > count) {
2652 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2653 break;
2654 }
2655
2656 if (count == 9) {
2657 break; /* Maximum reached (10 - 1 perm barred), done here */
2658 }
2659
2660 prev_count := count;
2661 }
2662
2663 setverdict(pass);
2664
2665 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2666 "rach access-control-class 4 allowed",
2667 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002668 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002669}
2670
Harald Welte4003d112017-12-09 22:35:39 +01002671testcase TC_ctrl_msc_connection_status() runs on test_CT {
2672 var charstring ctrl_resp;
2673
Harald Welte89d42e82017-12-17 16:42:41 +01002674 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002675
2676 /* See https://osmocom.org/issues/2729 */
2677 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002678 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002679}
2680
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002681testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2682 var charstring ctrl_resp;
2683
2684 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002685
2686 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002687 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002688}
2689
Harald Welte4003d112017-12-09 22:35:39 +01002690testcase TC_ctrl() runs on test_CT {
2691 var charstring ctrl_resp;
2692
Harald Welte89d42e82017-12-17 16:42:41 +01002693 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002694
2695 /* all below values must match the osmo-bsc.cfg config file used */
2696
Harald Welte6a129692018-03-17 17:30:14 +01002697 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2698 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002699 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002700
2701 var integer bts_nr := 0;
2702 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2703 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2704 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2705 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2706 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2707 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2708 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2709
2710 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2711 f_sleep(2.0);
2712 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2713 setverdict(fail, "oml-uptime not incrementing as expected");
2714 }
2715 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2716
2717 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2718
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002719 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002720}
2721
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002722/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2723 "location-state" over the SCCPlite IPA conn */
2724testcase TC_ctrl_location() runs on test_CT {
2725 var MSC_ConnHdlr vc_conn;
2726 var integer bts_nr := 0;
2727
2728 f_init(1, true);
2729 f_sleep(1.0);
2730
2731 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2732 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2733 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2734
2735 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2736 f_sleep(2.0);
2737
2738 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2739 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2740 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
2741
2742 /* should match the one from config */
2743 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
2744
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002745 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002746}
2747
Harald Welte6f521d82017-12-11 19:52:02 +01002748
2749/***********************************************************************
2750 * Paging Testing
2751 ***********************************************************************/
2752
2753type record Cell_Identity {
2754 GsmMcc mcc,
2755 GsmMnc mnc,
2756 GsmLac lac,
2757 GsmCellId ci
2758};
Harald Welte24135bd2018-03-17 19:27:53 +01002759private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01002760private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01002761
Harald Welte5d1a2202017-12-13 19:51:29 +01002762type set of integer BtsIdList;
2763
2764private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
2765 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
2766 if (bts_id == bts_ids[j]) {
2767 return true;
2768 }
2769 }
2770 return false;
2771}
Harald Welte6f521d82017-12-11 19:52:02 +01002772
2773/* core paging test helper function; used by most paging test cases */
2774private function f_pageing_helper(hexstring imsi,
2775 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01002776 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01002777 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002778 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01002779{
2780 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002781 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01002782 var RSL_Message rx_rsl;
2783 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01002784 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01002785
2786 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01002787
2788 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01002789 for (i := 0; i < NUM_BTS; i := i + 1) {
2790 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01002791 }
Harald Welte6f521d82017-12-11 19:52:02 +01002792
2793 if (isvalue(rsl_chneed)) {
2794 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
2795 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
2796 } else {
2797 bssmap_chneed := omit;
2798 }
2799
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002800 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
2801 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01002802
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002803 if (not istemplatekind(tmsi, "omit")) {
2804 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002805 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002806 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002807 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002808
Harald Welte5d1a2202017-12-13 19:51:29 +01002809 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002810 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01002811 /* check channel type, paging group */
2812 if (rx_rsl.ies[1].body.paging_group != paging_group) {
2813 setverdict(fail, "Paging for wrong paging group");
2814 }
2815 if (ispresent(rsl_chneed) and
2816 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
2817 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
2818 }
Harald Welte6f521d82017-12-11 19:52:02 +01002819 }
Harald Welte2fccd982018-01-31 15:48:19 +01002820 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01002821 /* do a quick check on all not-included BTSs if they received paging */
2822 for (i := 0; i < NUM_BTS; i := i + 1) {
2823 timer T := 0.1;
2824 if (f_bts_in_list(i, bts_ids)) {
2825 continue;
2826 }
2827 T.start;
2828 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002829 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01002830 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
2831 }
2832 [] IPA_RSL[i].receive { repeat; }
2833 [] T.timeout { }
2834 }
Harald Welte6f521d82017-12-11 19:52:02 +01002835 }
2836
2837 setverdict(pass);
2838}
2839
Harald Welte5d1a2202017-12-13 19:51:29 +01002840const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01002841const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01002842const BtsIdList c_BtsId_LAC1 := { 0, 1 };
2843const BtsIdList c_BtsId_LAC2 := { 2 };
2844
Harald Welte6f521d82017-12-11 19:52:02 +01002845/* PAGING by IMSI + TMSI */
2846testcase TC_paging_imsi_nochan() runs on test_CT {
2847 var BSSMAP_FIELD_CellIdentificationList cid_list;
2848 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01002849 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002850 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002851}
2852
2853/* PAGING by IMSI + TMSI */
2854testcase TC_paging_tmsi_nochan() runs on test_CT {
2855 var BSSMAP_FIELD_CellIdentificationList cid_list;
2856 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002857 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002858 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002859}
2860
2861/* Paging with different "channel needed' values */
2862testcase TC_paging_tmsi_any() runs on test_CT {
2863 var BSSMAP_FIELD_CellIdentificationList cid_list;
2864 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002865 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002866 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002867}
2868testcase TC_paging_tmsi_sdcch() runs on test_CT {
2869 var BSSMAP_FIELD_CellIdentificationList cid_list;
2870 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002871 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002872 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002873}
2874testcase TC_paging_tmsi_tch_f() runs on test_CT {
2875 var BSSMAP_FIELD_CellIdentificationList cid_list;
2876 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002877 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002878 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002879}
2880testcase TC_paging_tmsi_tch_hf() runs on test_CT {
2881 var BSSMAP_FIELD_CellIdentificationList cid_list;
2882 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002883 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002884 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002885}
2886
2887/* Paging by CGI */
2888testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
2889 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2890 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002891 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002892 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002893}
2894
2895/* Paging by LAC+CI */
2896testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
2897 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2898 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002899 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002900 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002901}
2902
2903/* Paging by CI */
2904testcase TC_paging_imsi_nochan_ci() runs on test_CT {
2905 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2906 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002907 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002908 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002909}
2910
2911/* Paging by LAI */
2912testcase TC_paging_imsi_nochan_lai() runs on test_CT {
2913 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2914 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002915 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002916 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002917}
2918
2919/* Paging by LAC */
2920testcase TC_paging_imsi_nochan_lac() runs on test_CT {
2921 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2922 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002923 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002924 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002925}
2926
2927/* Paging by "all in BSS" */
2928testcase TC_paging_imsi_nochan_all() runs on test_CT {
2929 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2930 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01002931 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002932 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002933}
2934
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002935/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01002936testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
2937 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2938 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 +01002939 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002940 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01002941}
Harald Welte6f521d82017-12-11 19:52:02 +01002942
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002943/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01002944testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
2945 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2946 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002947 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002948 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01002949}
2950
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002951/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01002952testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
2953 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2954 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002955 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002956 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01002957}
2958
Harald Welte6f521d82017-12-11 19:52:02 +01002959/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01002960testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
2961 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2962 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
2963 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002964 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01002965}
2966
2967/* Paging on empty list: Verify none of them page */
2968testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
2969 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2970 cid_list := { cIl_LAC := { } };
2971 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002972 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01002973}
2974
Stefan Sperling049a86e2018-03-20 15:51:00 +01002975/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
2976testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
2977 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2978 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
2979 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
2980 f_shutdown_helper();
2981}
2982
Harald Welte6f521d82017-12-11 19:52:02 +01002983/* Verify paging retransmission interval + count */
2984/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01002985/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01002986
Harald Weltee65d40e2017-12-13 00:09:06 +01002987/* Verify PCH load */
2988testcase TC_paging_imsi_load() runs on test_CT {
2989 var BSSMAP_FIELD_CellIdentificationList cid_list;
2990 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01002991 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01002992 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002993 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01002994
2995 /* tell BSC there is no paging space anymore */
2996 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01002997 f_sleep(0.2);
2998 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01002999
3000 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3001 * there would be 8 retransmissions during 4 seconds */
3002 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003003 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003004 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003005 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003006 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003007 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003008 }
Harald Welte2caa1062018-03-17 18:19:05 +01003009 [] T_retrans.timeout {
3010 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3011 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3012 T_retrans.start;
3013 repeat;
3014 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003015 [] T.timeout {
3016 setverdict(pass);
3017 }
3018 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003019
3020 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003021}
3022
Harald Welte235ebf12017-12-15 14:18:16 +01003023/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003024testcase TC_paging_counter() runs on test_CT {
3025 var BSSMAP_FIELD_CellIdentificationList cid_list;
3026 timer T := 4.0;
3027 var integer i;
3028 var integer paging_attempted_bsc;
3029 var integer paging_attempted_bts[NUM_BTS];
3030 var integer paging_expired_bts[NUM_BTS];
3031 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3032
3033 f_init();
3034
3035 /* read counters before paging */
3036 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3037 for (i := 0; i < NUM_BTS; i := i+1) {
3038 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3039 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3040 }
3041
3042 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3043
3044 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3045 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3046 for (i := 0; i < NUM_BTS; i := i+1) {
3047 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3048 paging_attempted_bts[i]+1);
3049 }
3050
3051 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3052 f_sleep(12.0);
3053 for (i := 0; i < NUM_BTS; i := i+1) {
3054 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3055 paging_expired_bts[i]+1);
3056 }
Harald Welte1ff69992017-12-14 12:31:17 +01003057
Philipp Maier282ca4b2018-02-27 17:17:00 +01003058 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003059}
3060
3061
Harald Welte10985002017-12-12 09:29:15 +01003062/* Verify paging stops after A-RESET */
3063testcase TC_paging_imsi_a_reset() runs on test_CT {
3064 var BSSMAP_FIELD_CellIdentificationList cid_list;
3065 timer T := 3.0;
3066 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003067 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003068
3069 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003070 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 +01003071 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003072 [] 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 +01003073 [] BSSAP.receive { repeat; }
3074 }
3075
Daniel Willmanncbef3982018-07-30 09:22:40 +02003076 /* Wait to avoid a possible race condition if a paging message is
3077 * received right before the reset ACK. */
3078 f_sleep(0.2);
3079
Harald Welte10985002017-12-12 09:29:15 +01003080 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003081 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3082 IPA_RSL[i].clear;
3083 }
Harald Welte10985002017-12-12 09:29:15 +01003084
3085 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3086 T.start;
3087 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003088 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003089 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003090 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003091 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003092 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003093 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003094 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003095 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003096 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003097 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003098 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003099 }
Harald Welte10985002017-12-12 09:29:15 +01003100 [] T.timeout {
3101 setverdict(pass);
3102 }
3103 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003104
3105 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003106}
Harald Welteae026692017-12-09 01:03:01 +01003107
Philipp Maierf45824a2019-08-14 14:44:10 +02003108/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3109 * paging response we can not know which MSC is in charge, so we will blindly
3110 * pick the first configured MSC. This behavior is required in order to make
3111 * MT-CSFB calls working because in those cases the BSC can not know that the
3112 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3113 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003114 */
3115testcase TC_paging_resp_unsol() runs on test_CT {
3116
3117 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003118 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003119
3120 var BSSAP_N_CONNECT_ind rx_c_ind;
3121 var DchanTuple dt;
3122 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003123 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003124
3125 /* Send CHAN RQD and wait for allocation; acknowledge it */
3126 dt.rsl_chan_nr := f_chreq_act_ack();
3127
3128 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3129 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3130
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003131
Philipp Maierf45824a2019-08-14 14:44:10 +02003132 /* Expevct a CR with a matching Paging response on the A-Interface */
3133 T.start;
3134 alt {
3135 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3136 setverdict(pass);
3137 }
3138 [] BSSAP.receive {
3139 setverdict(fail, "Received unexpected message on A-Interface!");
3140 }
3141 [] T.timeout {
3142 setverdict(fail, "Received nothing on A-Interface!");
3143 }
3144 }
3145
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003146 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003147}
3148
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003149/* Test RSL link drop causes counter increment */
3150testcase TC_rsl_drop_counter() runs on test_CT {
3151 var integer rsl_fail;
3152
Harald Welte89d42e82017-12-17 16:42:41 +01003153 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003154
3155 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3156
3157 bts[0].rsl.vc_IPA.stop;
3158
3159 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3160
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003161 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003162}
3163
3164/* TODO: Test OML link drop causes counter increment */
3165
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003166/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3167function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3168 timer T := 10.0;
3169
3170 bts[0].rsl.id := "IPA-0-RSL";
3171 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3172 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3173 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003174 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003175
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003176 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003177
3178 f_init_mgcp("VirtMSC");
3179
3180 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3181 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3182 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3183 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3184
3185 /* wait for IPA OML link to connect and then disconnect */
3186 T.start;
3187 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003188 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003189 T.stop;
3190 return true;
3191 }
3192 [] IPA_RSL[0].receive { repeat }
3193 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003194 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003195 }
3196 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003197 return false;
3198}
3199
3200/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3201testcase TC_rsl_unknown_unit_id() runs on test_CT {
3202 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3203 setverdict(pass);
3204 } else {
3205 setverdict(fail, "Timeout RSL waiting for connection to close");
3206 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003207 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003208}
3209
3210
3211/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3212testcase TC_oml_unknown_unit_id() runs on test_CT {
3213 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3214 setverdict(pass);
3215 } else {
3216 setverdict(fail, "Timeout OML waiting for connection to close");
3217 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003218 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003219}
3220
3221
Harald Weltec1a2fff2017-12-17 11:06:19 +01003222/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003223 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003224 ***********************************************************************/
3225
Harald Welte6811d102019-04-14 22:23:14 +02003226import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003227import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003228import from RSL_Emulation all;
3229import from MSC_ConnectionHandler all;
3230
3231type function void_fn(charstring id) runs on MSC_ConnHdlr;
3232
Harald Welte336820c2018-05-31 20:34:52 +02003233/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003234private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3235 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003236 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003237 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003238 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003239 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003240 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3241 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3242 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003243 if (isvalue(bts[2])) {
3244 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3245 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3246 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003247 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003248 if (mp_enable_lcs_tests) {
3249 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3250 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3251 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003252 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003253 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003254 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003255}
3256
3257function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3258runs on test_CT return MSC_ConnHdlr {
3259 var charstring id := testcasename();
3260 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003261 var integer bssap_idx := 0;
3262 if (isvalue(pars)) {
3263 bssap_idx := valueof(pars).mscpool.bssap_idx;
3264 }
Harald Welte336820c2018-05-31 20:34:52 +02003265 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003266 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003267 /* Emit a marker to appear in the SUT's own logging output */
3268 f_logp(BSCVTY, testcasename() & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003269 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003270 return vc_conn;
3271}
3272
Harald Weltea0630032018-03-20 21:09:55 +01003273/* first function inside ConnHdlr component; sets g_pars + starts function */
3274private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3275runs on MSC_ConnHdlr {
3276 if (isvalue(pars)) {
3277 g_pars := valueof(pars);
3278 }
3279 fn.apply(id);
3280}
3281
Harald Welte3c86ea02018-05-10 22:28:05 +02003282/* Establish signalling channel (non-assignment case) followed by cipher mode */
3283private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003284 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3285 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003286 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003287 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3288 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3289 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3290 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003291
Philipp Maier23000732018-05-18 11:25:37 +02003292 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003293}
3294testcase TC_ciph_mode_a5_0() runs on test_CT {
3295 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003296 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003297 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3298
3299 f_init(1, true);
3300 f_sleep(1.0);
3301 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3302 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003303 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003304}
3305testcase TC_ciph_mode_a5_1() runs on test_CT {
3306 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003307 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003308 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3309
3310 f_init(1, true);
3311 f_sleep(1.0);
3312 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3313 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003314 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003315}
3316testcase TC_ciph_mode_a5_3() runs on test_CT {
3317 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003318 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003319 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3320
3321 f_init(1, true);
3322 f_sleep(1.0);
3323 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3324 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003325 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003326}
3327
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003328/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3329private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3330 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3331 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3332 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3333 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3334
3335 f_establish_fully(ass_cmd, exp_compl);
3336}
3337testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3338 var MSC_ConnHdlr vc_conn;
3339 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3340
3341 f_init(1, true);
3342 f_sleep(1.0);
3343 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3344 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003345 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003346}
3347
Harald Welte3c86ea02018-05-10 22:28:05 +02003348
3349/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003350private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003351 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3352 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003353
Harald Welte552620d2017-12-16 23:21:36 +01003354 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3355 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003356
Harald Weltea0630032018-03-20 21:09:55 +01003357 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003358}
Harald Welte552620d2017-12-16 23:21:36 +01003359testcase TC_assignment_fr_a5_0() runs on test_CT {
3360 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003361 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003362 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003363
Harald Welte89d42e82017-12-17 16:42:41 +01003364 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003365 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003366 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003367 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003368 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003369}
Harald Welte552620d2017-12-16 23:21:36 +01003370testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003371 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003372 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003373 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003374
Harald Welte89d42e82017-12-17 16:42:41 +01003375 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003376 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003377 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3378 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003379 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003380}
3381testcase TC_assignment_fr_a5_3() runs on test_CT {
3382 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003383 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003384 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003385
Harald Welte651fcdc2018-05-10 20:23:16 +02003386 f_init(1, true);
3387 f_sleep(1.0);
3388 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003389 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003390 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003391}
3392
Harald Welte552620d2017-12-16 23:21:36 +01003393/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3394private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003395 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003396 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003397 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003398 const OCT8 kc := '0001020304050607'O;
3399
3400 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003401 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3402
Harald Weltea0630032018-03-20 21:09:55 +01003403 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003404}
Harald Welte552620d2017-12-16 23:21:36 +01003405testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3406 var MSC_ConnHdlr vc_conn;
3407
Harald Welte89d42e82017-12-17 16:42:41 +01003408 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003409 f_sleep(1.0);
3410
Harald Welte8863fa12018-05-10 20:15:27 +02003411 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003412 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003413 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003414}
3415
Harald Welte552620d2017-12-16 23:21:36 +01003416private function f_tc_assignment_fr_a5_4(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003417 g_pars := f_gen_test_hdlr_pars();
Harald Welteed848512018-05-24 22:27:58 +02003418 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3419 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003420 const OCT8 kc := '0001020304050607'O;
3421 const OCT16 kc128 := kc & kc;
3422
3423 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3424 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Weltea0630032018-03-20 21:09:55 +01003425 f_establish_fully(ass_cmd, exp_compl);
Harald Welte38b2a102017-12-23 02:42:58 +01003426 f_cipher_mode('10'O, kc, kc128, true);
Harald Welte552620d2017-12-16 23:21:36 +01003427 /* TODO: expect GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED cause value */
Harald Welte552620d2017-12-16 23:21:36 +01003428}
Harald Welte552620d2017-12-16 23:21:36 +01003429testcase TC_assignment_fr_a5_4() runs on test_CT {
3430 var MSC_ConnHdlr vc_conn;
3431
Harald Welte89d42e82017-12-17 16:42:41 +01003432 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003433 f_sleep(1.0);
3434
Harald Welte8863fa12018-05-10 20:15:27 +02003435 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_4));
Harald Welte552620d2017-12-16 23:21:36 +01003436 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003437 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003438}
3439
3440
Harald Welte4532e0a2017-12-23 02:05:44 +01003441private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003442 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003443 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003444 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003445 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003446
3447 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003448 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003449
3450 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003451 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3452 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003453 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3454 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3455 };
3456 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003457}
3458
3459testcase TC_assignment_sign() runs on test_CT {
3460 var MSC_ConnHdlr vc_conn;
3461
3462 f_init(1, true);
3463 f_sleep(1.0);
3464
Harald Welte8863fa12018-05-10 20:15:27 +02003465 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003466 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003467 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003468}
3469
Harald Welte60aa5762018-03-21 19:33:13 +01003470/***********************************************************************
3471 * Codec (list) testing
3472 ***********************************************************************/
3473
3474/* check if the given rsl_mode is compatible with the a_elem */
3475private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3476return boolean {
3477 select (a_elem.codecType) {
3478 case (GSM_FR) {
3479 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3480 return true;
3481 }
3482 }
3483 case (GSM_HR) {
3484 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3485 return true;
3486 }
3487 }
3488 case (GSM_EFR) {
3489 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3490 return true;
3491 }
3492 }
3493 case (FR_AMR) {
3494 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3495 return true;
3496 }
3497 }
3498 case (HR_AMR) {
3499 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3500 return true;
3501 }
3502 }
3503 case else { }
3504 }
3505 return false;
3506}
3507
3508/* check if the given rsl_mode is compatible with the a_list */
3509private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3510return boolean {
3511 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3512 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3513 return true;
3514 }
3515 }
3516 return false;
3517}
3518
3519/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003520function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003521return BSSMAP_IE_ChannelType {
3522 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3523 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3524 select (a_elem.codecType) {
3525 case (GSM_FR) {
3526 ret.channelRateAndType := ChRate_TCHF;
3527 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3528 }
3529 case (GSM_HR) {
3530 ret.channelRateAndType := ChRate_TCHH;
3531 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3532 }
3533 case (GSM_EFR) {
3534 ret.channelRateAndType := ChRate_TCHF;
3535 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3536 }
3537 case (FR_AMR) {
3538 ret.channelRateAndType := ChRate_TCHF;
3539 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3540 }
3541 case (HR_AMR) {
3542 ret.channelRateAndType := ChRate_TCHH;
3543 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3544 }
3545 case else {
3546 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003547 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003548 }
3549 }
3550 return ret;
3551}
3552
Harald Weltea63b9102018-03-22 20:36:16 +01003553private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3554return template RSL_IE_Body {
3555 var template RSL_IE_Body mode_ie := {
3556 chan_mode := {
3557 len := ?,
3558 reserved := ?,
3559 dtx_d := ?,
3560 dtx_u := ?,
3561 spd_ind := RSL_SPDI_SPEECH,
3562 ch_rate_type := -,
3563 coding_alg_rate := -
3564 }
3565 }
3566
3567 select (a_elem.codecType) {
3568 case (GSM_FR) {
3569 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3570 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3571 }
3572 case (GSM_HR) {
3573 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3574 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3575 }
3576 case (GSM_EFR) {
3577 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3578 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3579 }
3580 case (FR_AMR) {
3581 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3582 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3583 }
3584 case (HR_AMR) {
3585 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3586 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3587 }
3588 }
3589 return mode_ie;
3590}
3591
Harald Welte60aa5762018-03-21 19:33:13 +01003592type record CodecListTest {
3593 BSSMAP_IE_SpeechCodecList codec_list,
3594 charstring id
3595}
3596type record of CodecListTest CodecListTests
3597
3598private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003599 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3600 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003601
3602 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003603 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003604 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3605 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3606 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003607 if (isvalue(g_pars.expect_mr_s0_s7)) {
3608 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3609 g_pars.expect_mr_s0_s7;
3610 }
Harald Welte79f3f542018-05-25 20:02:37 +02003611 }
Harald Welte60aa5762018-03-21 19:33:13 +01003612 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3613 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003614 log("expecting ASS COMPL like this: ", exp_compl);
3615
3616 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01003617
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003618 if (not g_pars.expect_channel_mode_modify) {
3619 /* Verify that the RSL-side activation actually matches our expectations */
3620 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01003621
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003622 var RSL_IE_Body mode_ie;
3623 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
3624 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02003625 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003626 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003627 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
3628 if (not match(mode_ie, t_mode_ie)) {
3629 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
3630 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003631 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003632
3633 var RSL_IE_Body mr_conf;
3634 if (g_pars.expect_mr_conf_ie != omit) {
3635 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
3636 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
3637 mtc.stop;
3638 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003639 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003640
3641 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
3642 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
3643 g_pars.expect_mr_conf_ie);
3644 }
3645 } else {
3646 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
3647 log("found RSL MR CONFIG IE: ", mr_conf);
3648 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
3649 mtc.stop;
3650 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003651 }
3652 }
Harald Welte60aa5762018-03-21 19:33:13 +01003653}
3654
Philipp Maierd0e64b02019-03-13 14:15:23 +01003655private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
3656
3657 var PDU_BSSAP ass_cmd := f_gen_ass_req();
3658 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
3659
3660 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003661 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01003662 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3663 }
3664 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3665 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
3666 log("expecting ASS FAIL like this: ", exp_fail);
3667
3668 f_establish_fully(ass_cmd, exp_fail);
3669}
3670
Harald Welte60aa5762018-03-21 19:33:13 +01003671testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003672 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003673 var MSC_ConnHdlr vc_conn;
3674
3675 f_init(1, true);
3676 f_sleep(1.0);
3677
3678 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003679 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003680 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003681 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003682}
3683
3684testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003685 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003686 var MSC_ConnHdlr vc_conn;
3687
3688 f_init(1, true);
3689 f_sleep(1.0);
3690
3691 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003692 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003693 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003694 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003695}
3696
3697testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003698 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003699 var MSC_ConnHdlr vc_conn;
3700
3701 f_init(1, true);
3702 f_sleep(1.0);
3703
3704 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003705 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003706 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003707 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003708}
3709
Philipp Maierd0e64b02019-03-13 14:15:23 +01003710/* Allow 5,90k only (current default config) */
3711private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003712 f_vty_cfg_msc(BSCVTY, 0, {
3713 "amr-config 12_2k forbidden",
3714 "amr-config 10_2k forbidden",
3715 "amr-config 7_95k forbidden",
3716 "amr-config 7_40k forbidden",
3717 "amr-config 6_70k forbidden",
3718 "amr-config 5_90k allowed",
3719 "amr-config 5_15k forbidden",
3720 "amr-config 4_75k forbidden"
3721 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003722}
3723
3724/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
3725 * ("Config-NB-Code = 1") */
3726private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003727 f_vty_cfg_msc(BSCVTY, 0, {
3728 "amr-config 12_2k allowed",
3729 "amr-config 10_2k forbidden",
3730 "amr-config 7_95k forbidden",
3731 "amr-config 7_40k allowed",
3732 "amr-config 6_70k forbidden",
3733 "amr-config 5_90k allowed",
3734 "amr-config 5_15k forbidden",
3735 "amr-config 4_75k allowed"
3736 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003737}
3738
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003739private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
3740 var charstring tch;
3741 if (fr) {
3742 tch := "tch-f";
3743 } else {
3744 tch := "tch-h";
3745 }
3746 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
3747}
3748
3749/* Set the AMR start-mode for this TCH back to the default configuration. */
3750private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
3751 f_vty_amr_start_mode_set(fr, "auto");
3752}
3753
Harald Welte60aa5762018-03-21 19:33:13 +01003754testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003755 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003756 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02003757
3758 /* Note: This setups the codec configuration. The parameter payload in
3759 * mr_conf must be consistant with the parameter codecElements in pars
3760 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003761 var RSL_IE_Body mr_conf := {
3762 other := {
3763 len := 2,
3764 payload := '2804'O
3765 }
3766 };
Harald Welte60aa5762018-03-21 19:33:13 +01003767
Philipp Maier7695a0d2018-09-27 17:52:14 +02003768 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01003769 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02003770 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
3771 pars.expect_mr_conf_ie := mr_conf;
3772
Harald Welte60aa5762018-03-21 19:33:13 +01003773 f_init(1, true);
3774 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003775 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01003776
Harald Welte8863fa12018-05-10 20:15:27 +02003777 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003778 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003779
3780 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01003781 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003782}
3783
3784testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003785 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003786 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02003787
3788 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003789 var RSL_IE_Body mr_conf := {
3790 other := {
3791 len := 2,
3792 payload := '2804'O
3793 }
3794 };
Harald Welte60aa5762018-03-21 19:33:13 +01003795
Philipp Maier7695a0d2018-09-27 17:52:14 +02003796 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01003797 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02003798 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
3799 pars.expect_mr_conf_ie := mr_conf;
3800
Harald Welte60aa5762018-03-21 19:33:13 +01003801 f_init(1, true);
3802 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003803 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01003804
Harald Welte8863fa12018-05-10 20:15:27 +02003805 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003806 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003807
3808 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01003809 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003810}
3811
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003812/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
3813testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
3814 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3815 var MSC_ConnHdlr vc_conn;
3816
3817 f_init(1, true);
3818 f_sleep(1.0);
3819
3820 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
3821 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
3822 * expecting a Channel Mode Modify if the channel type is compatible. */
3823 f_disable_all_sdcch();
3824 f_disable_all_tch_h();
3825
3826 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3827 pars.expect_channel_mode_modify := true;
3828 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
3829 vc_conn.done;
3830
3831 f_enable_all_sdcch();
3832 f_enable_all_tch();
3833 f_shutdown_helper();
3834}
3835
Neels Hofmeyr454d7922020-11-26 02:24:57 +00003836/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
3837testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
3838 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3839 var MSC_ConnHdlr vc_conn;
3840
3841 var RSL_IE_Body mr_conf := {
3842 other := {
3843 len := 2,
3844 payload := '2004'O /* <- expect ICMI=0, smod=00 */
3845 }
3846 };
3847
3848 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
3849 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
3850 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
3851 pars.expect_mr_conf_ie := mr_conf;
3852
3853 f_init(1, true);
3854 f_sleep(1.0);
3855
3856 /* First set nonzero start mode bits */
3857 f_vty_amr_start_mode_set(true, "4");
3858 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
3859 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
3860 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
3861 f_vty_amr_start_mode_set(true, "auto");
3862
3863 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
3864 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00003865
3866 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
3867 f_vty_amr_start_mode_set(true, "1");
3868 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01003869 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00003870}
3871
Neels Hofmeyr21863562020-11-26 00:34:33 +00003872function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
3873 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01003874runs on test_CT {
3875
3876 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3877 var MSC_ConnHdlr vc_conn;
3878
3879 /* See note above */
3880 var RSL_IE_Body mr_conf := {
3881 other := {
3882 len := lengthof(mrconf),
3883 payload := mrconf
3884 }
3885 };
3886
3887 if (fr) {
3888 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
3889 } else {
3890 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
3891 }
3892 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
3893 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
3894 pars.expect_mr_conf_ie := mr_conf;
3895 pars.expect_mr_s0_s7 := exp_s8_s0;
3896
3897 f_init(1, true);
3898 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00003899 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01003900 f_sleep(1.0);
3901
3902 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
3903 vc_conn.done;
3904 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003905 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01003906}
3907
3908function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
3909runs on test_CT {
3910
3911 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3912 var MSC_ConnHdlr vc_conn;
3913
3914 if (fr) {
3915 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
3916 } else {
3917 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
3918 }
3919 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
3920 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
3921
3922 f_init(1, true);
3923 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003924 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01003925 f_sleep(1.0);
3926
3927 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
3928 vc_conn.done;
3929 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003930 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01003931}
3932
3933
3934/* Set S1, we expect an AMR multirate configuration IE with all four rates
3935 * set. */
3936testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003937 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003938 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003939}
3940
3941/* Set S1, we expect an AMR multirate configuration IE with the lower three
3942 * rates set. */
3943testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003944 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003945 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003946}
3947
3948/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
3949 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
3950testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003951 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003952 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003953}
3954
3955/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
3956 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
3957testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003958 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003959 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003960}
3961
3962/* The following block of tests selects more and more rates until all four
3963 * possible rates are in the active set (full rate) */
3964testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003965 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003966 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003967}
3968
3969testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003970 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003971 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003972}
3973
3974testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003975 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003976 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003977}
3978
3979testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003980 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003981 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003982}
3983
3984/* The following block of tests selects more and more rates until all three
3985 * possible rates are in the active set (half rate) */
3986testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003987 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003988 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003989}
3990
3991testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003992 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003993 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003994}
3995
3996testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02003997 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003998 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01003999}
4000
4001/* The following block tests what happens when the MSC does offer rate
4002 * configurations that are not supported by the BSC. Normally such situations
4003 * should not happen because the MSC gets informed by the BSC in advance via
4004 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4005 * to offer rates that are not applicable anyway. */
4006
4007testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004008 /* Try to include 12,2k in into the active set even though the channel
4009 * is half rate only. The BSC is expected to remove the 12,0k */
4010 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004011 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004012}
4013
4014testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004015 /* See what happens when all rates are selected at once. Since then
4016 * Also S1 is selected, this setting will be prefered and we should
4017 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4018 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004019 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004020}
4021
4022testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004023 /* Same as above, but with S1 missing, the MSC is then expected to
4024 * select the currently supported rates, which are also 12.2k, 7,40k,
4025 * 5,90k, and 4,75k, into the active set. */
4026 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004027 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004028}
4029
4030testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004031 /* Try to select no rates at all */
4032 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004033 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004034}
4035
4036testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004037 /* Try to select only unsupported rates */
4038 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004039 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004040}
4041
4042testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004043 /* Try to select 12,2k for half rate */
4044 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004045 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004046}
4047
Neels Hofmeyr21863562020-11-26 00:34:33 +00004048testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4049 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4050 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004051 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004052}
4053
4054testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4055 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4056 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004057 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004058}
4059
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004060testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004061 /* "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 +00004062 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4063 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004064 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004065}
4066
4067testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004068 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4069 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004070 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004071 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004072}
4073
Philipp Maierac09bfc2019-01-08 13:41:39 +01004074private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004075 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4076 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4077 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4078 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004079}
4080
4081private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004082 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4083 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004084}
4085
4086private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004087 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4088 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4089 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4090 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4091 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4092 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004093}
4094
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004095private function f_disable_all_sdcch() runs on test_CT {
4096 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4097 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4098 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4099 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4100}
4101
4102private function f_enable_all_sdcch() runs on test_CT {
4103 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4104 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4105 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4106 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4107}
4108
Philipp Maierac09bfc2019-01-08 13:41:39 +01004109/* Allow HR only */
4110private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4111 g_pars := f_gen_test_hdlr_pars();
4112 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4113 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4114 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4115 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4116 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4117 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4118 f_establish_fully(ass_cmd, exp_compl);
4119}
4120
4121/* Allow FR only */
4122private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4123 g_pars := f_gen_test_hdlr_pars();
4124 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4125 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4126 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4127 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4128 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4129 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4130 f_establish_fully(ass_cmd, exp_compl);
4131}
4132
4133/* Allow HR only (expect assignment failure) */
4134private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4135 g_pars := f_gen_test_hdlr_pars();
4136 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4137 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4138 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4139 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4140 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4141 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4142 f_establish_fully(ass_cmd, exp_fail);
4143}
4144
4145/* Allow FR only (expect assignment failure) */
4146private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4147 g_pars := f_gen_test_hdlr_pars();
4148 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4149 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4150 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4151 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4152 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4153 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4154 f_establish_fully(ass_cmd, exp_fail);
4155}
4156
4157/* Allow FR and HR, but prefer FR */
4158private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4159 g_pars := f_gen_test_hdlr_pars();
4160 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4161 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4162 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4163 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4164 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4165 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4166 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4167 f_establish_fully(ass_cmd, exp_compl);
4168}
4169
4170/* Allow FR and HR, but prefer HR */
4171private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4172 g_pars := f_gen_test_hdlr_pars();
4173 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4174 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4175 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4176 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4177 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4178 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4179 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4180 f_establish_fully(ass_cmd, exp_compl);
4181}
4182
4183/* Allow FR and HR, but prefer FR */
4184private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4185 g_pars := f_gen_test_hdlr_pars();
4186 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4187 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4188 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4189 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4190 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4191 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4192 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4193 f_establish_fully(ass_cmd, exp_compl);
4194}
4195
4196/* Allow FR and HR, but prefer HR */
4197private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4198 g_pars := f_gen_test_hdlr_pars();
4199 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4200 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4201 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4202 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4203 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4204 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4205 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4206 f_establish_fully(ass_cmd, exp_compl);
4207}
4208
4209/* Request a HR channel while all FR channels are exhausted, this is expected
4210 * to work without conflicts */
4211testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4212 var MSC_ConnHdlr vc_conn;
4213 f_init(1, true);
4214 f_sleep(1.0);
4215 f_enable_all_tch();
4216 f_disable_all_tch_f();
4217 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4218 vc_conn.done;
4219 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004220 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004221}
4222
4223/* Request a FR channel while all FR channels are exhausted, this is expected
4224 * to fail. */
4225testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4226 var MSC_ConnHdlr vc_conn;
4227 f_init(1, true);
4228 f_sleep(1.0);
4229 f_enable_all_tch();
4230 f_disable_all_tch_f();
4231 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4232 vc_conn.done;
4233 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004234 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004235}
4236
4237/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4238 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4239testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4240 var MSC_ConnHdlr vc_conn;
4241 f_init(1, true);
4242 f_sleep(1.0);
4243 f_enable_all_tch();
4244 f_disable_all_tch_f();
4245 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4246 vc_conn.done;
4247 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004248 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004249}
4250
4251/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4252 * are exhausted, this is expected to work without conflicts. */
4253testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4254 var MSC_ConnHdlr vc_conn;
4255 f_init(1, true);
4256 f_sleep(1.0);
4257 f_enable_all_tch();
4258 f_disable_all_tch_f();
4259 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4260 vc_conn.done;
4261 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004262 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004263}
4264
4265/* Request a FR channel while all HR channels are exhausted, this is expected
4266 * to work without conflicts */
4267testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4268 var MSC_ConnHdlr vc_conn;
4269 f_init(1, true);
4270 f_sleep(1.0);
4271 f_enable_all_tch();
4272 f_disable_all_tch_h();
4273 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4274 vc_conn.done;
4275 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004276 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004277}
4278
4279/* Request a HR channel while all HR channels are exhausted, this is expected
4280 * to fail. */
4281testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4282 var MSC_ConnHdlr vc_conn;
4283 f_init(1, true);
4284 f_sleep(1.0);
4285 f_enable_all_tch();
4286 f_disable_all_tch_h();
4287 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4288 vc_conn.done;
4289 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004290 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004291}
4292
4293/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4294 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4295testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4296 var MSC_ConnHdlr vc_conn;
4297 f_init(1, true);
4298 f_sleep(1.0);
4299 f_enable_all_tch();
4300 f_disable_all_tch_h();
4301 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4302 vc_conn.done;
4303 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004304 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004305}
4306
4307/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4308 * are exhausted, this is expected to work without conflicts. */
4309testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4310 var MSC_ConnHdlr vc_conn;
4311 f_init(1, true);
4312 f_sleep(1.0);
4313 f_enable_all_tch();
4314 f_disable_all_tch_h();
4315 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4316 vc_conn.done;
4317 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004318 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004319}
4320
4321/* Allow FR and HR, but prefer HR */
4322private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4323 g_pars := f_gen_test_hdlr_pars();
4324 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4325 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4326 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4327 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4328 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4329 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4330 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4331 f_establish_fully(ass_cmd, exp_compl);
4332}
4333
4334/* Allow FR and HR, but prefer FR */
4335private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4336 g_pars := f_gen_test_hdlr_pars();
4337 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4338 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4339 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4340 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4341 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4342 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4343 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4344 f_establish_fully(ass_cmd, exp_compl);
4345}
4346
4347/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4348 * HR, which is the prefered type, is selected. */
4349testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4350 var MSC_ConnHdlr vc_conn;
4351 f_init(1, true);
4352 f_sleep(1.0);
4353 f_enable_all_tch();
4354 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4355 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004356 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004357}
4358
4359/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4360 * FR, which is the prefered type, is selected. */
4361testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4362 var MSC_ConnHdlr vc_conn;
4363 f_init(1, true);
4364 f_sleep(1.0);
4365 f_enable_all_tch();
4366 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4367 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004368 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004369}
4370
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004371testcase TC_assignment_osmux() runs on test_CT {
4372 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4373 var MSC_ConnHdlr vc_conn;
4374
4375 /* See note above */
4376 var RSL_IE_Body mr_conf := {
4377 other := {
4378 len := 2,
4379 payload := '2804'O
4380 }
4381 };
4382
4383 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4384 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4385 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4386 pars.expect_mr_conf_ie := mr_conf;
4387 pars.use_osmux := true;
4388
4389 f_init(1, true, true);
4390 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004391 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004392
4393 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4394 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004395
4396 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004397 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004398}
4399
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004400/* test the procedure of the MSC requesting a Classmark Update:
4401 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4402 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004403private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004404 g_pars := f_gen_test_hdlr_pars();
4405
Harald Weltea0630032018-03-20 21:09:55 +01004406 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004407 /* we should now have a COMPL_L3 at the MSC */
4408 BSSAP.receive(tr_BSSMAP_ComplL3);
4409
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004410 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4411 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4412
Harald Welte898113b2018-01-31 18:32:21 +01004413 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4414 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4415 setverdict(pass);
4416}
4417testcase TC_classmark() runs on test_CT {
4418 var MSC_ConnHdlr vc_conn;
4419 f_init(1, true);
4420 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004421 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004422 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004423 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004424}
4425
Harald Welteeddf0e92020-06-21 19:42:15 +02004426/* Send a CommonID from the simulated MSC and verify that the information is used to
4427 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4428private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4429 g_pars := f_gen_test_hdlr_pars();
4430 f_MscConnHdlr_init_vty();
4431
4432 f_create_chan_and_exp();
4433 /* we should now have a COMPL_L3 at the MSC */
4434 BSSAP.receive(tr_BSSMAP_ComplL3);
4435
4436 /* Send CommonID */
4437 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4438
4439 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4440 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4441 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4442
4443 setverdict(pass);
4444}
4445testcase TC_common_id() runs on test_CT {
4446 var MSC_ConnHdlr vc_conn;
4447 f_init(1, true);
4448 f_sleep(1.0);
4449 vc_conn := f_start_handler(refers(f_tc_common_id));
4450 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004451 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004452}
4453
Harald Weltee3bd6582018-01-31 22:51:25 +01004454private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004455 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004456 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004457 /* we should now have a COMPL_L3 at the MSC */
4458 BSSAP.receive(tr_BSSMAP_ComplL3);
4459
Harald Weltee3bd6582018-01-31 22:51:25 +01004460 /* send the single message we want to send */
4461 f_rsl_send_l3(l3);
4462}
4463
4464private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4465 timer T := sec;
4466 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004467 T.start;
4468 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004469 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4470 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004471 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004472 }
4473 [] T.timeout {
4474 setverdict(pass);
4475 }
4476 }
4477}
4478
Harald Weltee3bd6582018-01-31 22:51:25 +01004479/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4480private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4481 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4482 f_bssap_expect_nothing();
4483}
Harald Welte898113b2018-01-31 18:32:21 +01004484testcase TC_unsol_ass_fail() runs on test_CT {
4485 var MSC_ConnHdlr vc_conn;
4486 f_init(1, true);
4487 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004488 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004489 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004490 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004491}
Harald Welte552620d2017-12-16 23:21:36 +01004492
Harald Welteea99a002018-01-31 20:46:43 +01004493
4494/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4495private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004496 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4497 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004498}
4499testcase TC_unsol_ass_compl() runs on test_CT {
4500 var MSC_ConnHdlr vc_conn;
4501 f_init(1, true);
4502 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004503 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004504 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004505 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004506}
4507
4508
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004509/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4510private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004511 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4512 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004513}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004514testcase TC_unsol_ho_fail() runs on test_CT {
4515 var MSC_ConnHdlr vc_conn;
4516 f_init(1, true);
4517 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004518 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004519 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004520 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004521}
4522
4523
Harald Weltee3bd6582018-01-31 22:51:25 +01004524/* short message from MS should be ignored */
4525private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004526 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004527 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01004528 /* we should now have a COMPL_L3 at the MSC */
4529 BSSAP.receive(tr_BSSMAP_ComplL3);
4530
4531 /* send short message */
4532 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
4533 f_bssap_expect_nothing();
4534}
4535testcase TC_err_82_short_msg() runs on test_CT {
4536 var MSC_ConnHdlr vc_conn;
4537 f_init(1, true);
4538 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004539 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01004540 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004541 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01004542}
4543
4544
Harald Weltee9e02e42018-01-31 23:36:25 +01004545/* 24.008 8.4 Unknown message must trigger RR STATUS */
4546private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
4547 f_est_single_l3(ts_RRM_UL_REL('00'O));
4548 timer T := 3.0
4549 alt {
4550 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
4551 setverdict(pass);
4552 }
4553 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01004554 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01004555 }
4556}
4557testcase TC_err_84_unknown_msg() runs on test_CT {
4558 var MSC_ConnHdlr vc_conn;
4559 f_init(1, true);
4560 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004561 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01004562 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004563 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01004564}
4565
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004566/***********************************************************************
4567 * Handover
4568 ***********************************************************************/
4569
Harald Welte94e0c342018-04-07 11:33:23 +02004570/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
4571private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
4572runs on test_CT {
4573 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4574 " timeslot "&int2str(ts_nr)&" ";
4575 f_vty_transceive(BSCVTY, cmd & suffix);
4576}
4577
Harald Welte261af4b2018-02-12 21:20:39 +01004578/* 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 +07004579private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
4580 uint8_t bts_nr, uint8_t trx_nr,
4581 in RslChannelNr chan_nr)
4582{
Harald Welte261af4b2018-02-12 21:20:39 +01004583 /* FIXME: resolve those from component-global state */
4584 var integer ts_nr := chan_nr.tn;
4585 var integer ss_nr;
4586 if (ischosen(chan_nr.u.ch0)) {
4587 ss_nr := 0;
4588 } else if (ischosen(chan_nr.u.lm)) {
4589 ss_nr := chan_nr.u.lm.sub_chan;
4590 } else if (ischosen(chan_nr.u.sdcch4)) {
4591 ss_nr := chan_nr.u.sdcch4.sub_chan;
4592 } else if (ischosen(chan_nr.u.sdcch8)) {
4593 ss_nr := chan_nr.u.sdcch8.sub_chan;
4594 } else {
4595 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02004596 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01004597 }
4598
4599 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4600 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004601 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01004602}
4603
Neels Hofmeyr91401012019-07-11 00:42:35 +02004604/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
4605 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
4606 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
4607 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
4608 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004609private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
4610 in RslChannelNr chan_nr, uint8_t new_bts_nr)
4611{
4612 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01004613}
4614
4615/* intra-BSC hand-over between BTS0 and BTS1 */
4616private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004617 g_pars := f_gen_test_hdlr_pars();
Harald Welteed848512018-05-24 22:27:58 +02004618 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4619 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01004620 const OCT8 kc := '0001020304050607'O;
4621
4622 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4623 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4624
Harald Weltea0630032018-03-20 21:09:55 +01004625 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02004626 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01004627
4628 var HandoverState hs := {
4629 rr_ho_cmpl_seen := false,
4630 handover_done := false,
4631 old_chan_nr := -
4632 };
4633 /* issue hand-over command on VTY */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004634 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01004635 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
4636 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004637
4638 /* From the MGW perspective, a handover is is characterized by
4639 * performing one MDCX operation with the MGW. So we expect to see
4640 * one more MDCX during handover. */
4641 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
4642
Harald Welte261af4b2018-02-12 21:20:39 +01004643 alt {
4644 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01004645 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004646
Philipp Maier4dae0652018-11-12 12:03:26 +01004647 /* Since this is an internal handover we expect the BSC to inform the
4648 * MSC about the event */
4649 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
4650
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004651 /* Check the amount of MGCP transactions is still consistant with the
4652 * test expectation */
4653 f_check_mgcp_expectations()
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01004654 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01004655}
4656
4657testcase TC_ho_int() runs on test_CT {
4658 var MSC_ConnHdlr vc_conn;
4659 f_init(2, true);
4660 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004661
4662 f_ctrs_bsc_and_bts_init();
4663
Harald Welte8863fa12018-05-10 20:15:27 +02004664 vc_conn := f_start_handler(refers(f_tc_ho_int));
Harald Welte261af4b2018-02-12 21:20:39 +01004665 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004666
4667 /* from f_establish_fully() */
4668 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4669 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4670 /* from handover */
4671 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4672 f_ctrs_bsc_and_bts_add(0, "handover:completed");
4673 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
4674 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
4675 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004676 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01004677}
Harald Weltee9e02e42018-01-31 23:36:25 +01004678
Neels Hofmeyr5f144212020-11-03 15:41:58 +00004679/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
4680private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
4681 g_pars := f_gen_test_hdlr_pars();
4682 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4683 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4684 const OCT8 kc := '0001020304050607'O;
4685
4686 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4687 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4688
4689 f_establish_fully(ass_cmd, exp_compl);
4690 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
4691
4692 var HandoverState hs := {
4693 rr_ho_cmpl_seen := false,
4694 handover_done := false,
4695 old_chan_nr := -
4696 };
4697 /* issue hand-over command on VTY */
4698 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
4699 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
4700 f_rslem_suspend(RSL1_PROC);
4701
4702 /* From the MGW perspective, a handover is is characterized by
4703 * performing one MDCX operation with the MGW. So we expect to see
4704 * one more MDCX during handover. */
4705 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
4706
4707 var RSL_Message rsl;
4708 var PDU_ML3_NW_MS l3;
4709 var RslChannelNr new_chan_nr;
4710 var GsmArfcn arfcn;
4711 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
4712 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
4713 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
4714 setverdict(fail, "Expected handoverCommand");
4715 mtc.stop;
4716 }
4717 }
4718 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
4719 new_chan_nr, arfcn);
4720
4721 f_rslem_register(0, new_chan_nr, RSL1_PROC);
4722
4723 /* resume processing of RSL DChan messages, which was temporarily suspended
4724 * before performing a hand-over */
4725 f_rslem_resume(RSL1_PROC);
4726 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
4727
4728 f_sleep(1.0);
4729
4730 /* Handover fails because no HANDO DET appears on the new lchan,
4731 * and the old lchan reports a Radio Link Failure. */
4732 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
4733
4734 var PDU_BSSAP rx_clear_request;
4735 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
4736 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
4737 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
4738
4739 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
4740
4741 var MgcpCommand mgcp;
4742 interleave {
4743 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
4744 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
4745 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
4746 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
4747 }
4748 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
4749 [] RSL1.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
4750 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
4751 }
4752 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
4753 }
4754
4755 f_sleep(0.5);
4756 setverdict(pass);
4757}
4758testcase TC_ho_int_radio_link_failure() runs on test_CT {
4759 var MSC_ConnHdlr vc_conn;
4760 f_init(2, true);
4761 f_sleep(1.0);
4762
4763 f_ctrs_bsc_and_bts_init();
4764
4765 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
4766 vc_conn.done;
4767
4768 /* from f_establish_fully() */
4769 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4770 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4771 /* from handover */
4772 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4773 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
4774 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
4775 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
4776 f_ctrs_bsc_and_bts_verify();
4777 f_shutdown_helper();
4778}
4779
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004780/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02004781private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004782 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02004783 var template MgcpResponse mgcp_resp;
4784 var MGCP_RecvFrom mrf;
4785 var template MgcpMessage msg_resp;
4786 var template MgcpMessage msg_dlcx := {
4787 command := tr_DLCX()
4788 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004789
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02004790 if (g_pars.aoip) {
4791 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004792 log("Got first DLCX: ", mgcp);
4793 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02004794 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004795
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004796 MGCP.receive(tr_DLCX()) -> value mgcp {
4797 log("Got second DLCX: ", mgcp);
4798 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
4799 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02004800 } else {
4801 /* For SCCPLite, BSC doesn't handle the MSC-side */
4802 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
4803 log("Got first DLCX: ", mrf.msg.command);
4804 msg_resp := {
4805 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
4806 }
4807 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
4808 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004809 }
4810
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02004811 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004812}
4813
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02004814private 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 +01004815
Neels Hofmeyr666f0432020-07-04 00:53:07 +02004816 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004817 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
4818
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02004819 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004820
4821 f_sleep(0.5);
4822 /* The MSC negotiates Handover Request and Handover Request Ack with
4823 * the other BSS and comes back with a BSSMAP Handover Command
4824 * containing an RR Handover Command coming from the target BSS... */
4825
4826 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
4827 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
4828 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
4829 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
4830 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
4831
4832 /* expect the Handover Command to go out on RR */
4833 var RSL_Message rsl_ho_cmd
4834 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
4835 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
4836 var RSL_IE_Body rsl_ho_cmd_l3;
4837 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
4838 log("RSL message contains no L3 Info IE, expected RR Handover Command");
4839 setverdict(fail);
4840 } else {
4841 log("Found L3 Info: ", rsl_ho_cmd_l3);
4842 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
4843 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
4844 setverdict(fail);
4845 } else {
4846 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
4847 setverdict(pass);
4848 }
4849 }
4850
4851 /* When the other BSS has reported a completed handover, this side is
4852 * torn down. */
4853
4854 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
4855 var BssmapCause cause := enum2int(cause_val);
4856 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
4857
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02004858 f_expect_dlcx_conns();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004859 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02004860}
4861
4862private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
4863 g_pars := f_gen_test_hdlr_pars();
4864 var PDU_BSSAP ass_req := f_gen_ass_req();
4865 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4866 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4867 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4868 f_establish_fully(ass_req, exp_compl);
4869
4870 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004871 f_sleep(1.0);
4872}
4873testcase TC_ho_out_of_this_bsc() runs on test_CT {
4874 var MSC_ConnHdlr vc_conn;
4875
4876 f_init(1, true);
4877 f_sleep(1.0);
4878
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004879 f_ctrs_bsc_and_bts_init();
4880
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004881 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
4882 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004883
4884 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4885 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4886 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4887 f_ctrs_bsc_and_bts_add(0, "handover:completed");
4888 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
4889 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
4890 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004891 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004892}
4893
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00004894private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
4895 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07004896 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07004897 octetstring l3 := '0123456789'O)
4898runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02004899 /* The old lchan and conn should still be active. See that arbitrary L3
4900 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00004901 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02004902 var template PDU_BSSAP exp_data := {
4903 discriminator := '1'B,
4904 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07004905 dlci := dlci,
4906 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02004907 pdu := {
4908 dtap := l3
4909 }
4910 };
4911 BSSAP.receive(exp_data);
4912 setverdict(pass);
4913}
4914
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00004915private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
4916 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07004917 template (value) OCT1 dlci := '00'O,
4918 octetstring l3 := '0123456789'O)
4919runs on MSC_ConnHdlr {
4920 BSSAP.send(PDU_BSSAP:{
4921 discriminator := '1'B,
4922 spare := '0000000'B,
4923 dlci := dlci,
4924 lengthIndicator := lengthof(l3),
4925 pdu := {
4926 dtap := l3
4927 }
4928 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00004929 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07004930 setverdict(pass);
4931}
4932
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004933/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
4934 * simply never sends a BSSMAP Handover Command. */
4935private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01004936 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004937
4938 var PDU_BSSAP ass_req := f_gen_ass_req();
4939 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4940 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4941 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4942 f_establish_fully(ass_req, exp_compl);
4943
Neels Hofmeyr666f0432020-07-04 00:53:07 +02004944 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004945 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
4946
4947 BSSAP.receive(tr_BSSMAP_HandoverRequired);
4948
4949 /* osmo-bsc should time out 10 seconds after the handover started.
4950 * Let's give it a bit extra. */
4951 f_sleep(15.0);
4952
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07004953 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004954 f_sleep(1.0);
4955}
4956testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
4957 var MSC_ConnHdlr vc_conn;
4958
4959 f_init(1, true);
4960 f_sleep(1.0);
4961
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004962 f_ctrs_bsc_and_bts_init();
4963
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004964 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
4965 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004966
4967 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4968 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4969 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4970 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
4971 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
4972 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
4973 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004974 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004975}
4976
4977/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
4978 * RR Handover Failure. */
4979private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01004980 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004981
4982 var PDU_BSSAP ass_req := f_gen_ass_req();
4983 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4984 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4985 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4986 f_establish_fully(ass_req, exp_compl);
4987
Neels Hofmeyr666f0432020-07-04 00:53:07 +02004988 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02004989 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
4990
4991 BSSAP.receive(tr_BSSMAP_HandoverRequired);
4992
4993 f_sleep(0.5);
4994 /* The MSC negotiates Handover Request and Handover Request Ack with
4995 * the other BSS and comes back with a BSSMAP Handover Command
4996 * containing an RR Handover Command coming from the target BSS... */
4997
4998 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
4999 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5000 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5001 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5002 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5003
5004 /* expect the Handover Command to go out on RR */
5005 var RSL_Message rsl_ho_cmd
5006 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5007 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5008 var RSL_IE_Body rsl_ho_cmd_l3;
5009 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5010 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5011 setverdict(fail);
5012 } else {
5013 log("Found L3 Info: ", rsl_ho_cmd_l3);
5014 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5015 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5016 setverdict(fail);
5017 } else {
5018 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5019 setverdict(pass);
5020 }
5021 }
5022
5023 f_sleep(0.2);
5024 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5025
5026 /* Should tell the MSC about the failure */
5027 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5028
5029 f_sleep(1.0);
5030
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005031 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005032 f_sleep(1.0);
5033
5034 setverdict(pass);
5035 f_sleep(1.0);
5036}
5037testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5038 var MSC_ConnHdlr vc_conn;
5039
5040 f_init(1, true);
5041 f_sleep(1.0);
5042
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005043 f_ctrs_bsc_and_bts_init();
5044
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005045 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5046 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005047
5048 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5049 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5050 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5051 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5052 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5053 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5054 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005055 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005056}
5057
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005058/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5059 * (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 +02005060 * and the lchan is released. */
5061private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005062 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005063
5064 var PDU_BSSAP ass_req := f_gen_ass_req();
5065 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5066 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5067 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5068 f_establish_fully(ass_req, exp_compl);
5069
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005070 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005071 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5072
5073 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5074
5075 f_sleep(0.5);
5076 /* The MSC negotiates Handover Request and Handover Request Ack with
5077 * the other BSS and comes back with a BSSMAP Handover Command
5078 * containing an RR Handover Command coming from the target BSS... */
5079
5080 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5081 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5082 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5083 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5084 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5085
5086 /* expect the Handover Command to go out on RR */
5087 var RSL_Message rsl_ho_cmd
5088 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5089 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5090 var RSL_IE_Body rsl_ho_cmd_l3;
5091 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5092 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5093 setverdict(fail);
5094 } else {
5095 log("Found L3 Info: ", rsl_ho_cmd_l3);
5096 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5097 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5098 setverdict(fail);
5099 } else {
5100 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5101 setverdict(pass);
5102 }
5103 }
5104
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005105 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5106 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5107 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005108
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005109 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005110 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5111 log("Got BSSMAP Clear Request");
5112 /* Instruct BSC to clear channel */
5113 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5114 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5115
5116 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005117 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005118 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5119 log("Got Deact SACCH");
5120 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005121 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005122 log("Got RR Release");
5123 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005124 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
5125 log("Got RF Chan Rel");
5126 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
5127 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005128 }
5129
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005130 f_expect_dlcx_conns();
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005131
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005132 setverdict(pass);
5133 f_sleep(1.0);
5134}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005135testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005136 var MSC_ConnHdlr vc_conn;
5137
5138 f_init(1, true);
5139 f_sleep(1.0);
5140
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005141 f_ctrs_bsc_and_bts_init();
5142
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005143 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005144 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005145
5146 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5147 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5148 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5149 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5150 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5151 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5152 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005153 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005154}
5155
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005156private 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 +01005157 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5158 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5159 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5160 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5161 * before we get started. */
5162 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5163 f_rslem_register(0, new_chan_nr);
5164 g_chan_nr := new_chan_nr;
5165 f_sleep(1.0);
5166
5167 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5168 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5169 activate(as_Media());
5170
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005171 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005172 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
5173 oldToNewBSSIEs := oldToNewBSSIEs)));
Harald Welte6811d102019-04-14 22:23:14 +02005174 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005175
5176 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5177
5178 var PDU_BSSAP rx_bssap;
5179 var octetstring ho_command_str;
5180
5181 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005182
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005183 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5184 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5185 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5186 log("L3 Info in HO Request Ack is ", ho_command);
5187
5188 var GsmArfcn arfcn;
5189 var RslChannelNr actual_new_chan_nr;
5190 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5191 actual_new_chan_nr, arfcn);
5192
5193 if (actual_new_chan_nr != new_chan_nr) {
5194 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5195 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5196 setverdict(fail);
5197 return;
5198 }
5199 log("Handover Command chan_nr is", actual_new_chan_nr);
5200
5201 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5202 * tells the MS to handover to the new lchan. Here comes the new MS on
5203 * the new lchan with a Handover RACH: */
5204
5205 /* send handover detect */
5206
5207 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5208
5209 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5210
5211 /* send handover complete over the new channel */
5212
5213 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5214 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5215 enc_PDU_ML3_MS_NW(l3_tx)));
5216
5217 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005218 setverdict(pass);
5219}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005220
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005221private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
5222 var template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
5223 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5224 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5225 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5226 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
5227 }
5228 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005229 f_perform_clear(RSL, exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005230 setverdict(pass);
5231}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005232function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005233 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005234
5235 f_init(1, true);
5236 f_sleep(1.0);
5237
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005238 f_ctrs_bsc_and_bts_init();
5239
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005240 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5241 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005242
5243 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5244 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005245
5246 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5247 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5248 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5249 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5250 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005251}
5252
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005253testcase TC_ho_into_this_bsc() runs on test_CT {
5254 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5255 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005256 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005257}
5258
5259testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5260 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5261 pars.host_aoip_tla := "::6";
5262 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005263 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005264}
5265
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005266/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005267 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005268 channel is later released (RR CHannel Release), should trigger inclusion of
5269 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5270 neighbors. */
5271testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5272 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5273 pars.last_used_eutran_plmn := '323454'O;
5274 f_tc_ho_into_this_bsc_main(pars);
5275 f_shutdown_helper();
5276}
5277
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005278private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5279 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5280 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5281 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5282 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5283 setverdict(pass);
5284}
5285/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5286 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5287 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5288 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5289testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5290 var MSC_ConnHdlr vc_conn;
5291 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5292
5293 f_init(1, true);
5294 f_sleep(1.0);
5295
5296 f_ctrs_bsc_and_bts_init();
5297
5298 pars.last_used_eutran_plmn := '323454'O;
5299 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5300 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5301
5302 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5303 vc_conn.done;
5304
5305 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5306 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5307 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5308 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5309 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5310 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
5311 f_ctrs_bsc_and_bts_verify();
5312 f_shutdown_helper();
5313}
5314
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005315private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5316 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5317 f_rslem_register(0, new_chan_nr);
5318 g_chan_nr := new_chan_nr;
5319 f_sleep(1.0);
5320
5321 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5322 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5323 activate(as_Media());
5324
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005325 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005326 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005327 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005328
5329 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5330
5331 var PDU_BSSAP rx_bssap;
5332 var octetstring ho_command_str;
5333
5334 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5335
5336 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5337 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5338 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5339 log("L3 Info in HO Request Ack is ", ho_command);
5340
5341 var GsmArfcn arfcn;
5342 var RslChannelNr actual_new_chan_nr;
5343 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5344 actual_new_chan_nr, arfcn);
5345
5346 if (actual_new_chan_nr != new_chan_nr) {
5347 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5348 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5349 setverdict(fail);
5350 return;
5351 }
5352 log("Handover Command chan_nr is", actual_new_chan_nr);
5353
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005354 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5355 f_sleep(1.0);
5356
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005357 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5358 * tells the MS to handover to the new lchan. In this case, the MS
5359 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5360 * Handover Failure to the MSC. The procedure according to 3GPP TS
5361 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5362 * BSSMAP Clear Command: */
5363
5364 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5365 var BssmapCause cause := enum2int(cause_val);
5366 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5367
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005368 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005369 setverdict(pass);
5370 f_sleep(1.0);
5371
5372 setverdict(pass);
5373}
5374testcase TC_ho_in_fail_msc_clears() runs on test_CT {
5375 var MSC_ConnHdlr vc_conn;
5376 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5377
5378 f_init(1, true);
5379 f_sleep(1.0);
5380
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005381 f_ctrs_bsc_and_bts_init();
5382
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005383 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5384 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005385
5386 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
5387 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005388
5389 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5390 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5391 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5392 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5393 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005394 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005395}
5396
5397private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
5398 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5399 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5400 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5401 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5402 * before we get started. */
5403 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5404 f_rslem_register(0, new_chan_nr);
5405 g_chan_nr := new_chan_nr;
5406 f_sleep(1.0);
5407
5408 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5409 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5410 activate(as_Media());
5411
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005412 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005413 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005414 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005415
5416 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5417
5418 var PDU_BSSAP rx_bssap;
5419 var octetstring ho_command_str;
5420
5421 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5422
5423 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5424 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5425 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5426 log("L3 Info in HO Request Ack is ", ho_command);
5427
5428 var GsmArfcn arfcn;
5429 var RslChannelNr actual_new_chan_nr;
5430 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5431 actual_new_chan_nr, arfcn);
5432
5433 if (actual_new_chan_nr != new_chan_nr) {
5434 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5435 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5436 setverdict(fail);
5437 return;
5438 }
5439 log("Handover Command chan_nr is", actual_new_chan_nr);
5440
5441 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5442 * tells the MS to handover to the new lchan. Here comes the new MS on
5443 * the new lchan with a Handover RACH: */
5444
5445 /* send handover detect */
5446
5447 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5448
5449 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5450
5451 /* The MSC chooses to clear the connection now, maybe we got the
5452 * Handover RACH on the new cell but the MS still signaled Handover
5453 * Failure to the old BSS? */
5454
5455 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5456 var BssmapCause cause := enum2int(cause_val);
5457 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5458
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005459 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005460 f_sleep(1.0);
5461}
5462testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
5463 var MSC_ConnHdlr vc_conn;
5464 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5465
5466 f_init(1, true);
5467 f_sleep(1.0);
5468
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005469 f_ctrs_bsc_and_bts_init();
5470
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005471 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5472 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005473
5474 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
5475 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005476
5477 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5478 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5479 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5480 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5481 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005482 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005483}
5484
5485/* The new BSS's lchan times out before the MSC decides that handover failed. */
5486private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
5487 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5488 f_rslem_register(0, new_chan_nr);
5489 g_chan_nr := new_chan_nr;
5490 f_sleep(1.0);
5491
5492 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5493 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5494 activate(as_Media());
5495
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005496 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005497 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005498 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005499
5500 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5501
5502 var PDU_BSSAP rx_bssap;
5503 var octetstring ho_command_str;
5504
5505 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5506
5507 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5508 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5509 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5510 log("L3 Info in HO Request Ack is ", ho_command);
5511
5512 var GsmArfcn arfcn;
5513 var RslChannelNr actual_new_chan_nr;
5514 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5515 actual_new_chan_nr, arfcn);
5516
5517 if (actual_new_chan_nr != new_chan_nr) {
5518 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5519 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5520 setverdict(fail);
5521 return;
5522 }
5523 log("Handover Command chan_nr is", actual_new_chan_nr);
5524
5525 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5526 * tells the MS to handover to the new lchan. But the MS never shows up
5527 * on the new lchan. */
5528
5529 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5530
5531 /* Did osmo-bsc also send a Clear Request? */
5532 timer T := 0.5;
5533 T.start;
5534 alt {
5535 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
5536 [] T.timeout { }
5537 }
5538
5539 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
5540 * asked for it, this is a Handover Failure after all). */
5541
5542 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5543 var BssmapCause cause := enum2int(cause_val);
5544 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5545
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005546 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005547 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005548}
5549testcase TC_ho_in_fail_no_detect() runs on test_CT {
5550 var MSC_ConnHdlr vc_conn;
5551 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5552
5553 f_init(1, true);
5554 f_sleep(1.0);
5555
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005556 f_ctrs_bsc_and_bts_init();
5557
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005558 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5559 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005560
5561 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
5562 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005563
5564 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5565 f_ctrs_bsc_and_bts_add(0, "handover:error");
5566 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5567 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
5568 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005569 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005570}
5571
5572/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
5573private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
5574 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5575 f_rslem_register(0, new_chan_nr);
5576 g_chan_nr := new_chan_nr;
5577 f_sleep(1.0);
5578
5579 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5580 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5581 activate(as_Media());
5582
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005583 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005584 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005585 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005586
5587 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5588
5589 var PDU_BSSAP rx_bssap;
5590 var octetstring ho_command_str;
5591
5592 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5593
5594 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5595 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5596 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5597 log("L3 Info in HO Request Ack is ", ho_command);
5598
5599 var GsmArfcn arfcn;
5600 var RslChannelNr actual_new_chan_nr;
5601 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5602 actual_new_chan_nr, arfcn);
5603
5604 if (actual_new_chan_nr != new_chan_nr) {
5605 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5606 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5607 setverdict(fail);
5608 return;
5609 }
5610 log("Handover Command chan_nr is", actual_new_chan_nr);
5611
5612 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5613 * tells the MS to handover to the new lchan. But the MS never shows up
5614 * on the new lchan. */
5615
5616 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5617
5618 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005619 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005620
5621 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005622 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5623 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5624 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005625 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005626 f_sleep(1.0);
5627}
5628testcase TC_ho_in_fail_no_detect2() runs on test_CT {
5629 var MSC_ConnHdlr vc_conn;
5630 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5631
5632 f_init(1, true);
5633 f_sleep(1.0);
5634
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005635 f_ctrs_bsc_and_bts_init();
5636
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005637 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5638 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005639
5640 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
5641 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005642
5643 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5644 f_ctrs_bsc_and_bts_add(0, "handover:error");
5645 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5646 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
5647 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005648 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005649}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005650
Neels Hofmeyr91401012019-07-11 00:42:35 +02005651type record of charstring Commands;
5652
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005653private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02005654{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005655 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02005656 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005657 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02005658 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005659 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02005660}
5661
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01005662private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
5663{
5664 f_vty_enter_cfg_cs7_inst(pt, 0);
5665 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
5666 f_vty_transceive(pt, cmds[i]);
5667 }
5668 f_vty_transceive(pt, "end");
5669}
5670
Neels Hofmeyr91401012019-07-11 00:42:35 +02005671private function f_probe_for_handover(charstring log_label,
5672 charstring log_descr,
5673 charstring handover_vty_cmd,
5674 boolean expect_handover,
5675 boolean is_inter_bsc_handover := false)
5676runs on MSC_ConnHdlr
5677{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02005678 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
5679 * lchans to be established on bts 1 or bts 2. */
5680 f_rslem_suspend(RSL1_PROC);
5681 f_rslem_suspend(RSL2_PROC);
5682
Neels Hofmeyr91401012019-07-11 00:42:35 +02005683 var RSL_Message rsl;
5684
5685 var charstring log_msg := " (expecting handover)"
5686 if (not expect_handover) {
5687 log_msg := " (expecting NO handover)";
5688 }
5689 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
5690 f_vty_transceive(BSCVTY, handover_vty_cmd);
5691
Neels Hofmeyr91401012019-07-11 00:42:35 +02005692 timer T := 2.0;
5693 T.start;
5694
5695 alt {
5696 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5697 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5698 log("Rx L3 from net: ", l3);
5699 if (ischosen(l3.msgs.rrm.handoverCommand)) {
5700 var RslChannelNr new_chan_nr;
5701 var GsmArfcn arfcn;
5702 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5703 new_chan_nr, arfcn);
5704 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
5705 log(l3.msgs.rrm.handoverCommand);
5706
5707 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
5708 * matter on which BTS it really is, we're not going to follow through an entire handover
5709 * anyway. */
5710 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5711 f_rslem_resume(RSL1_PROC);
5712 f_rslem_register(0, new_chan_nr, RSL2_PROC);
5713 f_rslem_resume(RSL2_PROC);
5714
5715 if (expect_handover and not is_inter_bsc_handover) {
5716 setverdict(pass);
5717 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
5718 } else {
5719 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
5720 & log_label & ": " & log_descr);
5721 }
5722
5723 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
5724 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
5725 * Handover Failure. */
5726 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5727
5728 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
5729 f_sleep(0.5);
5730 RSL1.clear;
5731 RSL2.clear;
5732 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
5733 break;
5734 } else {
5735 repeat;
5736 }
5737 }
5738 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
5739 if (expect_handover and is_inter_bsc_handover) {
5740 setverdict(pass);
5741 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
5742 } else {
5743 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
5744 & log_label & ": " & log_descr);
5745 }
5746
5747 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
5748
5749 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
5750 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
5751 * setting a short timeout and waiting is the only way. */
5752 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
5753 f_sleep(1.5);
5754 log("f_probe_for_handover(" & log_label & "): ...done");
5755
5756 break;
5757 }
5758 [] T.timeout {
5759 if (expect_handover) {
5760 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
5761 & log_label & ": " & log_descr);
5762 } else {
5763 setverdict(pass);
5764 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
5765 }
5766 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
5767 break;
5768 }
5769 }
5770
5771 f_rslem_resume(RSL1_PROC);
5772 f_rslem_resume(RSL2_PROC);
5773 f_sleep(3.0);
5774 RSL.clear;
5775
5776 log("f_probe_for_handover(" & log_label & "): done clearing");
5777}
5778
5779/* Test the effect of various neighbor configuration scenarios:
5780 *
5781 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
5782 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
5783 */
5784private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
5785 g_pars := f_gen_test_hdlr_pars();
5786 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5787 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5788 const OCT8 kc := '0001020304050607'O;
5789
5790 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5791 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5792
5793 /* Establish lchan at bts 0 */
5794 f_establish_fully(ass_cmd, exp_compl);
5795
5796 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
5797 f_vty_enter_cfg_network(BSCVTY);
5798 f_vty_transceive(BSCVTY, "timer T7 1");
5799 f_vty_transceive(BSCVTY, "end");
5800}
5801
5802private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
5803 f_tc_ho_neighbor_config_start();
5804
5805 /*
5806 * bts 0 ARFCN 871 BSIC 10
5807 * bts 1 ARFCN 871 BSIC 11
5808 * bts 2 ARFCN 871 BSIC 12
5809 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
5810 */
5811
5812 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005813 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02005814 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
5815 "handover any to arfcn 871 bsic 11",
5816 true);
5817
5818 f_probe_for_handover("1.b", "HO to unknown cell does not start",
5819 "handover any to arfcn 13 bsic 39",
5820 false);
5821
5822 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
5823 "handover any to arfcn 871 bsic 12",
5824 false);
5825
5826 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
5827 "handover any to arfcn 871 bsic 11",
5828 true);
5829}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005830testcase TC_ho_neighbor_config_1() runs on test_CT {
5831 var MSC_ConnHdlr vc_conn;
5832 f_init(3, true, guard_timeout := 60.0);
5833 f_sleep(1.0);
5834 f_ctrs_bsc_and_bts_init();
5835 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
5836 vc_conn.done;
5837
5838 /* f_tc_ho_neighbor_config_start() */
5839 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5840 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5841
5842 /* 1.a */
5843 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
5844 * handover quickly by sending a Handover Failure message. */
5845 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5846 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5847 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5848 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
5849
5850 /* 1.b */
5851 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5852 f_ctrs_bsc_and_bts_add(0, "handover:error");
5853
5854 /* 1.c */
5855 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5856 f_ctrs_bsc_and_bts_add(0, "handover:error");
5857
5858 /* 1.d */
5859 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5860 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5861 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5862 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
5863
5864 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005865 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005866}
5867
Neels Hofmeyr91401012019-07-11 00:42:35 +02005868private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
5869 f_tc_ho_neighbor_config_start();
5870
5871 /*
5872 * bts 0 ARFCN 871 BSIC 10
5873 * bts 1 ARFCN 871 BSIC 11
5874 * bts 2 ARFCN 871 BSIC 12
5875 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
5876 */
5877
5878 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005879 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02005880 f_sleep(0.5);
5881
5882 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
5883 "handover any to arfcn 871 bsic 11",
5884 true);
5885
5886 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
5887 "handover any to arfcn 871 bsic 12",
5888 false);
5889}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005890testcase TC_ho_neighbor_config_2() runs on test_CT {
5891 var MSC_ConnHdlr vc_conn;
5892 f_init(3, true, guard_timeout := 50.0);
5893 f_sleep(1.0);
5894 f_ctrs_bsc_and_bts_init();
5895 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
5896 vc_conn.done;
5897
5898 /* f_tc_ho_neighbor_config_start() */
5899 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5900 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5901
5902 /* 2.a */
5903 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
5904 * handover quickly by sending a Handover Failure message. */
5905 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5906 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5907 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5908 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
5909
5910 /* 2.b */
5911 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5912 f_ctrs_bsc_and_bts_add(0, "handover:error");
5913
5914 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005915 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005916}
5917
Neels Hofmeyr91401012019-07-11 00:42:35 +02005918private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
5919 f_tc_ho_neighbor_config_start();
5920
5921 /*
5922 * bts 0 ARFCN 871 BSIC 10
5923 * bts 1 ARFCN 871 BSIC 11
5924 * bts 2 ARFCN 871 BSIC 12
5925 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
5926 */
5927
5928 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005929 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02005930 f_sleep(0.5);
5931
5932 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
5933 "handover any to arfcn 871 bsic 11",
5934 false);
5935 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",
5936 "handover any to arfcn 871 bsic 12",
5937 true);
5938}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005939testcase TC_ho_neighbor_config_3() runs on test_CT {
5940 var MSC_ConnHdlr vc_conn;
5941 f_init(3, true, guard_timeout := 50.0);
5942 f_sleep(1.0);
5943 f_ctrs_bsc_and_bts_init();
5944 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
5945 vc_conn.done;
5946
5947 /* f_tc_ho_neighbor_config_start() */
5948 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5949 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5950
5951 /* 3.a */
5952 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5953 f_ctrs_bsc_and_bts_add(0, "handover:error");
5954
5955 /* 3.b */
5956 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
5957 * handover quickly by sending a Handover Failure message. */
5958 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5959 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5960 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5961 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
5962
5963 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005964 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005965}
5966
Neels Hofmeyr91401012019-07-11 00:42:35 +02005967private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
5968 f_tc_ho_neighbor_config_start();
5969
5970 /*
5971 * bts 0 ARFCN 871 BSIC 10
5972 * bts 1 ARFCN 871 BSIC 11
5973 * bts 2 ARFCN 871 BSIC 12
5974 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
5975 */
5976
5977 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005978 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02005979 f_sleep(0.5);
5980
5981 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
5982 "handover any to arfcn 871 bsic 11",
5983 false);
5984 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
5985 "handover any to arfcn 871 bsic 12",
5986 false);
5987 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
5988 "handover any to arfcn 123 bsic 45",
5989 true, true);
5990}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005991testcase TC_ho_neighbor_config_4() runs on test_CT {
5992 var MSC_ConnHdlr vc_conn;
5993 f_init(3, true, guard_timeout := 50.0);
5994 f_sleep(1.0);
5995 f_ctrs_bsc_and_bts_init();
5996 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
5997 vc_conn.done;
5998
5999 /* f_tc_ho_neighbor_config_start() */
6000 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6001 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6002
6003 /* 4.a */
6004 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6005 f_ctrs_bsc_and_bts_add(0, "handover:error");
6006
6007 /* 4.b */
6008 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6009 f_ctrs_bsc_and_bts_add(0, "handover:error");
6010
6011 /* 4.c */
6012 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6013 * handover quickly by timing out after the Handover Required message */
6014 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6015 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6016 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6017 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6018
6019 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006020 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006021}
6022
Neels Hofmeyr91401012019-07-11 00:42:35 +02006023private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6024 f_tc_ho_neighbor_config_start();
6025
6026 /*
6027 * bts 0 ARFCN 871 BSIC 10
6028 * bts 1 ARFCN 871 BSIC 11
6029 * bts 2 ARFCN 871 BSIC 12
6030 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6031 */
6032
6033 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 +02006034 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006035 f_sleep(0.5);
6036
6037 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6038 "handover any to arfcn 871 bsic 12",
6039 true, true);
6040}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006041testcase TC_ho_neighbor_config_5() runs on test_CT {
6042 var MSC_ConnHdlr vc_conn;
6043 f_init(3, true);
6044 f_sleep(1.0);
6045 f_ctrs_bsc_and_bts_init();
6046 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6047 vc_conn.done;
6048
6049 /* f_tc_ho_neighbor_config_start() */
6050 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6051 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6052
6053 /* 5 */
6054 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6055 * handover quickly by timing out after the Handover Required message */
6056 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6057 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6058 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6059 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6060
6061 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006062 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006063}
6064
Neels Hofmeyr91401012019-07-11 00:42:35 +02006065private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6066 f_tc_ho_neighbor_config_start();
6067
6068 /*
6069 * bts 0 ARFCN 871 BSIC 10
6070 * bts 1 ARFCN 871 BSIC 11
6071 * bts 2 ARFCN 871 BSIC 12
6072 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6073 */
6074
6075 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6076 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006077 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006078 f_sleep(0.5);
6079
6080 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6081 "handover any to arfcn 871 bsic 12",
6082 false);
6083}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006084testcase TC_ho_neighbor_config_6() runs on test_CT {
6085 var MSC_ConnHdlr vc_conn;
6086 f_init(3, true);
6087 f_sleep(1.0);
6088 f_ctrs_bsc_and_bts_init();
6089 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6090 vc_conn.done;
6091
6092 /* f_tc_ho_neighbor_config_start() */
6093 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6094 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6095
6096 /* 6.a */
6097 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6098 * handover quickly by timing out after the Handover Required message */
6099 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6100 f_ctrs_bsc_and_bts_add(0, "handover:error");
6101
6102 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006103 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006104}
6105
Neels Hofmeyr91401012019-07-11 00:42:35 +02006106private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6107 f_tc_ho_neighbor_config_start();
6108
6109 /*
6110 * bts 0 ARFCN 871 BSIC 10
6111 * bts 1 ARFCN 871 BSIC 11
6112 * bts 2 ARFCN 871 BSIC 12
6113 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6114 */
6115
6116 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6117 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006118 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006119 f_sleep(0.5);
6120
6121 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6122 "handover any to arfcn 871 bsic 12",
6123 true);
6124 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6125 "handover any to arfcn 123 bsic 45",
6126 true, true);
6127}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006128testcase TC_ho_neighbor_config_7() runs on test_CT {
6129 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006130 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006131 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006132 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006133 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6134 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006135
6136 /* f_tc_ho_neighbor_config_start() */
6137 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6138 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6139
6140 /* 7.a */
6141 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6142 * handover quickly by sending a Handover Failure message. */
6143 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6144 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6145 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6146 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6147
6148 /* 7.b */
6149 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6150 * handover quickly by timing out after the Handover Required message */
6151 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6152 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6153 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6154 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6155
6156 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006157 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006158}
6159
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006160/* OS#3041: Open and close N connections in a normal fashion, and expect no
6161 * BSSMAP Reset just because of that. */
6162testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6163 var default d;
6164 var integer i;
6165 var DchanTuple dt;
6166
6167 f_init();
6168
6169 /* Wait for initial BSSMAP Reset to pass */
6170 f_sleep(4.0);
6171
6172 d := activate(no_bssmap_reset());
6173
6174 /* Setup up a number of connections and RLSD them again from the MSC
6175 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6176 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006177 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006178 /* Since we're doing a lot of runs, give each one a fresh
6179 * T_guard from the top. */
6180 T_guard.start;
6181
6182 /* Setup a BSSAP connection and clear it right away. This is
6183 * the MSC telling the BSC about a planned release, it's not an
6184 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006185 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006186
6187 /* MSC disconnects (RLSD). */
6188 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6189 }
6190
6191 /* In the buggy behavior, a timeout of 2 seconds happens between above
6192 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6193 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6194 f_sleep(4.0);
6195
6196 deactivate(d);
6197 f_shutdown_helper();
6198}
Harald Welte552620d2017-12-16 23:21:36 +01006199
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006200/* OS#3041: Open and close N connections in a normal fashion, and expect no
6201 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6202 * the MSC. */
6203testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6204 var default d;
6205 var integer i;
6206 var DchanTuple dt;
6207 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006208 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6209 var BssmapCause cause := enum2int(cause_val);
6210
6211 f_init();
6212
6213 /* Wait for initial BSSMAP Reset to pass */
6214 f_sleep(4.0);
6215
6216 d := activate(no_bssmap_reset());
6217
6218 /* Setup up a number of connections and RLSD them again from the MSC
6219 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6220 * Let's do it some more times for good measure. */
6221 for (i := 0; i < 8; i := i+1) {
6222 /* Since we're doing a lot of runs, give each one a fresh
6223 * T_guard from the top. */
6224 T_guard.start;
6225
6226 /* Setup a BSSAP connection and clear it right away. This is
6227 * the MSC telling the BSC about a planned release, it's not an
6228 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006229 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006230
6231 /* Instruct BSC to clear channel */
6232 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6233
6234 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006235 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006236 }
6237
6238 /* In the buggy behavior, a timeout of 2 seconds happens between above
6239 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6240 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6241 f_sleep(4.0);
6242
6243 deactivate(d);
6244 f_shutdown_helper();
6245}
6246
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006247/* OS#3041: Open and close N connections in a normal fashion, and expect no
6248 * BSSMAP Reset just because of that. Close connections from the MS side with a
6249 * Release Ind on RSL. */
6250testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6251 var default d;
6252 var integer i;
6253 var DchanTuple dt;
6254 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006255 var integer j;
6256
6257 f_init();
6258
6259 /* Wait for initial BSSMAP Reset to pass */
6260 f_sleep(4.0);
6261
6262 d := activate(no_bssmap_reset());
6263
6264 /* Setup up a number of connections and RLSD them again from the MSC
6265 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6266 * Let's do it some more times for good measure. */
6267 for (i := 0; i < 8; i := i+1) {
6268 /* Since we're doing a lot of runs, give each one a fresh
6269 * T_guard from the top. */
6270 T_guard.start;
6271
6272 /* Setup a BSSAP connection and clear it right away. This is
6273 * the MSC telling the BSC about a planned release, it's not an
6274 * erratic loss of a connection. */
6275 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6276
6277 /* simulate RLL REL IND */
6278 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6279
6280 /* expect Clear Request on MSC side */
6281 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6282
6283 /* Instruct BSC to clear channel */
6284 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6285 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6286
6287 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006288 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006289 }
6290
6291 /* In the buggy behavior, a timeout of 2 seconds happens between above
6292 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6293 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6294 f_sleep(4.0);
6295
6296 deactivate(d);
6297 f_shutdown_helper();
6298}
6299
Harald Welte94e0c342018-04-07 11:33:23 +02006300/***********************************************************************
6301 * IPA style dynamic PDCH
6302 ***********************************************************************/
6303
6304private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6305 template (omit) RSL_Cause nack := omit)
6306runs on test_CT {
6307 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6308 var RSL_Message rsl_unused;
6309 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6310 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6311 /* expect the BSC to issue the related RSL command */
6312 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6313 if (istemplatekind(nack, "omit")) {
6314 /* respond with a related acknowledgement */
6315 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6316 } else {
6317 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6318 }
6319}
6320
6321private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6322 template (omit) RSL_Cause nack := omit)
6323runs on test_CT {
6324 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6325 var RSL_Message rsl_unused;
6326 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6327 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6328 /* expect the BSC to issue the related RSL command */
6329 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6330 if (istemplatekind(nack, "omit")) {
6331 /* respond with a related acknowledgement */
6332 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6333 } else {
6334 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6335 }
6336}
6337
6338private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6339runs on test_CT return charstring {
6340 var charstring cmd, resp;
6341 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006342 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006343}
6344
6345private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6346 template charstring exp)
6347runs on test_CT {
6348 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
6349 if (not match(mode, exp)) {
6350 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02006351 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02006352 }
6353}
6354
6355private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
6356runs on test_CT {
6357 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
6358 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
6359 f_vty_transceive(BSCVTY, "end");
6360}
6361
6362private const charstring TCHF_MODE := "TCH/F mode";
6363private const charstring TCHH_MODE := "TCH/H mode";
6364private const charstring PDCH_MODE := "PDCH mode";
6365private const charstring NONE_MODE := "NONE mode";
6366
6367/* Test IPA PDCH activation / deactivation triggered by VTY */
6368testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
6369 var RSL_Message rsl_unused;
6370
6371 /* change Timeslot 6 before f_init() starts RSL */
6372 f_init_vty();
6373 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6374 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6375
6376 f_init(1, false);
6377 f_sleep(1.0);
6378
6379 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6380
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006381 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006382 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6383 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6384 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6385 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6386 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006387 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006388 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6389
6390 /* De-activate it via VTY */
6391 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6392 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006393 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006394 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6395
6396 /* re-activate it via VTY */
6397 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
6398 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006399 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006400 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6401
6402 /* and finally de-activate it again */
6403 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6404 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006405 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006406 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6407
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006408 /* clean up config */
6409 f_ts_set_chcomb(0, 0, 6, "PDCH");
6410
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006411 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006412}
6413
6414/* Test IPA PDCH activation NACK */
6415testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
6416 var RSL_Message rsl_unused;
6417
6418 /* change Timeslot 6 before f_init() starts RSL */
6419 f_init_vty();
6420 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6421 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6422
6423 f_init(1, false);
6424 f_sleep(1.0);
6425
6426 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6427
6428 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6429 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6430 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6431 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6432 f_sleep(1.0);
6433 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6434
6435 /* De-activate it via VTY */
6436 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6437 f_sleep(1.0);
6438 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6439
6440 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
6441 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
6442 f_sleep(1.0);
6443 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6444
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006445 /* clean up config */
6446 f_ts_set_chcomb(0, 0, 6, "PDCH");
6447
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006448 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006449}
6450
6451
6452/***********************************************************************
6453 * Osmocom style dynamic PDCH
6454 ***********************************************************************/
6455
6456private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6457 template (omit) RSL_Cause nack := omit)
6458runs on test_CT {
6459 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6460 var RSL_Message rsl_unused;
6461 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6462 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6463 /* expect the BSC to issue the related RSL command */
6464 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
6465 if (istemplatekind(nack, "omit")) {
6466 /* respond with a related acknowledgement */
6467 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
6468 } else {
6469 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
6470 }
6471}
6472
6473private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6474 template (omit) RSL_Cause nack := omit)
6475runs on test_CT {
6476 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6477 var RSL_Message rsl_unused;
6478 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6479 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6480 /* expect the BSC to issue the related RSL command */
6481 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
6482 if (istemplatekind(nack, "omit")) {
6483 /* respond with a related acknowledgement */
6484 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
6485 } else {
6486 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
6487 }
6488}
6489
6490/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
6491testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
6492 var RSL_Message rsl_unused;
6493
6494 /* change Timeslot 6 before f_init() starts RSL */
6495 f_init_vty();
6496 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
6497 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6498
6499 f_init(1, false);
6500 f_sleep(1.0);
6501
6502 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
6503
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006504 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006505 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6506 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6507 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
6508
6509 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
6510 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006511 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 +02006512 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6513
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006514 /* clean up config */
6515 f_ts_set_chcomb(0, 0, 6, "PDCH");
6516
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006517 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006518}
6519
6520/* Test Osmocom dyn PDCH activation NACK behavior */
6521testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
6522 var RSL_Message rsl_unused;
6523
6524 /* change Timeslot 6 before f_init() starts RSL */
6525 f_init_vty();
6526 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
6527 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6528
6529 f_init(1, false);
6530 f_sleep(1.0);
6531
6532 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
6533
6534 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6535 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6536 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
6537
6538 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
6539 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
6540 f_sleep(1.0);
6541 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6542
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006543 /* clean up config */
6544 f_ts_set_chcomb(0, 0, 6, "PDCH");
6545
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006546 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006547}
6548
Stefan Sperling0796a822018-10-05 13:01:39 +02006549testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02006550 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02006551 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
6552 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
6553 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006554 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02006555}
6556
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02006557testcase TC_chopped_ipa_payload() runs on test_CT {
6558 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
6559 /* TODO: mp_bsc_ctrl_port does not work yet */};
6560 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
6561 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
6562 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006563 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02006564}
6565
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01006566/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
6567 the BTS does autonomous MS power control loop */
6568testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
6569 var MSC_ConnHdlr vc_conn;
6570 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6571 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
6572 pars.exp_ms_power_params := true;
6573
6574 f_init(1, true);
6575 f_sleep(1.0);
6576 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
6577 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006578 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01006579}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02006580
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006581/***********************************************************************
6582 * MSC Pooling
6583 ***********************************************************************/
6584
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006585template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01006586 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 +02006587
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006588private function f_expect_lchan_rel(RSL_DCHAN_PT rsl, template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
6589runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02006590 interleave {
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006591 [] rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02006592 f_logp(BSCVTY, "Got RSL RR Release");
6593 }
6594 [] rsl.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6595 f_logp(BSCVTY, "Got RSL Deact SACCH");
6596 }
6597 [] rsl.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
6598 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
6599 rsl.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
6600 break;
6601 }
6602 }
6603}
6604
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006605private function f_perform_clear(RSL_DCHAN_PT rsl, template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
6606runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00006607 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006608 BSSAP.send(ts_BSSMAP_ClearCommand(0));
6609 interleave {
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006610 [] rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00006611 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006612 }
6613 [] rsl.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00006614 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006615 }
6616 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00006617 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006618 /* Also drop the SCCP connection */
6619 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
6620 }
6621 [] rsl.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00006622 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006623 rsl.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
6624 }
6625 }
6626}
6627
Neels Hofmeyr66e15092020-10-12 18:44:41 +00006628private function f_perform_compl_l3(RSL_DCHAN_PT rsl, template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006629runs on MSC_ConnHdlr {
6630 timer T := 10.0;
6631 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
6632
Neels Hofmeyr767548a2020-08-09 20:26:07 +00006633 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006634 f_create_bssmap_exp(l3_enc);
6635
6636 /* RSL_Emulation.f_chan_est() on rsl:
6637 * This is basically code dup with s/RSL/rsl from:
6638 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
6639 */
6640 var RSL_Message rx_rsl;
6641 var GsmRrMessage rr;
6642
6643 /* request a channel to be established */
6644 rsl.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
6645 /* expect immediate assignment.
6646 * Code dup with s/RSL/rsl from:
6647 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
6648 */
6649 timer Tt := 10.0;
6650
6651 /* request a channel to be established */
6652 Tt.start;
6653 alt {
6654 [] rsl.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
6655 Tt.stop;
6656 }
6657 [] rsl.receive {
6658 setverdict(fail, "Unexpected RSL message on DCHAN");
6659 mtc.stop;
6660 }
6661 [] Tt.timeout {
6662 setverdict(fail, "Timeout waiting for RSL on DCHAN");
6663 mtc.stop;
6664 }
6665 }
6666 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
6667 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
6668 rsl.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
6669
6670
Neels Hofmeyr66e15092020-10-12 18:44:41 +00006671 if (expect_bssmap_l3) {
6672 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
6673 var template PDU_BSSAP exp_l3_compl;
6674 exp_l3_compl := tr_BSSMAP_ComplL3()
6675 if (g_pars.aoip == false) {
6676 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
6677 } else {
6678 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
6679 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006680
Neels Hofmeyr66e15092020-10-12 18:44:41 +00006681 var PDU_BSSAP bssap;
6682 T.start;
6683 alt {
6684 [] BSSAP.receive(exp_l3_compl) -> value bssap {
6685 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
6686 log("rx exp_l3_compl = ", bssap);
6687 }
6688 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
6689 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
6690 }
6691 [] T.timeout {
6692 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
6693 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006694 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006695
Neels Hofmeyr66e15092020-10-12 18:44:41 +00006696 /* start ciphering, if requested */
6697 if (ispresent(g_pars.encr)) {
6698 f_logp(BSCVTY, "start ciphering");
6699 f_cipher_mode(g_pars.encr.enc_alg, g_pars.encr.enc_key);
6700 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006701 }
6702
6703 if (do_clear) {
6704 f_perform_clear(rsl);
6705 }
6706 setverdict(pass);
6707 f_sleep(1.0);
6708}
6709
6710private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
6711 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6712 if (g_pars.mscpool.rsl_idx == 0) {
6713 f_perform_compl_l3(RSL, g_pars.mscpool.l3_info);
6714 } else if (g_pars.mscpool.rsl_idx == 1) {
6715 f_perform_compl_l3(RSL1, g_pars.mscpool.l3_info);
6716 } else if (g_pars.mscpool.rsl_idx == 2) {
6717 f_perform_compl_l3(RSL2, g_pars.mscpool.l3_info);
6718 }
6719}
6720
6721/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
6722private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
6723 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6724 f_perform_compl_l3(RSL, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
6725 f_perform_compl_l3(RSL, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
6726 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
6727 f_perform_compl_l3(RSL, ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_IMSI_LV('001010000000004'H))) );
6728}
6729testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
6730
6731 f_init(1, true);
6732 f_sleep(1.0);
6733 var MSC_ConnHdlr vc_conn;
6734 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006735
6736 f_ctrs_msc_init();
6737
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006738 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
6739 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006740
6741 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006742 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006743}
6744
6745/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
6746/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
6747 * just as well using only RSL. */
6748testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
6749
6750 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
6751 f_sleep(1.0);
6752
6753 /* Control which MSC gets chosen next by the round-robin, otherwise
6754 * would be randomly affected by which other tests ran before this. */
6755 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
6756
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006757 f_ctrs_msc_init();
6758
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006759 var MSC_ConnHdlr vc_conn1;
6760 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
6761 pars1.mscpool.rsl_idx := 0;
6762 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
6763 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
6764 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006765 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006766
6767 var MSC_ConnHdlr vc_conn2;
6768 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
6769 pars2.mscpool.rsl_idx := 1;
6770 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
6771 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
6772 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006773 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006774
6775 /* Test round-robin wrap to the first MSC */
6776 var MSC_ConnHdlr vc_conn3;
6777 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
6778 pars3.mscpool.rsl_idx := 2;
6779 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
6780 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
6781 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006782 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006783 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006784}
6785
6786/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
6787 * (configured in osmo-bsc.cfg). */
6788/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
6789 * just as well using only RSL. */
6790testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
6791
6792 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
6793 f_sleep(1.0);
6794
6795 /* Control which MSC gets chosen next by the round-robin, otherwise
6796 * would be randomly affected by which other tests ran before this. */
6797 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
6798
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006799 f_ctrs_msc_init();
6800
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006801 var MSC_ConnHdlr vc_conn1;
6802 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
6803 pars1.mscpool.rsl_idx := 0;
6804 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
6805 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
6806 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006807 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006808
6809 var MSC_ConnHdlr vc_conn2;
6810 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
6811 pars2.mscpool.rsl_idx := 1;
6812 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
6813 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
6814 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006815 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006816
6817 /* Test round-robin wrap to the first MSC */
6818 var MSC_ConnHdlr vc_conn3;
6819 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
6820 pars3.mscpool.rsl_idx := 2;
6821 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
6822 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
6823 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006824 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006825 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006826}
6827
6828/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
6829 * (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
6830 * NULL-NRI setting is stronger than that. */
6831/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
6832 * just as well using only RSL. */
6833testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
6834
6835 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
6836 f_sleep(1.0);
6837
6838 /* Control which MSC gets chosen next by the round-robin, otherwise
6839 * would be randomly affected by which other tests ran before this. */
6840 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
6841
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006842 f_ctrs_msc_init();
6843
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006844 var MSC_ConnHdlr vc_conn1;
6845 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
6846 pars1.mscpool.rsl_idx := 0;
6847 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
6848 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
6849 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006850 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006851
6852 var MSC_ConnHdlr vc_conn2;
6853 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
6854 pars2.mscpool.rsl_idx := 1;
6855 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
6856 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
6857 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006858 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006859
6860 /* Test round-robin wrap to the first MSC */
6861 var MSC_ConnHdlr vc_conn3;
6862 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
6863 pars3.mscpool.rsl_idx := 2;
6864 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
6865 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
6866 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006867 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006868 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006869}
6870
6871/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
6872 * assigned to any MSC (configured in osmo-bsc.cfg). */
6873/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
6874 * just as well using only RSL. */
6875testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
6876
6877 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
6878 f_sleep(1.0);
6879
6880 /* Control which MSC gets chosen next by the round-robin, otherwise
6881 * would be randomly affected by which other tests ran before this. */
6882 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
6883
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006884 f_ctrs_msc_init();
6885
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006886 var MSC_ConnHdlr vc_conn1;
6887 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
6888 pars1.mscpool.rsl_idx := 0;
6889 /* An NRI that is not assigned to any MSC */
6890 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
6891 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
6892 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006893 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006894
6895 var MSC_ConnHdlr vc_conn2;
6896 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
6897 pars2.mscpool.rsl_idx := 1;
6898 /* An NRI that is not assigned to any MSC */
6899 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
6900 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
6901 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006902 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006903
6904 /* Test round-robin wrap to the first MSC */
6905 var MSC_ConnHdlr vc_conn3;
6906 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
6907 pars3.mscpool.rsl_idx := 2;
6908 /* An NRI that is not assigned to any MSC */
6909 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
6910 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
6911 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006912 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006913 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006914}
6915
6916/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
6917 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
6918/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
6919 * just as well using only RSL. */
6920testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
6921
6922 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
6923 f_sleep(1.0);
6924
6925 /* Control which MSC gets chosen next by the round-robin, otherwise
6926 * would be randomly affected by which other tests ran before this. */
6927 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
6928
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006929 f_ctrs_msc_init();
6930
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006931 var MSC_ConnHdlr vc_conn1;
6932 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
6933 pars1.mscpool.rsl_idx := 0;
6934 /* An NRI that is assigned to an unconnected MSC */
6935 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
6936 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
6937 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006938 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
6939 f_ctrs_msc_add(0, "mscpool:subscr:new");
6940 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006941
6942 var MSC_ConnHdlr vc_conn2;
6943 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
6944 pars2.mscpool.rsl_idx := 1;
6945 /* An NRI that is assigned to an unconnected MSC */
6946 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
6947 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
6948 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006949 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
6950 f_ctrs_msc_add(1, "mscpool:subscr:new");
6951 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006952
6953 /* Test round-robin wrap to the first MSC */
6954 var MSC_ConnHdlr vc_conn3;
6955 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
6956 pars3.mscpool.rsl_idx := 2;
6957 /* An NRI that is assigned to an unconnected MSC */
6958 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
6959 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
6960 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006961 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
6962 f_ctrs_msc_add(0, "mscpool:subscr:new");
6963 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006964 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006965}
6966
6967/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
6968 * osmo-bsc.cfg). */
6969/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
6970 * just as well using only RSL. */
6971testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
6972
6973 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
6974 f_sleep(1.0);
6975
6976 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
6977 * this is not using round-robin. */
6978 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
6979
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006980 f_ctrs_msc_init();
6981
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006982 var MSC_ConnHdlr vc_conn1;
6983 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
6984 pars1.mscpool.rsl_idx := 0;
6985 /* An NRI of the second MSC's range (256-511) */
6986 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
6987 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
6988 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006989 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006990
6991 var MSC_ConnHdlr vc_conn2;
6992 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
6993 pars2.mscpool.rsl_idx := 1;
6994 /* An NRI of the second MSC's range (256-511) */
6995 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
6996 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
6997 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02006998 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02006999
7000 var MSC_ConnHdlr vc_conn3;
7001 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7002 pars3.mscpool.rsl_idx := 2;
7003 /* An NRI of the second MSC's range (256-511) */
7004 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7005 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7006 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007007 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007008 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007009}
7010
7011/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7012 * while a round-robin remains unaffected by that. */
7013/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7014 * just as well using only RSL. */
7015testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7016
7017 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7018 f_sleep(1.0);
7019
7020 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7021 * this is not using round-robin. */
7022 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7023
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007024 f_ctrs_msc_init();
7025
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007026 var MSC_ConnHdlr vc_conn1;
7027 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7028 pars1.mscpool.rsl_idx := 0;
7029 /* An NRI of the third MSC's range (512-767) */
7030 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7031 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7032 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007033 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007034
7035 var MSC_ConnHdlr vc_conn2;
7036 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7037 pars2.mscpool.rsl_idx := 1;
7038 /* An NRI of the third MSC's range (512-767) */
7039 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7040 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7041 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007042 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007043
7044 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7045 var MSC_ConnHdlr vc_conn3;
7046 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7047 pars3.mscpool.rsl_idx := 2;
7048 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7049 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7050 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007051 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007052 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007053}
7054
7055/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
7056/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7057 * just as well using only RSL. */
7058testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
7059
7060 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7061 f_sleep(1.0);
7062
7063 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
7064 * instead, and hits msc 0. */
7065 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7066
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007067 f_ctrs_msc_init();
7068
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007069 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
7070 var MSC_ConnHdlr vc_conn1;
7071 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7072 pars1.mscpool.rsl_idx := 0;
7073 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
7074 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7075 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007076 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007077
7078 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
7079 var MSC_ConnHdlr vc_conn2;
7080 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7081 pars2.mscpool.rsl_idx := 1;
7082 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
7083 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7084 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007085 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007086 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007087}
7088
7089/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
7090 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7091private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
7092 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7093 //cid_list := { cIl_allInBSS := ''O };
7094 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7095 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7096 var BSSAP_N_UNITDATA_req paging;
7097 var hexstring imsi := '001010000000123'H;
7098
7099 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7100
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007101 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007102 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
7103 BSSAP.send(paging);
7104
7105 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7106 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7107 * channel number is picked here. */
7108 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7109 f_rslem_register(0, new_chan_nr);
7110 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
7111 f_rslem_unregister(0, new_chan_nr);
7112
7113 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
7114 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
7115 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007116 f_sleep(1.0);
7117}
7118testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
7119 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7120 f_sleep(1.0);
7121
7122 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7123 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7124 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7125
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007126 f_ctrs_msc_init();
7127
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007128 var MSC_ConnHdlr vc_conn1;
7129 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7130 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007131 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7132 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007133 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
7134 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007135 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007136 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007137}
7138
7139/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
7140 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7141private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
7142 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7143 //cid_list := { cIl_allInBSS := ''O };
7144 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7145 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7146 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01007147 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007148 var BSSAP_N_UNITDATA_req paging;
7149
7150 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7151
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007152 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007153 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
7154 BSSAP.send(paging);
7155
7156 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7157 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7158 * channel number is picked here. */
7159 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7160 f_rslem_register(0, new_chan_nr);
7161 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
7162 f_rslem_unregister(0, new_chan_nr);
7163
7164 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
7165 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
7166 * the first MSC (bssap_idx := 0). */
7167 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(nri_v))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007168 f_sleep(1.0);
7169}
7170testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
7171 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7172 f_sleep(1.0);
7173
7174 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7175 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7176 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
7177
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007178 f_ctrs_msc_init();
7179
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007180 var MSC_ConnHdlr vc_conn1;
7181 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7182 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007183 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7184 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007185 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
7186 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007187 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007188 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007189}
7190
7191/* For round-robin, skip an MSC that has 'no allow-attach' set. */
7192/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7193 * just as well using only RSL. */
7194testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
7195
7196 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7197 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007198 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7199 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007200
7201 /* Control which MSC gets chosen next by the round-robin, otherwise
7202 * would be randomly affected by which other tests ran before this. */
7203 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7204
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007205 f_ctrs_msc_init();
7206
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007207 var MSC_ConnHdlr vc_conn1;
7208 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7209 pars1.mscpool.rsl_idx := 0;
7210 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7211 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7212 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007213 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007214
7215 var MSC_ConnHdlr vc_conn2;
7216 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7217 pars2.mscpool.rsl_idx := 1;
7218 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7219 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7220 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007221 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007222
7223 var MSC_ConnHdlr vc_conn3;
7224 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7225 pars3.mscpool.rsl_idx := 2;
7226 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7227 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7228 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007229 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007230 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007231}
7232
7233/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
7234 * TMSI NRI. */
7235testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
7236
7237 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7238 f_sleep(1.0);
7239
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007240 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7241 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
7242
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007243 /* Control which MSC gets chosen next by the round-robin, otherwise
7244 * would be randomly affected by which other tests ran before this. */
7245 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7246
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007247 f_ctrs_msc_init();
7248
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007249 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
7250 var MSC_ConnHdlr vc_conn1;
7251 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7252 pars1.mscpool.rsl_idx := 0;
7253 /* An NRI of the second MSC's range (256-511) */
7254 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
7255 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7256 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007257 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007258
7259 var MSC_ConnHdlr vc_conn2;
7260 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
7261 pars2.mscpool.rsl_idx := 1;
7262 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7263 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7264 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007265 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007266
7267 var MSC_ConnHdlr vc_conn3;
7268 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
7269 pars3.mscpool.rsl_idx := 2;
7270 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
7271 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7272 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007273 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007274 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007275}
7276
Philipp Maier783681c2020-07-16 16:47:06 +02007277/* Allow/Deny emergency calls globally via VTY */
7278private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
7279 f_vty_enter_cfg_msc(BSCVTY, 0);
7280 if (allow) {
7281 f_vty_transceive(BSCVTY, "allow-emergency allow");
7282 } else {
7283 f_vty_transceive(BSCVTY, "allow-emergency deny");
7284 }
7285 f_vty_transceive(BSCVTY, "exit");
7286 f_vty_transceive(BSCVTY, "exit");
7287}
7288
7289/* Allow/Deny emergency calls per BTS via VTY */
7290private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
7291 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
7292 if (allow) {
7293 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
7294 } else {
7295 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
7296 }
7297 f_vty_transceive(BSCVTY, "exit");
7298 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00007299 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02007300}
7301
7302/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
7303private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
7304 var PDU_ML3_MS_NW emerg_setup;
7305 var octetstring emerg_setup_enc;
7306 var RSL_Message emerg_setup_data_ind;
7307
7308 f_establish_fully(omit, omit);
7309
7310 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
7311 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
7312 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
7313
7314 RSL.send(emerg_setup_data_ind);
7315}
7316
7317/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
7318 * CALLS are permitted by the BSC config. */
7319private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
7320 var PDU_BSSAP emerg_setup_data_ind_bssap;
7321 var PDU_ML3_MS_NW emerg_setup;
7322 timer T := 3.0;
7323
7324 f_assignment_emerg_setup()
7325
7326 T.start;
7327 alt {
7328 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
7329 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
7330 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
7331 setverdict(fail, "no emergency setup");
7332 }
7333 }
7334 [] BSSAP.receive {
7335 setverdict(fail, "unexpected BSSAP message!");
7336 }
7337 [] T.timeout {
7338 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
7339 }
7340 }
7341
7342 setverdict(pass);
7343}
7344
7345/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
7346 * forbidden by the BSC config. */
7347private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
7348 var PDU_BSSAP emerg_setup_data_ind_bssap;
7349 timer T := 3.0;
7350
7351 f_assignment_emerg_setup()
7352
7353 T.start;
7354 alt {
7355 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
7356 setverdict(pass);
7357 }
7358 [] RSL.receive {
7359 setverdict(fail, "unexpected RSL message!");
7360 }
7361 [] T.timeout {
7362 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
7363 }
7364 }
7365}
7366
7367/* EMERGENCY CALL situation #1, allowed globally and by BTS */
7368testcase TC_assignment_emerg_setup_allow() runs on test_CT {
7369 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7370 var MSC_ConnHdlr vc_conn;
7371
7372 f_init(1, true);
7373 f_sleep(1.0);
7374
7375 f_vty_allow_emerg_msc(true);
7376 f_vty_allow_emerg_bts(true, 0);
7377 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
7378 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007379 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02007380}
7381
7382/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
7383testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
7384 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7385 var MSC_ConnHdlr vc_conn;
7386
7387 f_init(1, true);
7388 f_sleep(1.0);
7389
7390 f_vty_allow_emerg_msc(false);
7391 f_vty_allow_emerg_bts(true, 0);
7392 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
7393 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007394 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02007395}
7396
7397/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
7398testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
7399 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7400 var MSC_ConnHdlr vc_conn;
7401
7402 /* Note: This simulates a spec violation by the MS, correct MS
7403 * implementations would not try to establish an emergency call because
7404 * the system information tells in advance that emergency calls are
7405 * not forbidden */
7406
7407 f_init(1, true);
7408 f_sleep(1.0);
7409
7410 f_vty_allow_emerg_msc(true);
7411 f_vty_allow_emerg_bts(false, 0);
7412 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
7413 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007414 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02007415}
7416
Philipp Maier82812002020-08-13 18:48:27 +02007417/* Test what happens when an emergency call arrives while all TCH channels are
7418 * busy, the BSC is expected to terminate one call in favor of the incoming
7419 * emergency call */
7420testcase TC_emerg_premption() runs on test_CT {
7421 var ASP_RSL_Unitdata rsl_ud;
7422 var integer i;
7423 var integer chreq_total, chreq_nochan;
7424 var RSL_Message rx_rsl;
7425 var RslChannelNr chan_nr;
7426
7427 f_init(1);
7428 f_sleep(1.0);
7429
7430 f_vty_allow_emerg_msc(true);
7431 f_vty_allow_emerg_bts(true, 0);
7432
7433 /* Fill up all channels on the BTS */
7434 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
7435 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
7436 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
7437 chan_nr := f_chreq_act_ack('33'O, i);
7438 }
7439 IPA_RSL[0].clear;
7440 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
7441 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
7442
7443 /* Send Channel request for emegergency call */
7444 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
7445
7446 /* Expect the BSC to release one (the first) TCH/F on the BTS */
7447 chan_nr := valueof(t_RslChanNr_Bm(1));
7448 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
7449
7450 /* Expect the BSC to send activate/assign the a channel for the emergency call */
7451 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7452 chan_nr := rx_rsl.ies[0].body.chan_nr;
7453 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
7454 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02007455
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007456 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007457}
7458
7459/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07007460private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007461private type record FHParamsTs {
7462 boolean enabled,
7463 uint6_t hsn,
7464 uint6_t maio,
7465 ArfcnList ma
7466};
7467
7468/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007469private type record FHParamsTrx {
7470 GsmArfcn arfcn,
7471 FHParamsTs ts[8]
7472};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007473
7474/* Randomly generate the hopping parameters for the given timeslot numbers */
7475private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
7476runs on test_CT return FHParamsTrx {
7477 var FHParamsTrx fhp;
7478
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07007479 /* Generate a random ARFCN, including ARFCN 0 */
7480 fhp.arfcn := f_rnd_int(3);
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07007481
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007482 for (var integer tn := 0; tn < 8; tn := tn + 1) {
7483 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007484 fhp.ts[tn].enabled := false;
7485 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007486 continue;
7487 }
7488
7489 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007490 fhp.ts[tn].hsn := f_rnd_int(64);
7491 fhp.ts[tn].maio := f_rnd_int(64);
7492 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007493
7494 /* Random Mobile Allocation (hopping channels) */
7495 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
7496 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
7497 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007498 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007499 }
7500
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007501 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007502 }
7503
7504 log("f_TC_fh_params_gen(): ", fhp);
7505 return fhp;
7506}
7507
7508/* Make sure that the given Channel Description IE matches the hopping configuration */
7509private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
7510{
7511 var template (present) ChannelDescription tr_cd;
7512 var template (present) MaioHsn tr_maio_hsn;
7513 var uint3_t tn := cd.chan_nr.tn;
7514
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007515 if (fhp.ts[tn].enabled) {
7516 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007517 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
7518 } else {
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07007519 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007520 }
7521
7522 if (not match(cd, tr_cd)) {
7523 setverdict(fail, "Channel Description IE does not match: ",
7524 cd, " vs expected ", tr_cd);
7525 }
7526}
7527
7528/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
7529private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
7530 in MobileAllocationLV ma)
7531{
7532 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
7533
7534 if (not match(ma, tr_ma)) {
7535 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
7536 tn, "): ", ma, " vs expected: ", tr_ma);
7537 } else {
7538 setverdict(pass);
7539 }
7540}
7541
7542private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
7543 in MobileAllocationLV ma)
7544return template MobileAllocationLV {
7545 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007546 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007547 return { len := 0, ma := ''B };
7548 }
7549
7550 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
7551 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
7552 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007553
7554 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007555 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
7556 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
7557 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007558 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007559 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007560 }
7561 }
7562
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07007563 /* Take ARFCN of the TRX itself into account */
7564 full_mask[fhp.arfcn] := '1'B;
7565
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007566 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007567 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
7568 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007569 }
7570
7571 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07007572 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007573 if (full_mask[i] != '1'B)
7574 { continue; }
7575
7576 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
7577 if (slot_mask[i] == '1'B) {
7578 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007579 } else {
7580 ma_mask := ma_mask & '0'B;
7581 }
7582 }
7583
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07007584 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
7585 if (full_mask[0] == '1'B) {
7586 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
7587 if (slot_mask[0] == '1'B) {
7588 ma_mask := ma_mask & '1'B;
7589 } else {
7590 ma_mask := ma_mask & '0'B;
7591 }
7592 }
7593
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007594 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07007595 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007596 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
7597
7598 return { len := ma_mask_len, ma := ma_mask };
7599}
7600
7601/* Configure the hopping parameters in accordance with the given record */
7602private function f_TC_fh_params_set(in FHParamsTrx fhp,
7603 uint8_t bts_nr := 0,
7604 uint8_t trx_nr := 0)
7605runs on test_CT {
7606 /* Enter the configuration node for the given BTS/TRX numbers */
7607 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
7608
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07007609 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn));
7610
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007611 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007612 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
7613
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007614 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007615 f_vty_transceive(BSCVTY, "hopping enabled 0");
7616 f_vty_transceive(BSCVTY, "exit"); /* go back */
7617 continue;
7618 }
7619
7620 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007621 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
7622 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007623
7624 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007625 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
7626 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007627 }
7628
7629 f_vty_transceive(BSCVTY, "hopping enabled 1");
7630 f_vty_transceive(BSCVTY, "exit"); /* go back */
7631 }
7632
7633 f_vty_transceive(BSCVTY, "end");
7634}
7635
7636/* Disable frequency hopping on all timeslots */
7637private function f_TC_fh_params_unset(in FHParamsTrx fhp,
7638 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07007639 uint8_t trx_nr := 0,
7640 GsmArfcn arfcn := 871)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007641runs on test_CT {
7642 /* Enter the configuration node for the given BTS/TRX numbers */
7643 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
7644
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07007645 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn));
7646
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007647 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007648 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
7649
7650 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07007651 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
7652 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007653 }
7654
7655 f_vty_transceive(BSCVTY, "hopping enabled 0");
7656 f_vty_transceive(BSCVTY, "exit"); /* go back */
7657 }
7658
7659 f_vty_transceive(BSCVTY, "end");
7660 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7661}
7662
7663/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
7664 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
7665testcase TC_fh_params_chan_activ() runs on test_CT {
7666 var FHParamsTrx fhp := f_TC_fh_params_gen();
7667 var RSL_Message rsl_msg;
7668 var RSL_IE_Body ie;
7669
7670 f_init_vty();
7671
7672 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
7673 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7674
7675 f_init(1);
7676
7677 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
7678 for (var integer i := 0; i < 9; i := i + 1) {
7679 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
7680 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7681
7682 /* Make sure that Channel Identification IE is present */
7683 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
7684 setverdict(fail, "RSL Channel Identification IE is absent");
7685 continue;
7686 }
7687
7688 /* Make sure that hopping parameters (HSN/MAIO) match */
7689 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
7690
7691 /* "Mobile Allocation shall be included but empty" - let's check this */
7692 if (ie.chan_ident.ma.v.len != 0) {
7693 setverdict(fail, "Mobile Allocation IE is not empty: ",
7694 ie.chan_ident.ma, ", despite it shall be");
7695 continue;
7696 }
7697 }
7698
7699 /* Disable frequency hopping */
7700 f_TC_fh_params_unset(fhp);
7701
Vadim Yanitskiy21726312020-09-04 01:45:36 +07007702 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007703}
7704
7705/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
7706testcase TC_fh_params_imm_ass() runs on test_CT {
7707 var FHParamsTrx fhp := f_TC_fh_params_gen();
7708 var RSL_Message rsl_msg;
7709 var RSL_IE_Body ie;
7710
7711 f_init_vty();
7712
7713 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
7714 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7715
7716 f_init(1);
7717
7718 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
7719 for (var integer i := 0; i < 9; i := i + 1) {
7720 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
7721 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7722
7723 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
7724 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
7725
7726 /* Make sure that Full Immediate Assign Info IE is present */
7727 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
7728 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
7729 continue;
7730 }
7731
7732 /* Decode the actual Immediate Assignment message */
7733 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
7734 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
7735 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
7736 continue;
7737 }
7738
7739 /* Make sure that hopping parameters (HSN/MAIO) match */
7740 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
7741
7742 /* Make sure that the Mobile Allocation IE matches */
7743 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
7744 rr_msg.payload.imm_ass.mobile_allocation);
7745 }
7746
7747 /* Disable frequency hopping */
7748 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02007749
Vadim Yanitskiy21726312020-09-04 01:45:36 +07007750 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02007751}
7752
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07007753/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
7754testcase TC_fh_params_assignment_cmd() runs on test_CT {
7755 var FHParamsTrx fhp := f_TC_fh_params_gen();
7756 var RSL_Message rsl_msg;
7757 var RSL_IE_Body ie;
7758
7759 f_init_vty();
7760
7761 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
7762 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7763
7764 f_init(1);
7765
7766 /* HACK: work around "Couldn't find Expect for CRCX" */
7767 vc_MGCP.stop;
7768
7769 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
7770 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
7771
7772 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
7773 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
7774 for (var integer i := 0; i < 3; i := i + 1) {
7775 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
7776 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
7777
7778 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
7779 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
7780 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7781
7782 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
7783 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
7784 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
7785
7786 /* Make sure that L3 Information IE is present */
7787 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
7788 setverdict(fail, "RSL L3 Information IE is absent");
7789 continue;
7790 }
7791
7792 /* Decode the L3 message and make sure it is (RR) Assignment Command */
7793 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
7794 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
7795 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
7796 continue;
7797 }
7798
7799 /* Make sure that hopping parameters (HSN/MAIO) match */
7800 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
7801 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
7802
7803 /* Make sure that Cell Channel Description IE is present if FH is enabled */
7804 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07007805 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07007806 continue;
7807 }
7808
7809 /* Make sure that the Mobile Allocation IE matches (if present) */
7810 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
7811 if (chan_desc.h and ma_present) {
7812 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
7813 l3_msg.payload.ass_cmd.mobile_allocation.v);
7814 } else if (chan_desc.h and not ma_present) {
7815 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
7816 continue;
7817 } else if (not chan_desc.h and ma_present) {
7818 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
7819 continue;
7820 }
7821 }
7822
7823 /* Give the IUT some time to release all channels */
7824 f_sleep(3.0);
7825
7826 /* Disable frequency hopping */
7827 f_TC_fh_params_unset(fhp);
7828
Vadim Yanitskiy21726312020-09-04 01:45:36 +07007829 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07007830}
7831
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07007832/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
7833private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
7834runs on test_CT {
7835 var RSL_Message rsl_msg;
7836 var RSL_IE_Body ie;
7837 var DchanTuple dt;
7838
7839 /* Establish a dedicated channel, so we can trigger handover */
7840 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
7841
7842 /* Trigger handover from BTS0 to BTS1 */
7843 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
7844 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
7845
7846 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
7847 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7848
7849 /* ACKnowledge channel activation and expect (RR) Handover Command */
7850 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
7851 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
7852
7853 /* Make sure that L3 Information IE is present */
7854 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
7855 setverdict(fail, "RSL L3 Information IE is absent");
7856 return;
7857 }
7858
7859 /* Decode the L3 message and make sure it is (RR) Handover Command */
7860 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
7861 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
7862 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
7863 return;
7864 }
7865
7866 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
7867 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
7868 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
7869 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
7870 return;
7871 }
7872
7873 /* Make sure that hopping parameters (HSN/MAIO) match */
7874 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
7875
7876 /* Make sure that Cell Channel Description IE is present */
7877 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
7878 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
7879 return;
7880 }
7881
7882 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
7883 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
7884 if (ma_present) {
7885 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
7886 l3_msg.payload.ho_cmd.mobile_allocation.v);
7887 } else {
7888 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
7889 return;
7890 }
7891}
7892testcase TC_fh_params_handover_cmd() runs on test_CT {
7893 var FHParamsTrx fhp := f_TC_fh_params_gen();
7894
7895 f_init_vty();
7896
7897 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
7898 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
7899
7900 f_vty_transceive(BSCVTY, "timeslot 0");
7901 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
7902 f_vty_transceive(BSCVTY, "exit"); /* go back */
7903
7904 f_vty_transceive(BSCVTY, "timeslot 1");
7905 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
7906 f_vty_transceive(BSCVTY, "end"); /* we're done */
7907
7908 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
7909 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
7910
7911 f_init(2);
7912
7913 f_TC_fh_params_handover_cmd(fhp);
7914
7915 /* Disable frequency hopping on BTS1 */
7916 f_TC_fh_params_unset(fhp, 1);
7917
7918 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
7919 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
7920
7921 f_vty_transceive(BSCVTY, "timeslot 0");
7922 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
7923 f_vty_transceive(BSCVTY, "exit"); /* go back */
7924
7925 f_vty_transceive(BSCVTY, "timeslot 1");
7926 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
7927 f_vty_transceive(BSCVTY, "end"); /* we're done */
7928
7929 f_shutdown_helper();
7930}
7931
Vadim Yanitskiyca974032020-09-01 07:20:39 +07007932/* Verify the hopping parameters in System Information Type 4 */
7933testcase TC_fh_params_si4_cbch() runs on test_CT {
7934 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
7935 var ASP_RSL_Unitdata rx_rsl_ud;
7936 timer T := 5.0;
7937
7938 f_init_vty();
7939
7940 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
7941 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
7942
7943 f_vty_transceive(BSCVTY, "timeslot 0");
7944 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
7945 f_vty_transceive(BSCVTY, "exit"); /* go back */
7946
7947 f_vty_transceive(BSCVTY, "timeslot 1");
7948 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
7949 f_vty_transceive(BSCVTY, "end"); /* we're done */
7950
7951 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
7952 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7953
7954 f_init(1);
7955
7956 T.start;
7957 alt {
7958 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
7959 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
7960 var SystemInformation si := dec_SystemInformation(ie.other.payload);
7961
7962 /* Make sure that what we decoded is System Information Type 4 */
7963 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
7964 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
7965 repeat;
7966 }
7967
7968 /* Make sure that CBCH Channel Description IE is present */
7969 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
7970 setverdict(fail, "CBCH Channel Description IE is absent");
7971 break;
7972 }
7973
7974 /* Finally, check the hopping parameters (HSN, MAIO) */
7975 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
7976 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
7977
7978 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
7979 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
7980 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
7981 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
7982 break;
7983 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
7984 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
7985 si.payload.si4.cbch_mobile_alloc.v);
7986 }
7987 }
7988 [] IPA_RSL[0].receive { repeat; }
7989 [] T.timeout {
7990 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
7991 }
7992 }
7993
7994 /* Disable frequency hopping */
7995 f_TC_fh_params_unset(fhp);
7996
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07007997 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07007998 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
7999
8000 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008001 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008002 f_vty_transceive(BSCVTY, "exit"); /* go back */
8003
8004 f_vty_transceive(BSCVTY, "timeslot 1");
8005 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8006 f_vty_transceive(BSCVTY, "end"); /* we're done */
8007
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008008 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008009}
8010
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008011template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
8012 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
8013
8014private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
8015 template (present) BSSLAP_PDU expect_bsslap)
8016{
8017 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
8018 if (not match(bsslap, expect_bsslap)) {
8019 log("EXPECTING BSSLAP: ", expect_bsslap);
8020 log("GOT BSSLAP: ", bsslap);
8021 setverdict(fail, "BSSLAP is not as expected");
8022 mtc.stop;
8023 }
8024 setverdict(pass);
8025}
8026
8027/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
8028const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
8029
8030private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
8031 var PDU_BSSAP_LE rx_bsslap;
8032 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
8033 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
8034}
8035
8036/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8037 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
8038private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
8039 f_sleep(1.0);
8040
8041 f_establish_fully(omit, omit);
8042 f_bssap_le_register_imsi(g_pars.imsi, omit);
8043
8044 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8045 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8046
8047 var PDU_BSSAP_LE plr;
8048 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8049
8050 if (not do_ta_request) {
8051 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
8052 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
8053 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
8054 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
8055 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
8056 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
8057 mtc.stop;
8058 }
8059 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
8060 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
8061 if (not match(bsslap, expect_ta_layer3)) {
8062 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
8063 log("GOT BSSLAP: ", bsslap);
8064 setverdict(fail, "BSSLAP is not as expected");
8065 mtc.stop;
8066 }
8067 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
8068 * has no need to request the TA from the BSC and directly responds. */
8069 } else {
8070 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8071 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8072 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8073 }
8074
8075 /* SMLC got the TA from the BSC, now responds with geo information data. */
8076 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8077 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8078 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8079
8080 /* The LCS was using an active A-interface conn. It should still remain active after this. */
8081 f_mo_l3_transceive();
8082
8083 f_perform_clear(RSL);
8084
8085 f_sleep(2.0);
8086 setverdict(pass);
8087}
8088
8089/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8090 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
8091private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
8092 f_lcs_loc_req_for_active_ms(false);
8093}
8094testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
8095 var MSC_ConnHdlr vc_conn;
8096 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8097
8098 f_init(1, true);
8099 f_sleep(1.0);
8100 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
8101 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008102 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008103}
8104
8105/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8106 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
8107private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
8108 f_lcs_loc_req_for_active_ms(true);
8109}
8110testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
8111 var MSC_ConnHdlr vc_conn;
8112 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8113
8114 f_init(1, true);
8115 f_sleep(1.0);
8116 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
8117 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008118 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008119}
8120
8121/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
8122 * conn without an active lchan. */
8123private function f_clear_A_conn() runs on MSC_ConnHdlr
8124{
8125 var BssmapCause cause := 0;
8126 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
8127 BSSAP.receive(tr_BSSMAP_ClearComplete);
8128 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8129
8130 timer no_more_bssap := 5.0;
8131 no_more_bssap.start;
8132 alt {
8133 [] no_more_bssap.timeout { break; }
8134 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
8135 setverdict(fail, "Expected no more BSSAP after Clear Complete");
8136 mtc.stop;
8137 }
8138 }
8139 setverdict(pass);
8140}
8141
8142/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
8143 * for LCS, for cases where there is only an A conn without an active lchan. */
8144private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
8145{
8146 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
8147
8148 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
8149 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
8150 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
8151 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8152 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8153 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
8154
8155 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
8156 f_clear_A_conn();
8157 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
8158 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8159}
8160
8161/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8162 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
8163 */
8164private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
8165 f_sleep(1.0);
8166
8167 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8168 f_bssap_le_register_imsi(g_pars.imsi, omit);
8169
8170 /* Register to receive the Paging Command */
8171 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8172 g_chan_nr := new_chan_nr;
8173 f_rslem_register(0, g_chan_nr);
8174
8175 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8176 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8177 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8178 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8179
8180 var PDU_BSSAP_LE plr;
8181 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8182
8183 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8184 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8185
8186 /* OsmoBSC needs to Page */
8187 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
8188 f_logp(BSCVTY, "got Paging Command");
8189
8190 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
8191 * the MSC, and releases the lchan directly. */
8192 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(g_pars.imsi))), do_clear := false, expect_bssmap_l3 := false);
8193 f_expect_lchan_rel(RSL);
8194
8195 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
8196
8197 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8198
8199 /* SMLC got the TA from the BSC, now responds with geo information data. */
8200 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8201 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8202
8203 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8204
8205 /* The lchan is gone, the A-interface conn was created for the LCS only.
8206 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
8207 f_verify_active_A_conn_and_clear();
8208
8209 f_sleep(2.0);
8210 setverdict(pass);
8211}
8212testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
8213 var MSC_ConnHdlr vc_conn;
8214 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8215
8216 f_init(1, true);
8217 f_sleep(1.0);
8218
8219 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8220 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8221
8222 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
8223 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008224 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008225}
8226
8227/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
8228 */
8229private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
8230 f_sleep(1.0);
8231
8232 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8233 f_bssap_le_register_imsi(g_pars.imsi, omit);
8234
8235 /* provoke an abort by omitting both IMSI and IMEI */
8236 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8237 valueof(ts_BSSMAP_Perform_Location_Request(omit,
8238 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
8239 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8240
8241 /* BSC tells MSC about failure */
8242 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
8243 locationEstimate := omit, positioningData := omit,
8244 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
8245
8246 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
8247 f_verify_active_A_conn_and_clear();
8248
8249 f_sleep(2.0);
8250 setverdict(pass);
8251}
8252testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
8253 var MSC_ConnHdlr vc_conn;
8254 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8255
8256 f_init(1, true);
8257 f_sleep(1.0);
8258
8259 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8260 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8261
8262 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
8263 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008264 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008265}
8266
8267/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
8268 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
8269private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
8270 f_sleep(1.0);
8271
8272 f_establish_fully(omit, omit);
8273 f_bssap_le_register_imsi(g_pars.imsi, omit);
8274
8275 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8276 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8277
8278 var PDU_BSSAP_LE plr;
8279 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8280
8281 if (do_ta) {
8282 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8283 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8284 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8285 }
8286
8287 /* SMLC fails to respond, BSC runs into timeout */
8288 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
8289 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8290
8291 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
8292 locationEstimate := omit, positioningData := omit,
8293 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
8294
8295 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
8296 f_verify_active_A_conn_and_clear();
8297
8298 f_sleep(2.0);
8299 setverdict(pass);
8300}
8301
8302/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
8303 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
8304private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
8305 f_lcs_loc_req_for_active_ms_le_timeout(false);
8306}
8307
8308testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
8309 var MSC_ConnHdlr vc_conn;
8310 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8311
8312 f_init(1, true);
8313 f_sleep(1.0);
8314 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
8315 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008316 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008317}
8318
8319/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
8320 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
8321private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
8322 f_lcs_loc_req_for_active_ms_le_timeout(true);
8323}
8324
8325testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
8326 var MSC_ConnHdlr vc_conn;
8327 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8328
8329 f_init(1, true);
8330 f_sleep(1.0);
8331 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
8332 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008333 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008334}
8335
8336/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
8337private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
8338 f_sleep(1.0);
8339
8340 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8341 f_bssap_le_register_imsi(g_pars.imsi, omit);
8342
8343 /* Register to receive the Paging Command */
8344 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8345 g_chan_nr := new_chan_nr;
8346 f_rslem_register(0, g_chan_nr);
8347
8348 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8349 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8350 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8351 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8352
8353 var PDU_BSSAP_LE plr;
8354 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8355
8356 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8357 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8358
8359 /* OsmoBSC needs to Page */
8360 var PDU_BSSAP_LE rx_bsslap;
8361 alt {
8362 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
8363 f_logp(BSCVTY, "got Paging Command");
8364 repeat;
8365 }
8366 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
8367 /* MS does not respond to Paging, TA Req runs into timeout. */
8368 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
8369 }
8370 }
8371
8372 /* SMLC responds with failure */
8373 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
8374 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8375
8376 /* BSC tells MSC about failure */
8377 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
8378 locationEstimate := omit, positioningData := omit,
8379 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
8380
8381 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
8382 f_verify_active_A_conn_and_clear();
8383
8384 f_sleep(2.0);
8385 setverdict(pass);
8386}
8387testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
8388 var MSC_ConnHdlr vc_conn;
8389 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8390
8391 f_init(1, true);
8392 f_sleep(1.0);
8393
8394 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8395 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8396
8397 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
8398 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008399 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008400}
8401
8402/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
8403 * over. */
8404private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
8405 f_sleep(1.0);
8406
8407 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8408 f_bssap_le_register_imsi(g_pars.imsi, omit);
8409
8410 /* Register to receive the Paging Command */
8411 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8412 g_chan_nr := new_chan_nr;
8413 f_rslem_register(0, g_chan_nr);
8414
8415 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8416 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8417 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8418 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8419
8420 var PDU_BSSAP_LE plr;
8421 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8422
8423 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
8424 * and establish Layer 3. It should use the existing A-interface conn. */
8425 f_perform_compl_l3(RSL, valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV(g_pars.imsi)))),
8426 do_clear := false, expect_bssmap_l3 := true);
8427
8428 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8429 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8430
8431 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
8432 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8433
8434 /* SMLC got the TA from the BSC, now responds with geo information data. */
8435 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8436 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8437 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8438
8439 /* The lchan should still exist, it was from a CM Service Request. */
8440 f_mo_l3_transceive();
8441
8442 f_perform_clear(RSL);
8443
8444 f_sleep(2.0);
8445 setverdict(pass);
8446}
8447testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
8448 var MSC_ConnHdlr vc_conn;
8449 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8450
8451 f_init(1, true);
8452 f_sleep(1.0);
8453
8454 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8455 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8456
8457 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
8458 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008459 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008460}
8461
8462/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
8463 * the new lchan after handover. */
8464private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
8465 f_sleep(1.0);
8466
8467 f_establish_fully(omit, omit);
8468 f_bssap_le_register_imsi(g_pars.imsi, omit);
8469
8470 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8471 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8472
8473 var PDU_BSSAP_LE plr;
8474 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8475
8476 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
8477 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
8478
8479 var HandoverState hs := {
8480 rr_ho_cmpl_seen := false,
8481 handover_done := false,
8482 old_chan_nr := -
8483 };
8484 /* issue hand-over command on VTY */
8485 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
8486 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
8487 f_rslem_suspend(RSL1_PROC);
8488
8489 /* From the MGW perspective, a handover is is characterized by
8490 * performing one MDCX operation with the MGW. So we expect to see
8491 * one more MDCX during handover. */
8492 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
8493
8494 alt {
8495 [] as_handover(hs);
8496 }
8497
8498 var PDU_BSSAP_LE rx_bsslap;
8499
8500 interleave {
8501 /* Expect the BSC to inform the MSC about the handover */
8502 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
8503
8504 /* Expect the BSC to inform the SMLC about the handover */
8505 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
8506 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
8507 }
8508 }
8509
8510 /* SMLC now responds with geo information data. */
8511 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8512 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8513 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8514
8515 /* lchan still active */
8516 f_mo_l3_transceive(RSL1);
8517
8518 /* MSC decides it is done now. */
8519 f_perform_clear(RSL1);
8520
8521 f_sleep(2.0);
8522 setverdict(pass);
8523}
8524testcase TC_ho_during_lcs_loc_req() runs on test_CT {
8525 var MSC_ConnHdlr vc_conn;
8526 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8527
8528 f_init(2, true);
8529 f_sleep(1.0);
8530 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
8531 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008532 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008533}
8534
Neels Hofmeyrbf037052020-10-28 22:52:02 +00008535/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
8536private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
8537 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8538
8539 /* Also disable attach for the single connected MSC */
8540 f_vty_msc_allow_attach(BSCVTY, { false });
8541
8542 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) ));
8543 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8544
8545 /* No MSC is found, expecting a proper release on RSL */
8546 interleave {
8547 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8548 f_logp(BSCVTY, "Got RSL RR Release");
8549 }
8550 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8551 f_logp(BSCVTY, "Got RSL Deact SACCH");
8552 }
8553 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
8554 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8555 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8556 }
8557 }
8558 setverdict(pass);
8559}
8560testcase TC_no_msc() runs on test_CT {
8561
8562 f_init(1, true);
8563 f_sleep(1.0);
8564 var MSC_ConnHdlr vc_conn;
8565 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8566
8567 f_ctrs_bsc_init(counternames_bsc_mscpool);
8568
8569 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
8570 vc_conn.done;
8571
8572 f_ctrs_bsc_add("mscpool:subscr:no_msc");
8573 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008574 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00008575}
8576
Harald Welte0ea2d5e2018-04-07 21:40:29 +02008577/* Dyn PDCH todo:
8578 * activate OSMO as TCH/F
8579 * activate OSMO as TCH/H
8580 * does the BSC-located PCU socket get the updated INFO?
8581 * what if no PCU is connected at the time?
8582 * is the info correct on delayed PCU (re)connect?
8583 */
Harald Welte94e0c342018-04-07 11:33:23 +02008584
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00008585private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
8586 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
8587 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
8588
8589 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
8590 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
8591 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
8592 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
8593 g_pars.ass_codec_list.codecElements[0];
8594 if (isvalue(g_pars.expect_mr_s0_s7)) {
8595 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
8596 g_pars.expect_mr_s0_s7;
8597 }
8598 }
8599 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
8600 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
8601 log("expecting ASS COMPL like this: ", exp_compl);
8602
8603 f_establish_fully(ass_cmd, exp_compl);
8604
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02008605 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 +00008606
8607 var RSL_Message rsl;
8608
8609 timer T := 5.0;
8610 T.start;
8611 alt {
8612 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
8613 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
8614 log("Rx L3 from net: ", l3);
8615 if (ischosen(l3.msgs.rrm.channelModeModify)) {
8616 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
8617 mtc.stop;
8618 }
8619 }
8620 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
8621 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
8622 mtc.stop;
8623 }
8624 [] T.timeout {
8625 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
8626 setverdict(pass);
8627 }
8628 }
8629 T.stop;
8630}
8631
8632/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
8633 * osmo-bsc. */
8634testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
8635 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8636 var MSC_ConnHdlr vc_conn;
8637
8638 f_init(1, true);
8639 f_sleep(1.0);
8640
8641 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
8642 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
8643 vc_conn.done;
8644 f_shutdown_helper();
8645}
8646
8647/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
8648 */
8649testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
8650 f_init_vty();
8651
8652 f_init(1, false);
8653 f_sleep(1.0);
8654
8655 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
8656
8657 var ASP_RSL_Unitdata rx_rsl_ud;
8658 timer T := 5.0;
8659
8660 T.start;
8661 alt {
8662 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
8663 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
8664 T.stop;
8665 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
8666 mtc.stop;
8667 }
8668 repeat;
8669 }
8670 [] T.timeout {
8671 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
8672 setverdict(pass);
8673 }
8674 }
8675}
8676
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00008677private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
8678 /* First fully set up a speech lchan */
8679 f_TC_assignment_codec(id);
8680
8681 /* Trigger re-assignment to another lchan */
8682 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
8683
8684 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
8685 * one MDCX on MGCP. */
8686 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
8687
8688 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
8689 * as the old lchan used. */
8690 g_media.bts.ipa_crcx_seen := false;
8691 g_media.bts.ipa_mdcx_seen := false;
8692
8693 /* Send different BTS side RTP port number for the new lchan */
8694 g_media.bts.bts.port_nr := 4223;
8695
8696 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
8697
8698 /* Trigger re-assignment. */
8699 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
8700
8701 timer T := 5.0;
8702 T.start;
8703 alt {
8704 [] as_assignment(assignment_st);
8705 [] as_Media();
8706 [] T.timeout {
8707 break;
8708 }
8709 }
8710
8711 if (not assignment_st.assignment_done) {
8712 setverdict(fail, "Assignment did not complete");
8713 mtc.stop;
8714 }
8715
8716 f_check_mgcp_expectations()
8717 setverdict(pass);
8718
8719 f_sleep(2.0);
8720 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
8721
8722 /* Instruct BSC to clear channel */
8723 var BssmapCause cause := 0;
8724 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
8725 interleave {
8726 [] MGCP.receive(tr_DLCX) {}
8727 [] MGCP.receive(tr_DLCX) {}
8728 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
8729 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
8730 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
8731 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8732 }
8733 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8734 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8735 }
8736 }
8737
8738 f_sleep(0.5);
8739}
8740
8741testcase TC_reassignment_fr() runs on test_CT {
8742 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8743 var MSC_ConnHdlr vc_conn;
8744
8745 f_init(1, true);
8746 f_sleep(1.0);
8747
8748 f_ctrs_bsc_and_bts_init();
8749
8750 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
8751 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
8752 vc_conn.done;
8753
8754 /* from f_establish_fully() */
8755 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
8756 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
8757 /* from re-assignment */
8758 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
8759 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
8760 f_ctrs_bsc_and_bts_verify();
8761 f_shutdown_helper();
8762}
8763
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00008764
Harald Welte28d943e2017-11-25 15:00:50 +01008765control {
Harald Welte898113b2018-01-31 18:32:21 +01008766 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +01008767 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01008768 execute( TC_ctrl_msc0_connection_status() );
Harald Welte96c94412017-12-09 03:12:45 +01008769 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +02008770 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02008771 execute( TC_ctrl_location() );
8772 }
Harald Welte898113b2018-01-31 18:32:21 +01008773
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02008774 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02008775 execute( TC_si2quater_2_earfcns() );
8776 execute( TC_si2quater_3_earfcns() );
8777 execute( TC_si2quater_4_earfcns() );
8778 execute( TC_si2quater_5_earfcns() );
8779 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +02008780 execute( TC_si2quater_12_earfcns() );
8781 execute( TC_si2quater_23_earfcns() );
8782 execute( TC_si2quater_32_earfcns() );
8783 execute( TC_si2quater_33_earfcns() );
8784 execute( TC_si2quater_42_earfcns() );
8785 execute( TC_si2quater_48_earfcns() );
8786 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02008787 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +02008788 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02008789
Harald Welte898113b2018-01-31 18:32:21 +01008790 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +01008791 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +01008792 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +01008793 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +02008794 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +02008795 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +01008796 execute( TC_chan_act_ack_est_ind_noreply() );
8797 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +01008798 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +01008799 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07008800 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +01008801 execute( TC_chan_rel_rll_rel_ind() );
8802 execute( TC_chan_rel_conn_fail() );
8803 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02008804 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
8805 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +01008806 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +01008807 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +02008808 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +01008809 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01008810 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02008811 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +01008812
Harald Weltecfe2c962017-12-15 12:09:32 +01008813 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +01008814
8815 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +01008816 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +01008817 execute( TC_assignment_csd() );
8818 execute( TC_assignment_ctm() );
8819 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +02008820 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
8821 execute( TC_assignment_aoip_tla_v6() );
8822 }
Harald Welte235ebf12017-12-15 14:18:16 +01008823 execute( TC_assignment_fr_a5_0() );
8824 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +02008825 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +02008826 execute( TC_assignment_fr_a5_1_codec_missing() );
8827 }
Harald Welte235ebf12017-12-15 14:18:16 +01008828 execute( TC_assignment_fr_a5_3() );
8829 execute( TC_assignment_fr_a5_4() );
Harald Welte3c86ea02018-05-10 22:28:05 +02008830 execute( TC_ciph_mode_a5_0() );
8831 execute( TC_ciph_mode_a5_1() );
8832 execute( TC_ciph_mode_a5_3() );
Harald Welte16a4adf2017-12-14 18:54:01 +01008833
Harald Welte60aa5762018-03-21 19:33:13 +01008834 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02008835 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +01008836 execute( TC_assignment_codec_hr() );
8837 execute( TC_assignment_codec_efr() );
8838 execute( TC_assignment_codec_amr_f() );
8839 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +01008840
Neels Hofmeyrf246a922020-05-13 02:27:10 +02008841 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +01008842 execute( TC_assignment_codec_amr_f_S1() );
8843 execute( TC_assignment_codec_amr_h_S1() );
8844 execute( TC_assignment_codec_amr_f_S124() );
8845 execute( TC_assignment_codec_amr_h_S124() );
8846 execute( TC_assignment_codec_amr_f_S0() );
8847 execute( TC_assignment_codec_amr_f_S02() );
8848 execute( TC_assignment_codec_amr_f_S024() );
8849 execute( TC_assignment_codec_amr_f_S0247() );
8850 execute( TC_assignment_codec_amr_h_S0() );
8851 execute( TC_assignment_codec_amr_h_S02() );
8852 execute( TC_assignment_codec_amr_h_S024() );
8853 execute( TC_assignment_codec_amr_h_S0247() );
8854 execute( TC_assignment_codec_amr_f_S01234567() );
8855 execute( TC_assignment_codec_amr_f_S0234567() );
8856 execute( TC_assignment_codec_amr_f_zero() );
8857 execute( TC_assignment_codec_amr_f_unsupp() );
8858 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +00008859 execute( TC_assignment_codec_amr_f_start_mode_auto() );
8860 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00008861 execute( TC_assignment_codec_amr_f_start_mode_4() );
8862 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +00008863 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +01008864 }
Harald Welte60aa5762018-03-21 19:33:13 +01008865
Philipp Maierac09bfc2019-01-08 13:41:39 +01008866 execute( TC_assignment_codec_fr_exhausted_req_hr() );
8867 execute( TC_assignment_codec_fr_exhausted_req_fr() );
8868 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
8869 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
8870 execute( TC_assignment_codec_hr_exhausted_req_fr() );
8871 execute( TC_assignment_codec_hr_exhausted_req_hr() );
8872 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
8873 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
8874 execute( TC_assignment_codec_req_hr_fr() );
8875 execute( TC_assignment_codec_req_fr_hr() );
8876
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +02008877 if (mp_enable_osmux_test) {
8878 execute( TC_assignment_osmux() );
8879 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02008880
Harald Welte898113b2018-01-31 18:32:21 +01008881 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +01008882 execute( TC_rll_est_ind_inact_lchan() );
8883 execute( TC_rll_est_ind_inval_sapi1() );
8884 execute( TC_rll_est_ind_inval_sapi3() );
8885 execute( TC_rll_est_ind_inval_sacch() );
8886
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07008887 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
8888 execute( TC_tch_dlci_link_id_sapi() );
8889
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07008890 /* SAPI N Reject triggered by RLL establishment failures */
8891 execute( TC_rll_rel_ind_sapi_n_reject() );
8892 execute( TC_rll_err_ind_sapi_n_reject() );
8893 execute( TC_rll_timeout_sapi_n_reject() );
8894
Harald Welte898113b2018-01-31 18:32:21 +01008895 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +01008896 execute( TC_paging_imsi_nochan() );
8897 execute( TC_paging_tmsi_nochan() );
8898 execute( TC_paging_tmsi_any() );
8899 execute( TC_paging_tmsi_sdcch() );
8900 execute( TC_paging_tmsi_tch_f() );
8901 execute( TC_paging_tmsi_tch_hf() );
8902 execute( TC_paging_imsi_nochan_cgi() );
8903 execute( TC_paging_imsi_nochan_lac_ci() );
8904 execute( TC_paging_imsi_nochan_ci() );
8905 execute( TC_paging_imsi_nochan_lai() );
8906 execute( TC_paging_imsi_nochan_lac() );
8907 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +01008908 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
8909 execute( TC_paging_imsi_nochan_rnc() );
8910 execute( TC_paging_imsi_nochan_lac_rnc() );
8911 execute( TC_paging_imsi_nochan_lacs() );
8912 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +01008913 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +01008914 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +01008915 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +01008916 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01008917 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +01008918
8919 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +01008920 execute( TC_rsl_unknown_unit_id() );
8921
8922 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +01008923
8924 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +02008925 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +01008926 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +01008927 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +01008928 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +01008929 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +01008930 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01008931
Harald Welte261af4b2018-02-12 21:20:39 +01008932 execute( TC_ho_int() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +00008933 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01008934
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01008935 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02008936 execute( TC_ho_out_fail_no_msc_response() );
8937 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02008938 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01008939
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01008940 execute( TC_ho_into_this_bsc() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +02008941 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
8942 execute( TC_ho_into_this_bsc_tla_v6() );
8943 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008944 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02008945 execute( TC_srvcc_eutran_to_geran_ho_out() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01008946 execute( TC_ho_in_fail_msc_clears() );
8947 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
8948 execute( TC_ho_in_fail_no_detect() );
8949 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01008950
Neels Hofmeyr91401012019-07-11 00:42:35 +02008951 execute( TC_ho_neighbor_config_1() );
8952 execute( TC_ho_neighbor_config_2() );
8953 execute( TC_ho_neighbor_config_3() );
8954 execute( TC_ho_neighbor_config_4() );
8955 execute( TC_ho_neighbor_config_5() );
8956 execute( TC_ho_neighbor_config_6() );
8957 execute( TC_ho_neighbor_config_7() );
8958
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01008959 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01008960 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01008961 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +02008962
8963 execute( TC_dyn_pdch_ipa_act_deact() );
8964 execute( TC_dyn_pdch_ipa_act_nack() );
8965 execute( TC_dyn_pdch_osmo_act_deact() );
8966 execute( TC_dyn_pdch_osmo_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +02008967
Stefan Sperling0796a822018-10-05 13:01:39 +02008968 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008969 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +02008970
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008971 /* Power control related */
8972 execute( TC_assignment_verify_ms_power_params_ie() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008973
8974 /* MSC pooling */
8975 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
8976 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
8977 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
8978 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
8979 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
8980 execute( TC_mscpool_L3Compl_on_1_msc() );
8981 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
8982 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
8983 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
8984 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
8985 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
8986 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
8987 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
8988 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
8989 execute( TC_mscpool_paging_and_response_imsi() );
8990 execute( TC_mscpool_paging_and_response_tmsi() );
8991 execute( TC_mscpool_no_allow_attach_round_robin() );
8992 execute( TC_mscpool_no_allow_attach_valid_nri() );
8993 }
8994
Harald Welte99f3ca02018-06-14 13:40:29 +02008995 /* at bottom as they might crash OsmoBSC before OS#3182 is fixed */
8996 execute( TC_early_conn_fail() );
8997 execute( TC_late_conn_fail() );
8998
Philipp Maier783681c2020-07-16 16:47:06 +02008999 /* Emergency call handling (deny / allow) */
9000 execute( TC_assignment_emerg_setup_allow() );
9001 execute( TC_assignment_emerg_setup_deny_msc() );
9002 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +02009003 execute( TC_emerg_premption() );
9004
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009005 /* Frequency hopping parameters handling */
9006 execute( TC_fh_params_chan_activ() );
9007 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009008 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009009 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009010 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009011
9012 if (mp_enable_lcs_tests) {
9013 execute( TC_lcs_loc_req_for_active_ms() );
9014 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
9015 execute( TC_lcs_loc_req_for_idle_ms() );
9016 execute( TC_lcs_loc_req_no_subscriber() );
9017 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
9018 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
9019 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
9020 execute( TC_cm_service_during_lcs_loc_req() );
9021 execute( TC_ho_during_lcs_loc_req() );
9022 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009023
9024 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009025
9026 execute( TC_refuse_chan_act_to_vamos() );
9027 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009028
9029 execute( TC_reassignment_fr() );
Harald Welte28d943e2017-11-25 15:00:50 +01009030}
9031
9032}