blob: 2b11dc96a8f6971740052fd08f0404ac4c87838c [file] [log] [blame]
Harald Welte28d943e2017-11-25 15:00:50 +01001module BSC_Tests {
2
Harald Welte21b46bd2017-12-17 19:46:32 +01003/* Integration Tests for OsmoBSC
Harald Weltea0630032018-03-20 21:09:55 +01004 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
Harald Welte21b46bd2017-12-17 19:46:32 +01005 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
Harald Welte34b5a952019-05-27 11:54:11 +020010 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
Harald Welte21b46bd2017-12-17 19:46:32 +010012 * This test suite tests OsmoBSC while emulating both multiple BTS + MS as
13 * well as the MSC. See README for more details.
14 *
15 * There are test cases that run in so-called 'handler mode' and test cases
16 * that run directly on top of the BSSAP and RSL CodecPorts. The "handler mode"
17 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
18 * and/or RSL channels and are hence suitable for higher-level test cases, while
19 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
20 * level testing.
21 */
22
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020023friend module BSC_Tests_VAMOS;
24
Neels Hofmeyr4f118412020-06-04 15:25:10 +020025import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010026import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010027import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010028import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010029import from IPL4asp_Types all;
30
Harald Welte6f521d82017-12-11 19:52:02 +010031import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020032import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020033import from BSSAP_LE_Adapter all;
34import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020035import from BSSAP_LE_Types all;
36import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010037import from BSSAP_CodecPort all;
38import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010039import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010040import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010041import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020042import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010043import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010044import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010045import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010046import from MGCP_Templates all;
47import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020048import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010049
Harald Welte96c94412017-12-09 03:12:45 +010050import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010051import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010052import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010053
Daniel Willmannebdecc02020-08-12 15:30:17 +020054import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
Harald Weltebc03c762018-02-12 18:09:38 +010059import from Osmocom_VTY_Functions all;
60import from TELNETasp_PortType all;
61
Harald Welte6f521d82017-12-11 19:52:02 +010062import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010063import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010064import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010065import from L3_Templates all;
66import from GSM_RR_Types all;
67
Stefan Sperlingc307e682018-06-14 15:15:46 +020068import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010069import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020070import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010071
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010072import from SCCPasp_Types all;
73
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020074import from GSM_SystemInformation all;
75import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020076import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020077
Harald Welte5d1a2202017-12-13 19:51:29 +010078const integer NUM_BTS := 3;
Neels Hofmeyrf246a922020-05-13 02:27:10 +020079const integer NUM_MSC := 3;
Harald Welteae026692017-12-09 01:03:01 +010080const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010081
Harald Welte799c97b2017-12-14 17:50:30 +010082/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020083const integer NUM_TCHH_PER_BTS := 2;
84const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020085const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010086
Harald Welte4003d112017-12-09 22:35:39 +010087
Harald Welte21b46bd2017-12-17 19:46:32 +010088/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +010089type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +010090 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +010091 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +010092}
93
Neels Hofmeyr22c3f792020-06-17 02:49:28 +020094/* Default list of counters for an 'msc' entity. */
95const CounterNameVals counternames_msc_mscpool := {
96 { "mscpool:subscr:new", 0 },
97 { "mscpool:subscr:known", 0 },
98 { "mscpool:subscr:reattach", 0 },
99 { "mscpool:subscr:attach_lost", 0 },
100 { "mscpool:subscr:paged", 0 }
101};
102
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000103/* List of global mscpool counters, not related to a specific 'msc' entity. */
104const CounterNameVals counternames_bsc_mscpool := {
105 { "mscpool:subscr:no_msc", 0 }
106};
107
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000108/* Default list of counters for 'bsc' and 'bts' entities. */
109const CounterNameVals counternames_bsc_bts_handover := {
110 { "assignment:attempted", 0 },
111 { "assignment:completed", 0 },
112 { "assignment:stopped", 0 },
113 { "assignment:no_channel", 0 },
114 { "assignment:timeout", 0 },
115 { "assignment:failed", 0 },
116 { "assignment:error", 0 },
117
118 { "handover:attempted", 0 },
119 { "handover:completed", 0 },
120 { "handover:stopped", 0 },
121 { "handover:no_channel", 0 },
122 { "handover:timeout", 0 },
123 { "handover:failed", 0 },
124 { "handover:error", 0 },
125
126 { "intra_cell_ho:attempted", 0 },
127 { "intra_cell_ho:completed", 0 },
128 { "intra_cell_ho:stopped", 0 },
129 { "intra_cell_ho:no_channel", 0 },
130 { "intra_cell_ho:timeout", 0 },
131 { "intra_cell_ho:failed", 0 },
132 { "intra_cell_ho:error", 0 },
133
134 { "intra_bsc_ho:attempted", 0 },
135 { "intra_bsc_ho:completed", 0 },
136 { "intra_bsc_ho:stopped", 0 },
137 { "intra_bsc_ho:no_channel", 0 },
138 { "intra_bsc_ho:timeout", 0 },
139 { "intra_bsc_ho:failed", 0 },
140 { "intra_bsc_ho:error", 0 },
141
142 { "interbsc_ho_out:attempted", 0 },
143 { "interbsc_ho_out:completed", 0 },
144 { "interbsc_ho_out:stopped", 0 },
145 { "interbsc_ho_out:timeout", 0 },
146 { "interbsc_ho_out:failed", 0 },
147 { "interbsc_ho_out:error", 0 },
148
149 { "interbsc_ho_in:attempted", 0 },
150 { "interbsc_ho_in:completed", 0 },
151 { "interbsc_ho_in:stopped", 0 },
152 { "interbsc_ho_in:no_channel", 0 },
153 { "interbsc_ho_in:timeout", 0 },
154 { "interbsc_ho_in:failed", 0 },
155 { "interbsc_ho_in:error", 0 }
156};
157
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200158/* Set of all System Information received during one RSL port's startup.
159 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
160 * broadcast that SI type. That will be reflected as 'omit' here.
161 */
162type record SystemInformationConfig {
163 SystemInformationType1 si1 optional,
164 SystemInformationType2 si2 optional,
165 SystemInformationType2bis si2bis optional,
166 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200167 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200168 SystemInformationType3 si3 optional,
169 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100170 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200171 SystemInformationType5 si5 optional,
172 SystemInformationType5bis si5bis optional,
173 SystemInformationType5ter si5ter optional,
174 SystemInformationType6 si6 optional
175};
176
177const SystemInformationConfig SystemInformationConfig_omit := {
178 si1 := omit,
179 si2 := omit,
180 si2bis := omit,
181 si2ter := omit,
182 si2quater := omit,
183 si3 := omit,
184 si4 := omit,
185 si13 := omit,
186 si5 := omit,
187 si5bis := omit,
188 si5ter := omit,
189 si6 := omit
190};
191
192/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
193template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
194 template uint3_t meas_bw := 3)
195:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
196 meas_bw_presence := '1'B,
197 meas_bw := meas_bw);
198
199/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200200template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200201 template uint3_t prio := 3,
202 template (present) uint5_t thresh_high := 20,
203 template uint5_t thresh_low := 10,
204 template uint5_t qrxlevmin := 22)
205:= tr_EUTRAN_NeighbourCells(
206 cell_desc_list := cell_desc_list,
207 prio_presence := '1'B,
208 prio := prio,
209 thresh_high := thresh_high,
210 thresh_low_presence := '1'B,
211 thresh_low := thresh_low,
212 qrxlevmin_presence := '1'B,
213 qrxlevmin := qrxlevmin);
214
215template SystemInformationConfig SystemInformationConfig_default := {
216 si1 := {
217 cell_chan_desc := '8FB38000000000000000000000000000'O,
218 rach_control := {
219 max_retrans := RACH_MAX_RETRANS_7,
220 tx_integer := '1001'B,
221 cell_barr_access := false,
222 re_not_allowed := true,
223 acc := '0000010000000000'B
224 },
225 rest_octets := ?
226 },
227 si2 := {
228 bcch_freq_list := '00000000000000000000000000000000'O,
229 ncc_permitted := '11111111'B,
230 rach_control := {
231 max_retrans := RACH_MAX_RETRANS_7,
232 tx_integer := '1001'B,
233 cell_barr_access := false,
234 re_not_allowed := true,
235 acc := '0000010000000000'B
236 }
237 },
238 si2bis := omit,
239 si2ter := {
240 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
241 rest_octets := ?
242 },
243 si2quater := {
244 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
245 },
246 si3 := {
247 cell_id := 0,
248 lai := {
249 mcc_mnc := '001F01'H,
250 lac := 1
251 },
252 ctrl_chan_desc := {
253 msc_r99 := true,
254 att := true,
255 bs_ag_blks_res := 1,
256 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
257 si22ind := false,
258 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
259 spare := '00'B,
260 bs_pa_mfrms := 3,
261 t3212 := 30
262 },
263 cell_options := {
264 dn_ind := false,
265 pwrc := false,
266 dtx := MS_SHALL_USE_UL_DTX,
267 radio_link_tout_div4 := 7
268 },
269 cell_sel_par := {
270 cell_resel_hyst_2dB := 2,
271 ms_txpwr_max_cch := 7,
272 acs := '0'B,
273 neci := true,
274 rxlev_access_min := 0
275 },
276 rach_control := {
277 max_retrans := RACH_MAX_RETRANS_7,
278 tx_integer := '1001'B,
279 cell_barr_access := false,
280 re_not_allowed := true,
281 acc := '0000010000000000'B
282 },
283 rest_octets := {
284 sel_params := {
285 presence := '0'B,
286 params := omit
287 },
288 pwr_offset := {
289 presence := '0'B,
290 offset := omit
291 },
292 si_2ter_ind := '1'B,
293 early_cm_ind := '0'B,
294 sched_where := {
295 presence := '0'B,
296 where := omit
297 },
298 gprs_ind := {
299 presence := '1'B,
300 ind := {
301 ra_colour := 0,
302 si13_pos := '0'B
303 }
304 },
305 umts_early_cm_ind := '1'B,
306 si2_quater_ind := {
307 presence := '1'B,
308 ind := '0'B
309 },
310 iu_mode_ind := omit,
311 si21_ind := {
312 presence := '0'B,
313 pos := omit
314 }
315 }
316 },
317 si4 := {
318 lai := {
319 mcc_mnc := '001F01'H,
320 lac := 1
321 },
322 cell_sel_par := {
323 cell_resel_hyst_2dB := 2,
324 ms_txpwr_max_cch := 7,
325 acs := '0'B,
326 neci := true,
327 rxlev_access_min := 0
328 },
329 rach_control := {
330 max_retrans := RACH_MAX_RETRANS_7,
331 tx_integer := '1001'B,
332 cell_barr_access := false,
333 re_not_allowed := true,
334 acc := '0000010000000000'B
335 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200336 cbch_chan_desc := {
337 iei := '64'O,
338 v := {
339 chan_nr := {
340 u := {
341 sdcch4 := {
342 tag := '001'B,
343 sub_chan := 2
344 }
345 },
346 tn := 0
347 },
348 tsc := 2,
349 h := false,
350 arfcn := 871,
351 maio_hsn := omit
352 }
353 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200354 cbch_mobile_alloc := omit,
355 rest_octets := {
356 sel_params := {
357 presence := '0'B,
358 params := omit
359 },
360 pwr_offset := {
361 presence := '0'B,
362 offset := omit
363 },
364 gprs_ind := {
365 presence := '1'B,
366 ind := {
367 ra_colour := 0,
368 si13_pos := '0'B
369 }
370 },
371 s_presence := '0'B,
372 s := omit
373 }
374 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100375 si13 := {
376 rest_octets := {
377 presence := '1'B,
378 bcch_change_mark := ?,
379 si_change_field := '0000'B,
380 presence2 := '0'B,
381 si13_change_mark := omit,
382 gprs_ma := omit,
383 zero := '0'B, /* PBCCH not present in cell */
384 rac := 0,
385 spgc_ccch_sup := '0'B,
386 priority_access_thr := '110'B,
387 network_control_order := '00'B,
388 gprs_cell_opts := {
389 nmo := '01'B,
390 t3168 := '011'B,
391 t3192 := '010'B,
392 drx_timer_max := '011'B,
393 access_burst_type := '0'B,
394 control_ack_type := '1'B,
395 bs_cv_max := 15,
396 pan_presence := '1'B,
397 pan_dec := 1,
398 pan_inc := 1,
399 pan_max := '111'B,
400 ext_info_presence := ?,
401 ext_info_length := *,
402 ext_info := *
403 },
404 gprs_pwr_ctrl_params := {
405 alpha := 0,
406 t_avg_w := '10000'B,
407 t_avg_t := '10000'B,
408 pc_meas_chan := '0'B,
409 n_avg_i := '1000'B
410 }
411 }
412 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200413 si5 := {
414 bcch_freq_list := '10000000000000000000000000000000'O
415 },
416 si5bis := omit,
417 si5ter := {
418 extd_bcch_freq_list := '9E050020000000000000000000000000'O
419 },
420 si6 := {
421 cell_id := 0,
422 lai := {
423 mcc_mnc := '001F01'H,
424 lac := 1
425 },
426 cell_options := {
427 dtx_ext := '1'B,
428 pwrc := false,
429 dtx := '01'B,
430 radio_link_timeout := '0111'B
431 },
432 ncc_permitted := '11111111'B,
433 rest_octets := ?
434 }
435 };
436
437
438/* List of all the System Information received on all RSL ports */
439type record of SystemInformationConfig SystemInformationConfig_list;
440
441function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
442{
443 var RSL_IE_Body sysinfo_type_ie;
444 var RSL_IE_SysinfoType si_type;
445 var octetstring data;
446
447 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
448 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
449 mtc.stop;
450 }
451 si_type := sysinfo_type_ie.sysinfo_type;
452
453 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
454 var RSL_IE_Body bcch_ie;
455 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
456 data := bcch_ie.other.payload;
457 }
458 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
459 var RSL_IE_Body l3_ie;
460 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
461 data := l3_ie.l3_info.payload;
462 }
463 } else {
464 setverdict(fail, "Don't understand this System Information message");
465 mtc.stop;
466 }
467
468 var boolean handled := false;
469
470 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
471 handled := true;
472
473 if (si_type == RSL_SYSTEM_INFO_1) {
474 if (not isbound(data)) {
475 si.si1 := omit;
476 } else {
477 si.si1 := dec_SystemInformation(data).payload.si1;
478 }
479 } else if (si_type == RSL_SYSTEM_INFO_2) {
480 if (not isbound(data)) {
481 si.si2 := omit;
482 } else {
483 si.si2 := dec_SystemInformation(data).payload.si2;
484 }
485 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
486 if (not isbound(data)) {
487 si.si2bis := omit;
488 } else {
489 si.si2bis := dec_SystemInformation(data).payload.si2bis;
490 }
491 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
492 if (not isbound(data)) {
493 si.si2ter := omit;
494 } else {
495 si.si2ter := dec_SystemInformation(data).payload.si2ter;
496 }
497 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
498 if (not isbound(data)) {
499 si.si2quater := {};
500 } else {
501 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
502 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
503 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
504 }
505 } else if (si_type == RSL_SYSTEM_INFO_3) {
506 if (not isbound(data)) {
507 si.si3 := omit;
508 } else {
509 si.si3 := dec_SystemInformation(data).payload.si3;
510 }
511 } else if (si_type == RSL_SYSTEM_INFO_4) {
512 if (not isbound(data)) {
513 si.si4 := omit;
514 } else {
515 si.si4 := dec_SystemInformation(data).payload.si4;
516 }
517 } else if (si_type == RSL_SYSTEM_INFO_13) {
518 if (not isbound(data)) {
519 si.si13 := omit;
520 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100521 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200522 }
523 } else {
524 handled := false;
525 }
526 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
527 handled := true;
528
529 if (si_type == RSL_SYSTEM_INFO_5) {
530 if (not isbound(data)) {
531 si.si5 := omit;
532 } else {
533 si.si5 := dec_SystemInformation(data).payload.si5;
534 }
535 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
536 if (not isbound(data)) {
537 si.si5bis := omit;
538 } else {
539 si.si5bis := dec_SystemInformation(data).payload.si5bis;
540 }
541 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
542 if (not isbound(data)) {
543 si.si5ter := omit;
544 } else {
545 si.si5ter := dec_SystemInformation(data).payload.si5ter;
546 }
547 } else if (si_type == RSL_SYSTEM_INFO_6) {
548 if (not isbound(data)) {
549 si.si6 := omit;
550 } else {
551 si.si6 := dec_SystemInformation(data).payload.si6;
552 }
553 } else {
554 handled := false;
555 }
556 }
557
558 if (not handled) {
559 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
560 }
561}
562
Harald Weltea4ca4462018-02-09 00:17:14 +0100563type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100564 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100565 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100566 /* RSL common Channel Port (for RSL_Emulation) */
567 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100568 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100569 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100570 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200571 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
572 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100573
Daniel Willmann191e0d92018-01-17 12:44:35 +0100574 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100575 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100576
Daniel Willmannebdecc02020-08-12 15:30:17 +0200577 /* StatsD */
578 var StatsD_Checker_CT vc_STATSD;
579
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200580 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200581 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100582 /* for old legacy-tests only */
583 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200584 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100585
Harald Welte21b46bd2017-12-17 19:46:32 +0100586 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100587 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100588
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200589 /* Osmux is enabled through VTY */
590 var boolean g_osmux_enabled := false;
591
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100592 /*Configure T(tias) over VTY, seconds */
593 var integer g_bsc_sccp_timer_ias := 7 * 60;
594 /*Configure T(tiar) over VTY, seconds */
595 var integer g_bsc_sccp_timer_iar := 15 * 60;
596
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200597 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100598 timer T_guard := 30.0;
599
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200600 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000601 var CounterNameValsList g_ctr_bsc;
602 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200603
604 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
605 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100606}
607
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200608type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100609modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100610 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100611 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100612 /* port number to which to establish the IPA OML connections */
613 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100614 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100615 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100616 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100617 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200618 /* port number to which to listen for STATSD metrics */
619 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100620 /* IP address at which the test binds */
621 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100622
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200623 RAN_Configurations mp_bssap_cfg := {
624 {
625 transport := BSSAP_TRANSPORT_AoIP,
626 sccp_service_type := "mtp3_itu",
627 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
628 own_pc := 185, /* 0.23.1 first MSC emulation */
629 own_ssn := 254,
630 peer_pc := 187, /* 0.23.3 osmo-bsc */
631 peer_ssn := 254,
632 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200633 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200634 },
635 {
636 transport := BSSAP_TRANSPORT_AoIP,
637 sccp_service_type := "mtp3_itu",
638 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
639 own_pc := 2, /* 0.0.2 second MSC emulation */
640 own_ssn := 254,
641 peer_pc := 187, /* 0.23.3 osmo-bsc */
642 peer_ssn := 254,
643 sio := '83'O,
644 rctx := 2
645 },
646 {
647 transport := BSSAP_TRANSPORT_AoIP,
648 sccp_service_type := "mtp3_itu",
649 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
650 own_pc := 3, /* 0.0.3 third MSC emulation */
651 own_ssn := 254,
652 peer_pc := 187, /* 0.23.3 osmo-bsc */
653 peer_ssn := 254,
654 sio := '83'O,
655 rctx := 3
656 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100657 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200658
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200659 /* Must match per BTS config in osmo-bsc.cfg */
660 phys_chan_configs phys_chan_config := {
661 "CCCH+SDCCH4+CBCH",
662 "TCH/F",
663 "TCH/F",
664 "TCH/F",
665 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600666 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200667 "PDCH",
668 "PDCH"
669 };
670
Harald Welte47cd0e32020-08-21 12:39:11 +0200671 BSSAP_LE_Configuration mp_bssap_le_cfg := {
672 sccp_service_type := "mtp3_itu",
673 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200674 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200675 own_ssn := 252, /* SMLC side SSN */
676 peer_pc := 187, /* 0.23.3 osmo-bsc */
677 peer_ssn := 250, /* BSC side SSN */
678 sio := '83'O,
679 rctx := 6
680 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200681 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200682
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200683 /* Whether to enable osmux tests. Can be dropped completely and enable
684 unconditionally once new version of osmo-bsc is released (current
685 version: 1.4.1) */
686 boolean mp_enable_osmux_test := true;
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +0200687
688 /* Whether to enable dyn TS SDCCH8 tests. Can be dropped completely and enable
689 unconditionally once new version of osmo-bsc is released (current
690 version: 1.7.0) */
691 boolean mp_enable_dyn_sdcch8_test := true;
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100692 /* Value set in osmo-bsc.cfg "ms max power" */
693 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100694}
695
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200696friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200697
698 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200699 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200700 pars.aoip := true;
701 } else {
702 pars.aoip := false;
703 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100704 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200705 pars.mscpool.bssap_idx := bssap_idx;
Philipp Maier48604732018-10-09 15:00:37 +0200706
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200707 /* BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2 */
708 pars.expect_tsc := 2;
709
Philipp Maier48604732018-10-09 15:00:37 +0200710 return pars;
711}
712
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200713/* Convenience functions for rate counters using g_ctr_msc. */
714
715private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
716 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
717 log("initial msc rate counters: ", g_ctr_msc);
718}
719
720private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200721 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200722}
723
724/* f_ctrs_msc_init();
725 * f_do_thing(on_msc := 0);
726 * f_do_thing(on_msc := 0);
727 * f_do_other(on_msc := 1);
728 * f_ctrs_msc_add(0, "thing", 2);
729 * f_ctrs_msc_add(1, "other");
730 * f_ctrs_msc_verify();
731 */
732private function f_ctrs_msc_verify() runs on test_CT {
733 log("verifying msc rate counters: ", g_ctr_msc);
734 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
735}
736
737/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
738 * f_ctrs_msc_init();
739 * f_do_thing(on_msc := 0);
740 * f_do_thing(on_msc := 0);
741 * f_do_thing(on_msc := 0);
742 * f_ctrs_msc_expect(0, "thing", 3);
743 */
744private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
745 f_ctrs_msc_add(msc_nr, countername, val);
746 f_ctrs_msc_verify();
747}
748
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000749/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
750
751private function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
752 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
753 log("initial bts rate counters: ", g_ctr_bts);
754 f_ctrs_bsc_init(counternames);
755}
756
757private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
758 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
759 f_ctrs_bsc_add(countername, val);
760}
761
762/* f_ctrs_bsc_and_bts_init();
763 * f_do_thing(on_bts := 0);
764 * f_do_thing(on_bts := 0);
765 * f_do_other(on_bts := 1);
766 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
767 * f_ctrs_bsc_and_bts_add(1, "other");
768 * f_ctrs_bsc_and_bts_verify();
769 */
770private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
771 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
772 f_ctrs_bsc_verify();
773}
774
775/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
776 * f_ctrs_bsc_and_bts_init();
777 * f_do_thing(on_bts := 0);
778 * f_do_thing(on_bts := 0);
779 * f_do_thing(on_bts := 0);
780 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
781 */
782private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
783 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
784 f_ctrs_bsc_and_bts_verify();
785}
786
787
788/* Convenience functions for rate counters using g_ctr_bsc. */
789
790private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
791 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
792 log("initial bsc rate counters: ", g_ctr_bsc);
793}
794
795private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
796 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
797}
798
799/* f_ctrs_bsc_init();
800 * f_do_thing();
801 * f_do_thing();
802 * f_do_other();
803 * f_ctrs_bsc_add("thing", 2);
804 * f_ctrs_bsc_add("other");
805 * f_ctrs_bsc_verify();
806 */
807private function f_ctrs_bsc_verify() runs on test_CT {
808 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
809}
810
811/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
812 * f_ctrs_bsc_init();
813 * f_do_thing();
814 * f_ctrs_bsc_expect("thing", 1);
815 */
816private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
817 f_ctrs_bsc_add(countername, val);
818 f_ctrs_bsc_verify();
819}
820
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200821
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200822friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200823 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100824 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200825 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100826}
827
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200828private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100829 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200830 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100831 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200832 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
833 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100834 T.start;
835 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200836 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
837 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200838 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100839 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200840 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200841 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100842 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200843 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200844 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100845 repeat;
846 }
847 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200848 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200849 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200850 /* If we received a RESET after ours was sent, it
851 may be a race condition where the other peer beacame
852 available after we sent it, but we are in a desired
853 state anyway, so go forward. */
854 if (not reset_received) {
855 setverdict(fail);
856 }
857 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100858 }
Harald Welte28d943e2017-11-25 15:00:50 +0100859}
860
Harald Welteae026692017-12-09 01:03:01 +0100861type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100862 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100863 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100864 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100865 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100866 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100867 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100868 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100869 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100870}
871
Harald Welte21b46bd2017-12-17 19:46:32 +0100872/*! Start the IPA/RSL related bits for one IPA_Client.
873 * \param clnt IPA_Client for which to establish
874 * \param bsc_host IP address / hostname of the BSC
875 * \param bsc_port TCP port number of the BSC
876 * \param i number identifying this BTS
877 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100878function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
879 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100880runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100881 timer T := 10.0;
882
Harald Welte96c94412017-12-09 03:12:45 +0100883 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100884 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
885 clnt.ccm_pars := c_IPA_default_ccm_pars;
886 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
887 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100888 if (handler_mode) {
889 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100890 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100891 }
Harald Welteae026692017-12-09 01:03:01 +0100892
893 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100894 if (handler_mode) {
895 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
896 } else {
897 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
898 }
Harald Welteae026692017-12-09 01:03:01 +0100899
Harald Welte5d1a2202017-12-13 19:51:29 +0100900 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100901 if (handler_mode) {
902 clnt.vc_RSL.start(RSL_Emulation.main());
903 return;
904 }
Harald Welteae026692017-12-09 01:03:01 +0100905
906 /* wait for IPA RSL link to connect and send ID ACK */
907 T.start;
908 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700909 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100910 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700911 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100912 }
Harald Welte60e823a2017-12-10 14:10:59 +0100913 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100914 [] IPA_RSL[i].receive { repeat }
915 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100916 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200917 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100918 }
919 }
920}
921
Harald Welte12055472018-03-17 20:10:08 +0100922function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
923 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
924 return;
925 }
926 clnt.vc_IPA.stop;
927 if (isbound(clnt.vc_RSL)) {
928 clnt.vc_RSL.stop;
929 }
930}
931
Harald Welte21b46bd2017-12-17 19:46:32 +0100932/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100933function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
934 timer T := secs_max;
935 T.start;
936 while (true) {
937 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
938 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100939 /* the 'degraded' state exists from OML connection time, and we have to wait
940 * until all MO's are initialized */
941 T.start(1.0);
942 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100943 return;
944 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100945 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100946 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100947 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200948 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100949 }
950 }
951}
952
Harald Welte21b46bd2017-12-17 19:46:32 +0100953/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100954altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100955 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100956 [] T_guard.timeout {
957 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200958 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100959 }
Harald Welte60e823a2017-12-10 14:10:59 +0100960 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200961 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100962 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200963 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100964 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100965 }
Harald Welte28d943e2017-11-25 15:00:50 +0100966}
967
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100968altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200969 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100970 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +0200971 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100972 }
973}
974
Daniel Willmann191e0d92018-01-17 12:44:35 +0100975function f_init_mgcp(charstring id) runs on test_CT {
976 id := id & "-MGCP";
977
978 var MGCPOps ops := {
979 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
980 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
981 };
982 var MGCP_conn_parameters mgcp_pars := {
983 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +0100984 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +0100985 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200986 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +0200987 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
988 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200989 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +0100990 };
991
992 vc_MGCP := MGCP_Emulation_CT.create(id);
993 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
994}
995
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200996/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
997 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
998 * OsmuxCID IE.
999 */
1000private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1001 f_vty_enter_cfg_msc(BSCVTY, 0);
1002 if (allow) {
1003 f_vty_transceive(BSCVTY, "osmux on");
1004 } else {
1005 f_vty_transceive(BSCVTY, "osmux off");
1006 }
1007 f_vty_transceive(BSCVTY, "exit");
1008 f_vty_transceive(BSCVTY, "exit");
1009 g_osmux_enabled := allow;
1010}
1011
Max2253c0b2018-11-06 19:28:05 +01001012function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001013 if (BSCVTY.checkstate("Mapped")) {
1014 /* skip initialization if already executed once */
1015 return;
1016 }
Harald Weltebc03c762018-02-12 18:09:38 +01001017 map(self:BSCVTY, system:BSCVTY);
1018 f_vty_set_prompts(BSCVTY);
1019 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001020 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1021 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001022}
1023
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001024friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001025{
1026 // log on TTCN3 log output
1027 log(log_msg);
1028 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001029 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001030}
1031
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001032private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1033{
1034 if (rsl_idx >= lengthof(g_system_information)) {
1035 g_system_information[rsl_idx] := SystemInformationConfig_omit
1036 }
1037 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1038}
1039
1040altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1041 var ASP_RSL_Unitdata rx_rsl_ud;
1042
1043 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1044 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1045 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1046 repeat;
1047 }
1048 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1049 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1050 repeat;
1051 }
1052 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1053 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1054 repeat;
1055 }
1056 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1057 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1058 repeat;
1059 }
1060
1061 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1062 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1063 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1064 repeat;
1065 }
1066 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1067 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1068 repeat;
1069 }
1070 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1071 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1072 repeat;
1073 }
1074 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1075 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1076 repeat;
1077 }
1078}
1079
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001080/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1081private type record of boolean my_BooleanList;
1082
1083private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1084{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001085 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1086
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001087 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001088 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1089 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1090 * stepping into that config node. */
1091 log("msc ", msc_nr, " is not configured, skipping");
1092 continue;
1093 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001094 f_vty_enter_cfg_msc(pt, msc_nr);
1095 if (allow_attach_list[msc_nr]) {
1096 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1097 f_vty_transceive(pt, "allow-attach", strict := false);
1098 } else {
1099 f_vty_transceive(pt, "no allow-attach", strict := false);
1100 }
1101 f_vty_transceive(pt, "exit");
1102 f_vty_transceive(pt, "exit");
1103 }
1104}
1105
Harald Welte21b46bd2017-12-17 19:46:32 +01001106/* global initialization function
1107 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001108 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1109 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1110 */
1111function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001112 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001113 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001114
Harald Welteae026692017-12-09 01:03:01 +01001115 if (g_initialized) {
1116 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001117 }
Harald Welteae026692017-12-09 01:03:01 +01001118 g_initialized := true;
1119
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001120 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001121 activate(as_Tguard());
1122
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001123 f_init_vty("VirtMSC");
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +02001124 if (mp_enable_osmux_test) {
1125 f_vty_allow_osmux(allow_osmux);
1126 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001127
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001128 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001129 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1130
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001131 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001132 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001133 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1134 * MSC-side BSSAP emulation */
1135 if (handler_mode) {
1136 var RanOps ranops := MSC_RanOps;
1137 ranops.use_osmux := g_osmux_enabled;
1138 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1139 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1140 f_ran_adapter_start(g_bssap[bssap_idx]);
1141 } else {
1142 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1143 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1144 f_ran_adapter_start(g_bssap[bssap_idx]);
1145 f_legacy_bssap_reset();
1146 }
Harald Welte67089ee2018-01-17 22:19:03 +01001147 }
Harald Welted5833a82018-05-27 16:52:56 +02001148
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001149 if (mp_enable_lcs_tests) {
1150 if (handler_mode) {
1151 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1152 } else {
1153 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1154 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1155 }
1156 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001157 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001158
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001159 /* start the test with exactly all enabled MSCs allowed to attach */
1160 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1161
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001162 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001163
Daniel Willmann191e0d92018-01-17 12:44:35 +01001164 f_init_mgcp("VirtMSC");
1165
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001166 for (var integer i := 0; i < nr_bts; i := i+1) {
1167 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001168 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001169}
Harald Welte696ddb62017-12-08 14:01:43 +01001170
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001171function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1172runs on test_CT {
1173 /* wait until osmo-bts-omldummy has respawned */
1174 f_wait_oml(bts_idx, "degraded", 5.0);
1175
1176 /* start RSL connection */
1177 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1178 /* wait until BSC tells us "connected" */
1179 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001180}
1181
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001182function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1183 template SystemInformationConfig expect_si)
1184runs on test_CT {
1185 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1186
1187 f_init_bts(bts_idx, handler_mode);
1188
1189 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1190 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1191 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1192 */
1193 f_sleep(5.0);
1194 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1195
1196 deactivate(sysinfo);
1197
1198 if (match(g_system_information[bts_idx], expect_si)) {
1199 setverdict(pass);
1200 } else {
1201 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1202 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1203 setverdict(fail, "received SI does not match expectations");
1204 return;
1205 }
1206}
1207
Maxd4e56962018-10-31 19:08:25 +01001208/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001209function 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 +01001210runs on test_CT return RSL_Message {
1211 var ASP_RSL_Unitdata rx_rsl_ud;
1212 timer T := t_secs;
1213
1214 T.start;
1215 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001216 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001217 T.stop;
1218 }
1219 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001220 [] T.timeout {
1221 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001222 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001223 }
Harald Welteae026692017-12-09 01:03:01 +01001224 }
1225 return rx_rsl_ud.rsl;
1226}
1227
Harald Welte21b46bd2017-12-17 19:46:32 +01001228/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001229function 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 +01001230runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001231 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001232}
1233
1234
Harald Welte4003d112017-12-09 22:35:39 +01001235/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001236testcase TC_chan_act_noreply() runs on test_CT {
1237 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001238 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001239
Harald Welte89d42e82017-12-17 16:42:41 +01001240 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001241
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001242 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001243 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001244 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001245}
1246
Harald Welte4003d112017-12-09 22:35:39 +01001247/* verify if the "chreq:total" counter increments as expected */
1248testcase TC_chan_act_counter() runs on test_CT {
1249 var BSSAP_N_UNITDATA_ind ud_ind;
1250 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001251 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001252
Harald Welte89d42e82017-12-17 16:42:41 +01001253 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001254
1255 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001256 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001257 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001258 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1259
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001260 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001261}
1262
Harald Welteae026692017-12-09 01:03:01 +01001263/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001264private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001265 var RSL_Message rx_rsl;
1266
Harald Welteae026692017-12-09 01:03:01 +01001267 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001268 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001269
1270 /* expect BSC to disable the channel again if there's no RLL EST IND */
1271 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1272
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001273 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001274}
1275
Philipp Maier9c60a622020-07-09 15:08:46 +02001276/* Normal variant */
1277testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001278 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001279 f_TC_chan_act_ack_noest();
1280}
1281
1282/* Emergency call variant */
1283testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1284 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001285 f_init(1);
1286 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001287 f_TC_chan_act_ack_noest(ra := 'A5'O);
1288}
1289
Philipp Maier606f07d2020-08-12 17:21:58 +02001290/* Emergency call variant, but emergency calls are not allowed */
1291testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1292 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1293
1294 var RSL_Message rx_rsl;
1295 var GsmRrMessage rr;
1296
1297 f_init(1);
1298 f_vty_allow_emerg_bts(false, 0);
1299
1300 IPA_RSL[0].clear;
1301 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1302
1303 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1304 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1305 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1306 setverdict(pass);
1307 } else {
1308 setverdict(fail, "immediate assignment not rejected");
1309 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001310
1311 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001312}
1313
Harald Welteae026692017-12-09 01:03:01 +01001314/* Test behavior if MSC never answers to CR */
1315testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001316 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1317 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001318 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001319 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001320
Harald Welte89d42e82017-12-17 16:42:41 +01001321 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001322
1323 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001324 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001325
1326 var octetstring l3 := '00010203040506'O
1327 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1328
1329 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1330
1331 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001332 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001333 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001334 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001335}
1336
1337/* Test behavior if MSC answers with CREF to CR */
1338testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1339 var BSSAP_N_CONNECT_ind rx_c_ind;
1340 var RSL_Message rx_rsl;
1341
Harald Welte89d42e82017-12-17 16:42:41 +01001342 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001343
1344 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001345 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001346
1347 var octetstring l3 := '00010203040506'O
1348 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1349
1350 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1351 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1352
1353 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001354 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001355 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001356}
1357
Harald Welte618ef642017-12-14 14:58:20 +01001358/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1359testcase TC_chan_act_nack() runs on test_CT {
1360 var RSL_Message rx_rsl;
1361 var integer chact_nack;
1362
Harald Welte89d42e82017-12-17 16:42:41 +01001363 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001364
1365 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1366
1367 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1368 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1369 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1370
1371 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1372
1373 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1374 f_sleep(0.5);
1375
1376 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1377
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001378 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001379}
1380
Harald Welte799c97b2017-12-14 17:50:30 +01001381/* Test for channel exhaustion due to RACH overload */
1382testcase TC_chan_exhaustion() runs on test_CT {
1383 var ASP_RSL_Unitdata rsl_ud;
1384 var integer i;
1385 var integer chreq_total, chreq_nochan;
1386
Harald Welte89d42e82017-12-17 16:42:41 +01001387 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001388
1389 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1390 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1391
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001392 /* GSM 04.08 Table 9.9a:
1393 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1394 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001395 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 +01001396 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001397 }
1398
1399 IPA_RSL[0].clear;
1400
Harald Weltedd8cbf32018-01-28 12:07:52 +01001401 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001402 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001403
1404 /* now expect additional channel activations to fail */
1405 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1406
1407 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001408 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001409 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1410 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001411 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001412 var GsmRrMessage rr;
1413 /* match on IMM ASS REJ */
1414 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1415 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1416 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001417 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001418 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1419 chreq_nochan+1);
1420 setverdict(pass);
1421 } else {
1422 repeat;
1423 }
1424 }
1425 [] IPA_RSL[0].receive { repeat; }
1426 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001427 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001428}
1429
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001430/* Test channel deactivation due to silence from MS */
1431testcase TC_chan_deact_silence() runs on test_CT {
1432 var RslChannelNr chan_nr;
1433
1434 f_init(1);
1435
1436 /* Request for a dedicated channel */
1437 chan_nr := f_chreq_act_ack('23'O);
1438
1439 /* Wait some time until the channel is released */
1440 f_sleep(2.0);
1441
1442 /* Expect CHANnel RELease */
1443 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001444 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001445 log("Received CHANnel RELease");
1446 setverdict(pass);
1447 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001448 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001449 /* See OS#3709, OsmoBSC should not send Immediate
1450 * Assignment Reject since a dedicated channel was
1451 * already allocated, and Immediate Assignment was
1452 * already sent. */
1453 setverdict(fail, "Unexpected Immediate Assignment!");
1454 }
1455 [] IPA_RSL[0].receive {
1456 setverdict(fail, "Unexpected RSL message!");
1457 }
1458 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001459 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001460}
1461
Harald Weltecfe2c962017-12-15 12:09:32 +01001462/***********************************************************************
1463 * Assignment Testing
1464 ***********************************************************************/
1465
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001466/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1467 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001468testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001469 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001470
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001471 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1472 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001473 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001474 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001475}
1476
Harald Welte16a4adf2017-12-14 18:54:01 +01001477/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001478testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001479 var BSSAP_N_CONNECT_ind rx_c_ind;
1480 var RSL_Message rx_rsl;
1481 var DchanTuple dt;
1482
Harald Welte89d42e82017-12-17 16:42:41 +01001483 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001484
1485 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001486 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001487 /* send assignment without AoIP IEs */
1488 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1489 } else {
1490 /* Send assignmetn without CIC in IPA case */
1491 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1492 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1493 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1494 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001495 alt {
1496 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1497 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1498 }
Harald Welte235ebf12017-12-15 14:18:16 +01001499 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001500 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1501 setverdict(pass);
1502 }
1503 [] BSSAP.receive { repeat; }
1504 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001505 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001506}
1507
Harald Welteed848512018-05-24 22:27:58 +02001508/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001509function 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 +02001510 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001511 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001512 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001513 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001514 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001515 if (osmux_enabled) {
1516 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1517 } else {
1518 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1519 }
Harald Welteed848512018-05-24 22:27:58 +02001520 } else {
1521 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001522 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001523 }
1524 return ass_cmd;
1525}
1526
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001527function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001528 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1529 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001530 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001531
1532 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1533 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1534 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1535 var template BSSMAP_IE_KC128 kc128 := omit;
1536 if (ispresent(enc)) {
1537 var TestHdlrEncrParams v_enc := valueof(enc);
1538 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1539 chosenEncryptionAlgorithm := valueof(
1540 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001541 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001542 if (ispresent(v_enc.enc_kc128)) {
1543 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1544 }
1545 }
1546
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001547 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001548 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001549 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001550 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1551 encryptionInformation := encryptionInformation,
1552 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1553 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001554 } else {
1555 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001556 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1557 encryptionInformation := encryptionInformation,
1558 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1559 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001560 }
1561 return ho_req;
1562}
1563
Harald Welteed848512018-05-24 22:27:58 +02001564/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001565function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001566 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001567 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001568 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001569 if (expect_osmux) {
1570 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1571 } else {
1572 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1573 }
Harald Welteed848512018-05-24 22:27:58 +02001574 } else {
1575 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001576 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001577 }
1578 return exp_compl;
1579}
1580
Harald Welte235ebf12017-12-15 14:18:16 +01001581/* Run everything required up to sending a caller-specified assignment command and expect response */
1582function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1583runs on test_CT {
1584 var BSSAP_N_CONNECT_ind rx_c_ind;
1585 var RSL_Message rx_rsl;
1586 var DchanTuple dt;
1587
Harald Welte89d42e82017-12-17 16:42:41 +01001588 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001589
1590 dt := f_est_dchan('23'O, 23, '00000000'O);
1591 /* send assignment without AoIP IEs */
1592 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1593 alt {
1594 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1595 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1596 setverdict(pass);
1597 } else {
1598 setverdict(fail, fail_text);
1599 }
1600 }
1601 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1602 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1603 setverdict(pass);
1604 } else {
1605 setverdict(fail, fail_text);
1606 }
1607 }
1608 [] BSSAP.receive { repeat; }
1609 }
1610}
1611testcase TC_assignment_csd() runs on test_CT {
1612 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001613 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001614 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1615 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1616 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001617 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001618}
1619
1620testcase TC_assignment_ctm() runs on test_CT {
1621 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001622 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001623 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1624 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1625 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001626 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001627}
1628
Harald Welte4003d112017-12-09 22:35:39 +01001629type record DchanTuple {
1630 integer sccp_conn_id,
1631 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001632}
1633
Harald Welted6939652017-12-13 21:02:46 +01001634/* Send CHAN RQD and wait for allocation; acknowledge it */
1635private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1636runs on test_CT return RslChannelNr {
1637 var RSL_Message rx_rsl;
1638 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1639 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1640 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1641 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001642 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001643 return chan_nr;
1644}
1645
Harald Welte4003d112017-12-09 22:35:39 +01001646/* helper function to establish a dedicated channel via BTS and MSC */
1647function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1648runs on test_CT return DchanTuple {
1649 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001650 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001651
Harald Welte4003d112017-12-09 22:35:39 +01001652 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001653 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001654
1655 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1656
1657 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1658 dt.sccp_conn_id := rx_c_ind.connectionId;
1659 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1660
1661 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001662}
1663
Harald Welte641fcbe2018-06-14 10:58:35 +02001664/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1665private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1666 var RSL_Message rx_rsl;
1667 /* expect BSC to disable the channel */
1668 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1669 /* respond with CHAN REL ACK */
1670 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1671
1672 /* expect Clear Complete from BSC */
1673 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1674
1675 /* MSC disconnects as instructed. */
1676 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1677}
1678
Harald Welte4003d112017-12-09 22:35:39 +01001679/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1680testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001681 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001682 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001683
Harald Welte89d42e82017-12-17 16:42:41 +01001684 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001685
Harald Welte4003d112017-12-09 22:35:39 +01001686 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1687
1688 /* simulate RLL REL IND */
1689 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1690
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001691 /* expect Clear Request on MSC side */
1692 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1693
1694 /* Instruct BSC to clear channel */
1695 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1696 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1697
Harald Welte4003d112017-12-09 22:35:39 +01001698 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001699 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001700
1701 /* wait for SCCP emulation to do its job */
1702 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001703
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001704 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001705}
1706
1707/* Test behavior of channel release after CONN FAIL IND from BTS */
1708testcase TC_chan_rel_conn_fail() runs on test_CT {
1709 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001710 var DchanTuple dt;
1711
Harald Welte89d42e82017-12-17 16:42:41 +01001712 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001713
1714 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1715
1716 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001717 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 +01001718 /* TODO: different cause values? */
1719
Harald Welte4003d112017-12-09 22:35:39 +01001720 /* expect Clear Request from BSC */
1721 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1722
1723 /* Instruct BSC to clear channel */
1724 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1725 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1726
Harald Welte6ff76ea2018-01-28 13:08:01 +01001727 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001728 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001729
1730 /* wait for SCCP emulation to do its job */
1731 f_sleep(1.0);
1732
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001733 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001734}
1735
Harald Welte99f3ca02018-06-14 13:40:29 +02001736/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1737/* See also https://www.osmocom.org/issues/3182 */
1738testcase TC_early_conn_fail() runs on test_CT {
1739 var RSL_Message rx_rsl;
1740 var DchanTuple dt;
1741
1742 f_init(1);
1743
1744 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001745 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001746
1747 /* BTS->BSC: simulate CONN FAIL IND */
1748 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1749
1750 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1751 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1752
1753 /* BTS<-BSC: respond with CHAN REL ACK */
1754 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1755
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001756 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001757}
1758
1759/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1760/* See also https://www.osmocom.org/issues/3182 */
1761testcase TC_late_conn_fail() runs on test_CT {
1762 var RSL_Message rx_rsl;
1763 var DchanTuple dt;
1764
1765 f_init(1);
1766
1767 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1768
1769 /* BSC<-MSC: Instruct BSC to clear connection */
1770 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1771
1772 /* BTS->BSC: expect BSC to deactivate SACCH */
1773 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1774
1775 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1776 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1777
1778 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1779 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1780 /* BTS->BSC: respond with CHAN REL ACK */
1781 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1782
1783 /* BSC->MSC: expect Clear Complete from BSC */
1784 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1785
1786 /* BSC<-MSC: MSC disconnects as requested. */
1787 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1788
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001789 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001790}
1791
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001792function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001793 boolean expect_deact_sacch := true,
1794 boolean expect_rr_chan_rel := true,
1795 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001796 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001797 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001798 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001799 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001800
1801 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001802 var boolean got_deact_sacch := false;
1803 var boolean got_rr_chan_rel := false;
1804 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001805 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001806 var RSL_IE_Body l3_ie;
1807 var PDU_ML3_NW_MS l3;
1808 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001809 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1810 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001811 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001812 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001813 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001814 repeat;
1815 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001816 [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 +01001817 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001818
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001819 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1820 setverdict(fail, "cannot find L3");
1821 mtc.stop;
1822 }
1823 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1824
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001825 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001826 var CellSelIndValue cells := dec_CellSelIndValue(
1827 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1828
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001829 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1830 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001831 setverdict(pass);
1832 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001833 log("EXPECTED CELLS: ", expect_cells);
1834 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001835 }
1836 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001837
1838 if (not istemplatekind(expect_rr_cause, "omit")) {
1839 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1840 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1841 if (match(got_cause, expect_rr_cause)) {
1842 setverdict(pass);
1843 } else {
1844 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1845 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1846 }
1847 }
Harald Welte99787102019-02-04 10:41:36 +01001848 repeat;
1849 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001850 [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 +01001851 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001852
1853 if (not istemplatekind(expect_rr_cause, "omit")) {
1854 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1855 setverdict(fail, "cannot find L3");
1856 mtc.stop;
1857 }
1858 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1859
1860 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1861 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1862 if (match(got_cause, expect_rr_cause)) {
1863 setverdict(pass);
1864 } else {
1865 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1866 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1867 }
1868 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001869 repeat;
1870 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001871 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001872 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001873 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001874 if (handle_rll_rel) {
1875 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1876 }
Harald Welte91d54a52018-01-28 15:35:07 +01001877 repeat;
1878 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001879 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001880 /* respond with CHAN REL ACK */
1881 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1882 }
1883 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001884 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001885 repeat;
1886 }
1887 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001888
1889 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
1890 " got_rll_rel_req=", got_rll_rel_req);
1891
1892 if (expect_deact_sacch != got_deact_sacch) {
1893 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
1894 }
1895 if (expect_rr_chan_rel != got_rr_chan_rel) {
1896 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
1897 }
1898 if (expect_rll_rel_req != got_rll_rel_req) {
1899 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
1900 }
Harald Welte91d54a52018-01-28 15:35:07 +01001901}
1902
Harald Welte4003d112017-12-09 22:35:39 +01001903/* Test behavior of channel release after hard Clear Command from MSC */
1904testcase TC_chan_rel_hard_clear() runs on test_CT {
1905 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001906 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01001907
Harald Welte89d42e82017-12-17 16:42:41 +01001908 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001909
1910 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1911
1912 /* Instruct BSC to clear channel */
1913 var BssmapCause cause := 0;
1914 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1915
1916 /* expect Clear Complete from BSC on A */
1917 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1918 /* release the SCCP connection */
1919 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1920 }
1921
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001922 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001923 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001924}
1925
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001926function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
1927 var BSSAP_N_DATA_ind rx_di;
1928 var DchanTuple dt;
1929
1930 f_init(1);
1931
1932 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1933 /* Send CommonID with some random PLMN (BSC doesn't take it into account
1934 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
1935 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
1936
1937 /* Instruct BSC to clear channel */
1938 var BssmapCause cause := 0;
1939 if (tx_csfb_ind) {
1940 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
1941 } else {
1942 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1943 }
1944
1945 /* expect Clear Complete from BSC on A */
1946 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1947 /* release the SCCP connection */
1948 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1949 }
1950
1951 /* 1 neighbor is added by default in osmo-bts.cfg and
1952 SystemInformationConfig_default, use that: */
1953 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
1954
1955 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
1956 f_shutdown_helper();
1957}
1958
1959/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
1960 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
1961 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
1962 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
1963 Indicator or not shouldn't matter at all. */
1964testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
1965 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
1966}
1967
1968/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
1969 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
1970 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
1971 EUTRAN neighbor list sent later on by BSC in RR Channel. */
1972testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
1973 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
1974}
1975
1976/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
1977 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
1978 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
1979 CSFB Indicator should not be used anymore, and hence, there should be no
1980 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
1981 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01001982testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
1983 var BSSAP_N_DATA_ind rx_di;
1984 var DchanTuple dt;
1985
1986 f_init(1);
1987
1988 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1989
1990 /* Instruct BSC to clear channel */
1991 var BssmapCause cause := 0;
1992 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
1993
1994 /* expect Clear Complete from BSC on A */
1995 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1996 /* release the SCCP connection */
1997 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1998 }
1999
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002000 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002001 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002002}
2003
Harald Welted8c36cd2017-12-09 23:05:31 +01002004/* Test behavior of channel release after hard RLSD from MSC */
2005testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002006 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002007
Harald Welte89d42e82017-12-17 16:42:41 +01002008 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002009
2010 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2011
2012 /* release the SCCP connection */
2013 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2014
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002015 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002016 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002017}
2018
Harald Welte550daf92018-06-11 19:22:13 +02002019/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2020testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2021 var DchanTuple dt;
2022
2023 f_init(1);
2024
2025 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2026
2027 /* release the SCCP connection */
2028 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2029
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002030 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002031 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002032}
2033
Harald Welte85804d42017-12-10 14:11:58 +01002034/* Test behavior of channel release after BSSMAP RESET from MSC */
2035testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002036 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002037
Harald Welte89d42e82017-12-17 16:42:41 +01002038 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002039
2040 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2041
2042 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2043 IPA_RSL[0].clear;
2044
2045 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002046 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 +01002047 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002048 [] 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 +01002049 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2050 }
2051
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002052 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002053 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002054}
2055
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002056/* Verify T(iar) triggers and releases the channel */
2057testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2058 var DchanTuple dt;
2059
2060 /* Set T(iar) in BSC low enough that it will trigger before other side
2061 has time to keep alive with a T(ias). Keep recommended ratio of
2062 T(iar) >= T(ias)*2 */
2063 g_bsc_sccp_timer_ias := 2;
2064 g_bsc_sccp_timer_iar := 5;
2065
2066 f_init(1);
2067
2068 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2069 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002070 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002071}
2072
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002073private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2074runs on test_CT
2075{
2076 var DchanTuple dt;
2077
2078 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2079 var BssmapCause cause := 0;
2080 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2081 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2082 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2083 }
2084
2085 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 +02002086}
2087
2088/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2089testcase TC_chan_rel_rr_cause() runs on test_CT {
2090 f_init(1);
2091
2092 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2093 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2094 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2095 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2096 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2097 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002098
2099 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002100}
2101
Harald Welte5cd20ed2017-12-13 21:03:20 +01002102/* Test behavior if RSL EST IND for non-active channel */
2103testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2104 timer T := 2.0;
2105
Harald Welte89d42e82017-12-17 16:42:41 +01002106 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002107
2108 var octetstring l3 := '00010203040506'O;
2109 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2110 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2111
2112 T.start;
2113 alt {
2114 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2115 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2116 }
2117 [] BSSAP.receive {}
2118 [] IPA_RSL[0].receive {}
2119 [] T.timeout {}
2120 }
2121
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002122 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002123}
2124
2125/* Test behavior if RSL EST IND for invalid SAPI */
2126testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2127 var RslChannelNr chan_nr;
2128
Harald Welte89d42e82017-12-17 16:42:41 +01002129 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002130
2131 chan_nr := f_chreq_act_ack()
2132
2133 var octetstring l3 := '00010203040506'O;
2134 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2135
2136 timer T := 2.0;
2137 T.start;
2138 alt {
2139 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2140 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2141 }
2142 [] BSSAP.receive { repeat; }
2143 [] IPA_RSL[0].receive { repeat; }
2144 [] T.timeout {}
2145 }
2146
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002147 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002148}
2149
2150/* Test behavior if RSL EST IND for invalid SAPI */
2151testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2152 timer T := 2.0;
2153
Harald Welte89d42e82017-12-17 16:42:41 +01002154 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002155
2156 var RslChannelNr chan_nr := f_chreq_act_ack();
2157
2158 var octetstring l3 := '00010203040506'O;
2159 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2160
2161 T.start;
2162 alt {
2163 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2164 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2165 }
2166 [] BSSAP.receive { repeat; }
2167 [] IPA_RSL[0].receive { repeat; }
2168 [] T.timeout {}
2169 }
2170
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002171 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002172}
2173
2174/* Test behavior if RSL EST IND for invalid SACCH */
2175testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2176 timer T := 2.0;
2177
Harald Welte89d42e82017-12-17 16:42:41 +01002178 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002179
2180 var RslChannelNr chan_nr := f_chreq_act_ack();
2181
2182 var octetstring l3 := '00010203040506'O;
2183 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2184
2185 T.start;
2186 alt {
2187 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2188 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2189 }
2190 [] BSSAP.receive { repeat; }
2191 [] IPA_RSL[0].receive { repeat; }
2192 [] T.timeout {}
2193 }
2194
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002195 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002196}
2197
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002198/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2199private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2200 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2201 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2202
2203 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2204 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2205
2206 f_establish_fully(ass_cmd, exp_compl);
2207
2208 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2209 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2210 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2211 BSSAP.receive(PDU_BSSAP:{
2212 discriminator := '1'B,
2213 spare := '0000000'B,
2214 dlci := 'C3'O,
2215 lengthIndicator := ?,
2216 pdu := { dtap := '0904'O }
2217 });
2218
2219 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2220 for (var integer i := 0; i < 32; i := i + 1) {
2221 var octetstring l3 := '09'O & f_rnd_octstring(14);
2222 var template (value) RslLinkId link_id;
2223 var template (value) OCT1 dlci;
2224
2225 if (i mod 2 == 0) {
2226 /* SAPI0 on FACCH or SDCCH */
2227 link_id := ts_RslLinkID_DCCH(0);
2228 dlci := '80'O;
2229 } else {
2230 /* SAPI3 on SACCH */
2231 link_id := ts_RslLinkID_SACCH(3);
2232 dlci := 'C3'O;
2233 }
2234
2235 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002236 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002237 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002238 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002239 }
2240}
2241testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2242 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2243 var MSC_ConnHdlr vc_conn;
2244
2245 f_init(1, true);
2246 f_sleep(1.0);
2247
2248 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2249 vc_conn.done;
2250
2251 f_shutdown_helper();
2252}
2253
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002254private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2255 template myBSSMAP_Cause cause := ?,
2256 float T_val := 2.0)
2257runs on test_CT {
2258 var BSSAP_N_DATA_ind rx_di;
2259 timer T;
2260
2261 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2262 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2263
2264 T.start(T_val);
2265 alt {
2266 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2267 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2268 if (not match(rx_cause, tr_cause)) {
2269 setverdict(fail, "Rx unexpected Cause IE: ",
2270 rx_cause, " vs expected ", tr_cause);
2271 }
2272 setverdict(pass);
2273 }
2274 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2275 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2276 }
2277 [] T.timeout {
2278 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2279 }
2280 }
2281}
2282
2283/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2284testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2285 var octetstring rnd_data := f_rnd_octstring(16);
2286 var RSL_Message rx_rsl;
2287 var DchanTuple dt;
2288
2289 f_init(1);
2290
2291 /* MS establishes a SAPI=0 link on DCCH */
2292 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2293
2294 /* MSC sends some data on (not yet established) SAPI=3 link */
2295 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2296 /* BSC attempts to establish a SAPI=3 link on DCCH */
2297 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2298
2299 /* MS sends unexpected RELease INDication on SAPI=3 */
2300 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2301 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2302 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2303
2304 /* Clean up the connection */
2305 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2306 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2307
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002308 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002309}
2310
2311/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2312testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2313 var octetstring rnd_data := f_rnd_octstring(16);
2314 var RSL_Message rx_rsl;
2315 var DchanTuple dt;
2316
2317 f_init(1);
2318
2319 /* MS establishes a SAPI=0 link on DCCH */
2320 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2321
2322 /* MSC sends some data on (not yet established) SAPI=3 link */
2323 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2324 /* BSC attempts to establish a SAPI=3 link on DCCH */
2325 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2326
2327 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2328 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2329 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2330 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2331
2332 /* Clean up the connection */
2333 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2334 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2335
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002336 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002337}
2338
2339/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2340testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2341 var octetstring rnd_data := f_rnd_octstring(16);
2342 var RSL_Message rx_rsl;
2343 var DchanTuple dt;
2344
2345 f_init(1);
2346
2347 /* MS establishes a SAPI=0 link on DCCH */
2348 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2349
2350 /* MSC sends some data on (not yet established) SAPI=3 link */
2351 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2352 /* BSC attempts to establish a SAPI=3 link on DCCH */
2353 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2354
2355 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2356 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2357
2358 /* Clean up the connection */
2359 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2360 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2361
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002362 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002363}
2364
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002365testcase TC_si_default() runs on test_CT {
2366 f_init(0);
2367 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002368 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002369}
Harald Welte4003d112017-12-09 22:35:39 +01002370
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002371/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2372 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2373private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2374{
2375 select (earfcn_index) {
2376 case (0) {
2377 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2378 return 111;
2379 }
2380 case (1) {
2381 return 1;
2382 }
2383 case (2) {
2384 return 0;
2385 }
2386 case (3) {
2387 return 65535;
2388 }
2389 case else {
2390 return 23 * (earfcn_index - 3);
2391 }
2392 }
2393}
2394
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002395function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2396 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002397
2398 f_init(0);
2399
2400 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2401 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002402 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2403 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002404 }
2405
2406 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2407
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002408 if (not istemplatekind(expect_cells, "omit")) {
2409 /* Also check that RR Channel Release contains these EARFCNs.
2410 * (copied code from TC_chan_rel_hard_clear_csfb) */
2411 var BSSAP_N_DATA_ind rx_di;
2412 var DchanTuple dt;
2413
2414 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002415 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2416 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2417 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002418
2419 /* Instruct BSC to clear channel */
2420 var BssmapCause cause := 0;
2421 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2422
2423 /* expect Clear Complete from BSC on A */
2424 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2425 /* release the SCCP connection */
2426 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2427 }
2428
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002429 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 +02002430 }
2431
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002432 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002433 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 +02002434 }
2435}
2436
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002437private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2438{
2439 var template SI2quaterRestOctetsList si2quater := {};
2440 var integer si2quater_count := (count + 2) / 3;
2441
2442 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002443 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002444 var integer index := i / 3;
2445 var integer earfcn_index := i mod 3;
2446 if (index >= lengthof(si2quater)) {
2447 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2448 }
2449 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);
2450 }
2451
2452 return si2quater;
2453}
2454
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002455private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2456{
2457 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2458
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002459 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002460 for (var integer i := 0; i < count; i := i + 1) {
2461 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002462 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002463 }
2464
2465 return tr_CellSelIndValue_EUTRAN(cells);
2466}
2467
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002468private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2469{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002470 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002471 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002472 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2473 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002474}
2475
2476testcase TC_si2quater_2_earfcns() runs on test_CT {
2477 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002478 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002479}
2480
2481testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002482 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002483 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002484}
2485
2486testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002487 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002488 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002489}
2490
2491testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002492 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002493 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002494}
2495
2496testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002497 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002498 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002499}
2500
2501testcase TC_si2quater_12_earfcns() runs on test_CT {
2502 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002503 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002504}
2505
2506testcase TC_si2quater_23_earfcns() runs on test_CT {
2507 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002508 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002509}
2510
2511testcase TC_si2quater_32_earfcns() runs on test_CT {
2512 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002513 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002514}
2515
2516testcase TC_si2quater_33_earfcns() runs on test_CT {
2517 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002518 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002519}
2520
2521testcase TC_si2quater_42_earfcns() runs on test_CT {
2522 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002523 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002524}
2525
2526testcase TC_si2quater_48_earfcns() runs on test_CT {
2527 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002528 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002529}
2530
2531/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2532 * 48 EARFCNs. */
2533testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002534 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002535 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2536 f_init(0);
2537
2538 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002539 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2540 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002541 }
2542
2543 /* The 49th EARFCN no longer fits, expect VTY error */
2544 f_vty_enter_cfg_bts(BSCVTY, 0);
2545 var charstring vty_error;
2546 vty_error := f_vty_transceive_ret(BSCVTY,
2547 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2548 f_vty_transceive(BSCVTY, "end");
2549
2550 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2551 log("Got expected VTY error: ", vty_error);
2552 setverdict(pass);
2553 } else {
2554 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2555 }
2556
2557 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2558
2559 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002560 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 +02002561 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002562 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002563}
2564
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002565private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2566{
2567 var uint8_t count := 0;
2568 for (var integer i := 5; i < 16; i := i + 1) {
2569 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2570 count := count + 1;
2571 }
2572 }
2573 return count;
2574}
2575
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002576private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2577{
2578 var ASP_RSL_Unitdata rx_rsl_ud;
2579 var SystemInformationType1 last_si1;
2580
2581 timer T := 30.0;
2582 T.start;
2583 alt {
2584 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2585 tr_RSL_BCCH_INFO,
2586 tr_RSL_NO_SACCH_FILL,
2587 tr_RSL_SACCH_FILL))
2588 ) -> value rx_rsl_ud {
2589 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2590 if (g_system_information[rsl_idx].si1 == omit) {
2591 repeat;
2592 }
2593 last_si1 := g_system_information[rsl_idx].si1;
2594 g_system_information[rsl_idx].si1 := omit;
2595 T.stop;
2596 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002597 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002598 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2599 }
2600 return last_si1;
2601}
2602
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002603/* verify ACC rotate feature */
2604testcase TC_si_acc_rotate() runs on test_CT {
2605 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002606 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002607 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002608 var uint8_t count;
2609 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2610
2611 f_init(0, guard_timeout := 60.0);
2612
2613 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2614 "access-control-class-rotate 3",
2615 "access-control-class-rotate-quantum 1"});
2616
2617 /* Init and get first sysinfo */
2618 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2619
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002620 for (var integer i:= 0; i < 20; i := i + 1) {
2621 last_si1 := f_recv_next_si1(0);
2622 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002623 count := f_acc09_count_allowed(acc);
2624 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2625
2626 if (count != 3) {
2627 log("RSL: EXPECTED SI ACC len=3");
2628 setverdict(fail, "received SI does not match expectations");
2629 break;
2630 }
2631
2632 for (var integer j := 0; j < 10; j := j + 1) {
2633 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2634 times_allowed[j] := times_allowed[j] + 1;
2635 }
2636 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002637 }
2638
2639 for (var integer j := 0; j < 10; j := j + 1) {
2640 log("ACC", j, " allowed ", times_allowed[j], " times" );
2641 if (j != 5 and times_allowed[j] < 3) {
2642 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2643 } else if (j == 5 and times_allowed[j] > 0) {
2644 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2645 }
2646 }
2647
2648 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2649 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002650 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002651}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002652
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002653/* verify ACC startup ramp+rotate feature */
2654testcase TC_si_acc_ramp_rotate() runs on test_CT {
2655 var template SystemInformationConfig sic := SystemInformationConfig_default;
2656 var SystemInformationType1 last_si1;
2657 var AccessControlClass acc;
2658 var ASP_RSL_Unitdata rx_rsl_ud;
2659 var uint8_t count;
2660 var uint8_t prev_count;
2661 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2662
2663 f_init(0, guard_timeout := 80.0);
2664
2665 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2666 "access-control-class-rotate 0",
2667 "access-control-class-rotate-quantum 1",
2668 "access-control-class-ramping",
2669 "access-control-class-ramping-step-interval 5",
2670 "access-control-class-ramping-step-size 5"});
2671
2672 /* Init and get first sysinfo */
2673 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2674 last_si1 := g_system_information[0].si1;
2675 acc := last_si1.rach_control.acc;
2676 count := f_acc09_count_allowed(acc);
2677 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2678 while (count > 0) {
2679 last_si1 := f_recv_next_si1(0);
2680 acc := last_si1.rach_control.acc;
2681 count := f_acc09_count_allowed(acc);
2682 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2683 }
2684
2685 /* Increase adm subset size, we should see ramping start up */
2686 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2687 prev_count := 0;
2688 while (true) {
2689 last_si1 := f_recv_next_si1(0);
2690 acc := last_si1.rach_control.acc;
2691 count := f_acc09_count_allowed(acc);
2692 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2693
2694 if (prev_count > count) {
2695 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2696 break;
2697 }
2698
2699 if (count == 9) {
2700 break; /* Maximum reached (10 - 1 perm barred), done here */
2701 }
2702
2703 prev_count := count;
2704 }
2705
2706 setverdict(pass);
2707
2708 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2709 "rach access-control-class 4 allowed",
2710 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002711 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002712}
2713
Harald Welte4003d112017-12-09 22:35:39 +01002714testcase TC_ctrl_msc_connection_status() runs on test_CT {
2715 var charstring ctrl_resp;
2716
Harald Welte89d42e82017-12-17 16:42:41 +01002717 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002718
2719 /* See https://osmocom.org/issues/2729 */
2720 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002721 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002722}
2723
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002724testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2725 var charstring ctrl_resp;
2726
2727 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002728
2729 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002730 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002731}
2732
Harald Welte4003d112017-12-09 22:35:39 +01002733testcase TC_ctrl() runs on test_CT {
2734 var charstring ctrl_resp;
2735
Harald Welte89d42e82017-12-17 16:42:41 +01002736 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002737
2738 /* all below values must match the osmo-bsc.cfg config file used */
2739
Harald Welte6a129692018-03-17 17:30:14 +01002740 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2741 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002742 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002743
2744 var integer bts_nr := 0;
2745 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2746 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2747 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2748 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2749 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2750 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2751 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2752
2753 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2754 f_sleep(2.0);
2755 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2756 setverdict(fail, "oml-uptime not incrementing as expected");
2757 }
2758 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2759
2760 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2761
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002762 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002763}
2764
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002765/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2766 "location-state" over the SCCPlite IPA conn */
2767testcase TC_ctrl_location() runs on test_CT {
2768 var MSC_ConnHdlr vc_conn;
2769 var integer bts_nr := 0;
2770
2771 f_init(1, true);
2772 f_sleep(1.0);
2773
2774 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2775 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2776 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2777
2778 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2779 f_sleep(2.0);
2780
2781 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2782 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2783 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
2784
2785 /* should match the one from config */
2786 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
2787
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002788 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002789}
2790
Harald Welte6f521d82017-12-11 19:52:02 +01002791
2792/***********************************************************************
2793 * Paging Testing
2794 ***********************************************************************/
2795
2796type record Cell_Identity {
2797 GsmMcc mcc,
2798 GsmMnc mnc,
2799 GsmLac lac,
2800 GsmCellId ci
2801};
Harald Welte24135bd2018-03-17 19:27:53 +01002802private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01002803private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01002804
Harald Welte5d1a2202017-12-13 19:51:29 +01002805type set of integer BtsIdList;
2806
2807private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
2808 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
2809 if (bts_id == bts_ids[j]) {
2810 return true;
2811 }
2812 }
2813 return false;
2814}
Harald Welte6f521d82017-12-11 19:52:02 +01002815
2816/* core paging test helper function; used by most paging test cases */
2817private function f_pageing_helper(hexstring imsi,
2818 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01002819 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01002820 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002821 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01002822{
2823 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002824 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01002825 var RSL_Message rx_rsl;
2826 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01002827 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01002828
2829 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01002830
2831 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01002832 for (i := 0; i < NUM_BTS; i := i + 1) {
2833 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01002834 }
Harald Welte6f521d82017-12-11 19:52:02 +01002835
2836 if (isvalue(rsl_chneed)) {
2837 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
2838 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
2839 } else {
2840 bssmap_chneed := omit;
2841 }
2842
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002843 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
2844 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01002845
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002846 if (not istemplatekind(tmsi, "omit")) {
2847 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002848 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002849 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002850 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002851
Harald Welte5d1a2202017-12-13 19:51:29 +01002852 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002853 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01002854 /* check channel type, paging group */
2855 if (rx_rsl.ies[1].body.paging_group != paging_group) {
2856 setverdict(fail, "Paging for wrong paging group");
2857 }
2858 if (ispresent(rsl_chneed) and
2859 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
2860 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
2861 }
Harald Welte6f521d82017-12-11 19:52:02 +01002862 }
Harald Welte2fccd982018-01-31 15:48:19 +01002863 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01002864 /* do a quick check on all not-included BTSs if they received paging */
2865 for (i := 0; i < NUM_BTS; i := i + 1) {
2866 timer T := 0.1;
2867 if (f_bts_in_list(i, bts_ids)) {
2868 continue;
2869 }
2870 T.start;
2871 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002872 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01002873 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
2874 }
2875 [] IPA_RSL[i].receive { repeat; }
2876 [] T.timeout { }
2877 }
Harald Welte6f521d82017-12-11 19:52:02 +01002878 }
2879
2880 setverdict(pass);
2881}
2882
Harald Welte5d1a2202017-12-13 19:51:29 +01002883const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01002884const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01002885const BtsIdList c_BtsId_LAC1 := { 0, 1 };
2886const BtsIdList c_BtsId_LAC2 := { 2 };
2887
Harald Welte6f521d82017-12-11 19:52:02 +01002888/* PAGING by IMSI + TMSI */
2889testcase TC_paging_imsi_nochan() runs on test_CT {
2890 var BSSMAP_FIELD_CellIdentificationList cid_list;
2891 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01002892 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002893 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002894}
2895
2896/* PAGING by IMSI + TMSI */
2897testcase TC_paging_tmsi_nochan() runs on test_CT {
2898 var BSSMAP_FIELD_CellIdentificationList cid_list;
2899 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002900 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002901 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002902}
2903
2904/* Paging with different "channel needed' values */
2905testcase TC_paging_tmsi_any() runs on test_CT {
2906 var BSSMAP_FIELD_CellIdentificationList cid_list;
2907 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002908 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002909 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002910}
2911testcase TC_paging_tmsi_sdcch() runs on test_CT {
2912 var BSSMAP_FIELD_CellIdentificationList cid_list;
2913 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002914 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002915 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002916}
2917testcase TC_paging_tmsi_tch_f() runs on test_CT {
2918 var BSSMAP_FIELD_CellIdentificationList cid_list;
2919 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002920 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002921 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002922}
2923testcase TC_paging_tmsi_tch_hf() runs on test_CT {
2924 var BSSMAP_FIELD_CellIdentificationList cid_list;
2925 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01002926 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002927 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002928}
2929
2930/* Paging by CGI */
2931testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
2932 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2933 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002934 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002935 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002936}
2937
2938/* Paging by LAC+CI */
2939testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
2940 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2941 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002942 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002943 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002944}
2945
2946/* Paging by CI */
2947testcase TC_paging_imsi_nochan_ci() runs on test_CT {
2948 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2949 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002950 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01002951 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002952}
2953
2954/* Paging by LAI */
2955testcase TC_paging_imsi_nochan_lai() runs on test_CT {
2956 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2957 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002958 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002959 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002960}
2961
2962/* Paging by LAC */
2963testcase TC_paging_imsi_nochan_lac() runs on test_CT {
2964 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2965 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01002966 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002967 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002968}
2969
2970/* Paging by "all in BSS" */
2971testcase TC_paging_imsi_nochan_all() runs on test_CT {
2972 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2973 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01002974 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002975 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01002976}
2977
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002978/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01002979testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
2980 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2981 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 +01002982 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002983 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01002984}
Harald Welte6f521d82017-12-11 19:52:02 +01002985
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002986/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01002987testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
2988 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2989 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002990 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002991 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01002992}
2993
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002994/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01002995testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
2996 var template BSSMAP_FIELD_CellIdentificationList cid_list;
2997 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01002998 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01002999 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003000}
3001
Harald Welte6f521d82017-12-11 19:52:02 +01003002/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003003testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3004 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3005 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3006 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003007 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003008}
3009
3010/* Paging on empty list: Verify none of them page */
3011testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3012 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3013 cid_list := { cIl_LAC := { } };
3014 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003015 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003016}
3017
Stefan Sperling049a86e2018-03-20 15:51:00 +01003018/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3019testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3020 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3021 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3022 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3023 f_shutdown_helper();
3024}
3025
Harald Welte6f521d82017-12-11 19:52:02 +01003026/* Verify paging retransmission interval + count */
3027/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003028/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003029
Harald Weltee65d40e2017-12-13 00:09:06 +01003030/* Verify PCH load */
3031testcase TC_paging_imsi_load() runs on test_CT {
3032 var BSSMAP_FIELD_CellIdentificationList cid_list;
3033 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003034 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003035 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003036 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003037
3038 /* tell BSC there is no paging space anymore */
3039 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003040 f_sleep(0.2);
3041 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003042
3043 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3044 * there would be 8 retransmissions during 4 seconds */
3045 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003046 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003047 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003048 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003049 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003050 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003051 }
Harald Welte2caa1062018-03-17 18:19:05 +01003052 [] T_retrans.timeout {
3053 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3054 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3055 T_retrans.start;
3056 repeat;
3057 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003058 [] T.timeout {
3059 setverdict(pass);
3060 }
3061 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003062
3063 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003064}
3065
Harald Welte235ebf12017-12-15 14:18:16 +01003066/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003067testcase TC_paging_counter() runs on test_CT {
3068 var BSSMAP_FIELD_CellIdentificationList cid_list;
3069 timer T := 4.0;
3070 var integer i;
3071 var integer paging_attempted_bsc;
3072 var integer paging_attempted_bts[NUM_BTS];
3073 var integer paging_expired_bts[NUM_BTS];
3074 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3075
3076 f_init();
3077
3078 /* read counters before paging */
3079 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3080 for (i := 0; i < NUM_BTS; i := i+1) {
3081 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3082 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3083 }
3084
3085 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3086
3087 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3088 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3089 for (i := 0; i < NUM_BTS; i := i+1) {
3090 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3091 paging_attempted_bts[i]+1);
3092 }
3093
3094 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3095 f_sleep(12.0);
3096 for (i := 0; i < NUM_BTS; i := i+1) {
3097 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3098 paging_expired_bts[i]+1);
3099 }
Harald Welte1ff69992017-12-14 12:31:17 +01003100
Philipp Maier282ca4b2018-02-27 17:17:00 +01003101 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003102}
3103
3104
Harald Welte10985002017-12-12 09:29:15 +01003105/* Verify paging stops after A-RESET */
3106testcase TC_paging_imsi_a_reset() runs on test_CT {
3107 var BSSMAP_FIELD_CellIdentificationList cid_list;
3108 timer T := 3.0;
3109 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003110 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003111
3112 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003113 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 +01003114 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003115 [] 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 +01003116 [] BSSAP.receive { repeat; }
3117 }
3118
Daniel Willmanncbef3982018-07-30 09:22:40 +02003119 /* Wait to avoid a possible race condition if a paging message is
3120 * received right before the reset ACK. */
3121 f_sleep(0.2);
3122
Harald Welte10985002017-12-12 09:29:15 +01003123 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003124 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3125 IPA_RSL[i].clear;
3126 }
Harald Welte10985002017-12-12 09:29:15 +01003127
3128 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3129 T.start;
3130 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003131 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003132 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003133 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003134 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003135 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003136 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003137 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003138 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003139 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003140 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003141 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003142 }
Harald Welte10985002017-12-12 09:29:15 +01003143 [] T.timeout {
3144 setverdict(pass);
3145 }
3146 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003147
3148 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003149}
Harald Welteae026692017-12-09 01:03:01 +01003150
Philipp Maierf45824a2019-08-14 14:44:10 +02003151/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3152 * paging response we can not know which MSC is in charge, so we will blindly
3153 * pick the first configured MSC. This behavior is required in order to make
3154 * MT-CSFB calls working because in those cases the BSC can not know that the
3155 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3156 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003157 */
3158testcase TC_paging_resp_unsol() runs on test_CT {
3159
3160 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003161 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003162
3163 var BSSAP_N_CONNECT_ind rx_c_ind;
3164 var DchanTuple dt;
3165 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003166 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003167
3168 /* Send CHAN RQD and wait for allocation; acknowledge it */
3169 dt.rsl_chan_nr := f_chreq_act_ack();
3170
3171 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3172 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3173
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003174
Philipp Maierf45824a2019-08-14 14:44:10 +02003175 /* Expevct a CR with a matching Paging response on the A-Interface */
3176 T.start;
3177 alt {
3178 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3179 setverdict(pass);
3180 }
3181 [] BSSAP.receive {
3182 setverdict(fail, "Received unexpected message on A-Interface!");
3183 }
3184 [] T.timeout {
3185 setverdict(fail, "Received nothing on A-Interface!");
3186 }
3187 }
3188
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003189 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003190}
3191
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003192/* Test RSL link drop causes counter increment */
3193testcase TC_rsl_drop_counter() runs on test_CT {
3194 var integer rsl_fail;
3195
Harald Welte89d42e82017-12-17 16:42:41 +01003196 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003197
3198 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3199
3200 bts[0].rsl.vc_IPA.stop;
3201
3202 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3203
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003204 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003205}
3206
3207/* TODO: Test OML link drop causes counter increment */
3208
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003209/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3210function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3211 timer T := 10.0;
3212
3213 bts[0].rsl.id := "IPA-0-RSL";
3214 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3215 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3216 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003217 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003218
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003219 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003220
3221 f_init_mgcp("VirtMSC");
3222
3223 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3224 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3225 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3226 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3227
3228 /* wait for IPA OML link to connect and then disconnect */
3229 T.start;
3230 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003231 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003232 T.stop;
3233 return true;
3234 }
3235 [] IPA_RSL[0].receive { repeat }
3236 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003237 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003238 }
3239 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003240 return false;
3241}
3242
3243/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3244testcase TC_rsl_unknown_unit_id() runs on test_CT {
3245 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3246 setverdict(pass);
3247 } else {
3248 setverdict(fail, "Timeout RSL waiting for connection to close");
3249 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003250 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003251}
3252
3253
3254/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3255testcase TC_oml_unknown_unit_id() runs on test_CT {
3256 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3257 setverdict(pass);
3258 } else {
3259 setverdict(fail, "Timeout OML waiting for connection to close");
3260 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003261 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003262}
3263
3264
Harald Weltec1a2fff2017-12-17 11:06:19 +01003265/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003266 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003267 ***********************************************************************/
3268
Harald Welte6811d102019-04-14 22:23:14 +02003269import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003270import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003271import from RSL_Emulation all;
3272import from MSC_ConnectionHandler all;
3273
3274type function void_fn(charstring id) runs on MSC_ConnHdlr;
3275
Harald Welte336820c2018-05-31 20:34:52 +02003276/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003277private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3278 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003279 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003280 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003281 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003282 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003283 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3284 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3285 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003286 if (isvalue(bts[2])) {
3287 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3288 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3289 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003290 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003291 if (mp_enable_lcs_tests) {
3292 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3293 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3294 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003295 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003296 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003297 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003298}
3299
3300function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3301runs on test_CT return MSC_ConnHdlr {
3302 var charstring id := testcasename();
3303 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003304 var integer bssap_idx := 0;
3305 if (isvalue(pars)) {
3306 bssap_idx := valueof(pars).mscpool.bssap_idx;
3307 }
Harald Welte336820c2018-05-31 20:34:52 +02003308 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003309 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003310 /* Emit a marker to appear in the SUT's own logging output */
3311 f_logp(BSCVTY, testcasename() & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003312 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003313 return vc_conn;
3314}
3315
Harald Weltea0630032018-03-20 21:09:55 +01003316/* first function inside ConnHdlr component; sets g_pars + starts function */
3317private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3318runs on MSC_ConnHdlr {
3319 if (isvalue(pars)) {
3320 g_pars := valueof(pars);
3321 }
3322 fn.apply(id);
3323}
3324
Oliver Smith26a3db72021-07-09 13:51:29 +02003325private function f_vty_encryption_a5(charstring options) runs on test_CT {
3326 f_vty_transceive(BSCVTY, "configure terminal");
3327 f_vty_transceive(BSCVTY, "network");
3328 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3329 f_vty_transceive(BSCVTY, "exit");
3330 f_vty_transceive(BSCVTY, "exit");
3331}
3332
3333private function f_vty_encryption_a5_reset() runs on test_CT {
3334 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3335 f_vty_encryption_a5("0 1 3");
3336}
3337
Harald Welte3c86ea02018-05-10 22:28:05 +02003338/* Establish signalling channel (non-assignment case) followed by cipher mode */
3339private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003340 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3341 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003342 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003343 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3344 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3345 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3346 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003347
Philipp Maier23000732018-05-18 11:25:37 +02003348 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003349}
3350testcase TC_ciph_mode_a5_0() runs on test_CT {
3351 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003352 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003353 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3354
3355 f_init(1, true);
3356 f_sleep(1.0);
3357 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3358 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003359 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003360}
3361testcase TC_ciph_mode_a5_1() runs on test_CT {
3362 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003363 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003364 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3365
3366 f_init(1, true);
3367 f_sleep(1.0);
3368 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3369 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003370 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003371}
Oliver Smith50b98122021-07-09 15:00:28 +02003372/* OS#4975: verify that A5/2 is preferred over A5/0 */
3373testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3374 var MSC_ConnHdlr vc_conn;
3375 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3376
3377 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3378 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3379
3380 f_init(1, true);
3381 f_vty_encryption_a5("0 1 2 3");
3382 f_sleep(1.0);
3383 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3384 vc_conn.done;
3385 f_vty_encryption_a5_reset();
3386 f_shutdown_helper();
3387}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003388/* OS#4975: verify that A5/1 is preferred over A5/2 */
3389testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3390 var MSC_ConnHdlr vc_conn;
3391 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3392
3393 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3394 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3395
3396 f_init(1, true);
3397 f_vty_encryption_a5("1 2");
3398 f_sleep(1.0);
3399 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3400 vc_conn.done;
3401 f_vty_encryption_a5_reset();
3402 f_shutdown_helper();
3403}
Harald Welte3c86ea02018-05-10 22:28:05 +02003404testcase TC_ciph_mode_a5_3() runs on test_CT {
3405 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003406 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003407 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3408
3409 f_init(1, true);
3410 f_sleep(1.0);
3411 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3412 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003413 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003414}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003415/* Establish a Signalling channel with A5/4 encryption. */
3416testcase TC_ciph_mode_a5_4() runs on test_CT {
3417 var MSC_ConnHdlr vc_conn;
3418 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3419 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003420
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003421 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003422 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003423 f_sleep(1.0);
3424 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3425 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003426 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003427 f_shutdown_helper();
3428}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003429/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3430private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3431 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3432 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3433 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3434 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3435
3436 f_establish_fully(ass_cmd, exp_compl);
3437}
3438testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3439 var MSC_ConnHdlr vc_conn;
3440 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3441
3442 f_init(1, true);
3443 f_sleep(1.0);
3444 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3445 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003446 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003447}
3448
Harald Welte3c86ea02018-05-10 22:28:05 +02003449
3450/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003451private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003452 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3453 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003454
Harald Welte552620d2017-12-16 23:21:36 +01003455 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3456 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003457
Harald Weltea0630032018-03-20 21:09:55 +01003458 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003459}
Harald Welte552620d2017-12-16 23:21:36 +01003460testcase TC_assignment_fr_a5_0() runs on test_CT {
3461 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003462 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003463 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003464
Harald Welte89d42e82017-12-17 16:42:41 +01003465 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003466 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003467 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003468 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003469 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003470}
Harald Welte552620d2017-12-16 23:21:36 +01003471testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003472 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003473 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003474 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003475
Harald Welte89d42e82017-12-17 16:42:41 +01003476 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003477 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003478 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3479 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003480 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003481}
3482testcase TC_assignment_fr_a5_3() runs on test_CT {
3483 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003484 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003485 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003486
Harald Welte651fcdc2018-05-10 20:23:16 +02003487 f_init(1, true);
3488 f_sleep(1.0);
3489 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003490 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003491 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003492}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003493/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3494testcase TC_assignment_fr_a5_4() runs on test_CT {
3495 var MSC_ConnHdlr vc_conn;
3496 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3497 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3498
3499 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003500 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003501 f_sleep(1.0);
3502 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3503 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003504 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003505 f_shutdown_helper();
3506}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003507
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003508/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3509testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3510 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3511 var MSC_ConnHdlr vc_conn;
3512
3513 f_init(1, true);
3514 f_sleep(1.0);
3515
3516 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3517 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3518 vc_conn.done;
3519 f_shutdown_helper();
3520}
3521
Harald Welte552620d2017-12-16 23:21:36 +01003522/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3523private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003524 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003525 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003526 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003527
3528 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003529 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3530
Harald Weltea0630032018-03-20 21:09:55 +01003531 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003532}
Harald Welte552620d2017-12-16 23:21:36 +01003533testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3534 var MSC_ConnHdlr vc_conn;
3535
Harald Welte89d42e82017-12-17 16:42:41 +01003536 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003537 f_sleep(1.0);
3538
Harald Welte8863fa12018-05-10 20:15:27 +02003539 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003540 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003541 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003542}
3543
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003544private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3545 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3546 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003547
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003548 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3549 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3550
3551 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3552
3553 var BSSMAP_FIELD_CodecType codecType;
3554 timer T := 10.0;
3555
3556 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3557 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3558
3559 f_create_chan_and_exp();
3560 /* we should now have a COMPL_L3 at the MSC */
3561
3562 var template PDU_BSSAP exp_l3_compl;
3563 exp_l3_compl := tr_BSSMAP_ComplL3()
3564 if (g_pars.aoip == false) {
3565 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3566 } else {
3567 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3568 }
3569 T.start;
3570 alt {
3571 [] BSSAP.receive(exp_l3_compl);
3572 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3573 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3574 }
3575 [] T.timeout {
3576 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3577 }
3578 }
3579
3580 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003581 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003582}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003583testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3584 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003585 var MSC_ConnHdlr vc_conn;
3586
Harald Welte89d42e82017-12-17 16:42:41 +01003587 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003588 f_sleep(1.0);
3589
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003590 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003591 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003592 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003593 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003594}
3595
3596
Harald Welte4532e0a2017-12-23 02:05:44 +01003597private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003598 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003599 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003600 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003601 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003602
3603 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003604 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003605
3606 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003607 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3608 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003609 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3610 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3611 };
3612 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003613}
3614
3615testcase TC_assignment_sign() runs on test_CT {
3616 var MSC_ConnHdlr vc_conn;
3617
3618 f_init(1, true);
3619 f_sleep(1.0);
3620
Harald Welte8863fa12018-05-10 20:15:27 +02003621 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003622 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003623 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003624}
3625
Harald Welte60aa5762018-03-21 19:33:13 +01003626/***********************************************************************
3627 * Codec (list) testing
3628 ***********************************************************************/
3629
3630/* check if the given rsl_mode is compatible with the a_elem */
3631private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3632return boolean {
3633 select (a_elem.codecType) {
3634 case (GSM_FR) {
3635 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3636 return true;
3637 }
3638 }
3639 case (GSM_HR) {
3640 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3641 return true;
3642 }
3643 }
3644 case (GSM_EFR) {
3645 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3646 return true;
3647 }
3648 }
3649 case (FR_AMR) {
3650 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3651 return true;
3652 }
3653 }
3654 case (HR_AMR) {
3655 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3656 return true;
3657 }
3658 }
3659 case else { }
3660 }
3661 return false;
3662}
3663
3664/* check if the given rsl_mode is compatible with the a_list */
3665private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3666return boolean {
3667 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3668 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3669 return true;
3670 }
3671 }
3672 return false;
3673}
3674
3675/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003676function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003677return BSSMAP_IE_ChannelType {
3678 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3679 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3680 select (a_elem.codecType) {
3681 case (GSM_FR) {
3682 ret.channelRateAndType := ChRate_TCHF;
3683 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3684 }
3685 case (GSM_HR) {
3686 ret.channelRateAndType := ChRate_TCHH;
3687 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3688 }
3689 case (GSM_EFR) {
3690 ret.channelRateAndType := ChRate_TCHF;
3691 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3692 }
3693 case (FR_AMR) {
3694 ret.channelRateAndType := ChRate_TCHF;
3695 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3696 }
3697 case (HR_AMR) {
3698 ret.channelRateAndType := ChRate_TCHH;
3699 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3700 }
3701 case else {
3702 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003703 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003704 }
3705 }
3706 return ret;
3707}
3708
Harald Weltea63b9102018-03-22 20:36:16 +01003709private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3710return template RSL_IE_Body {
3711 var template RSL_IE_Body mode_ie := {
3712 chan_mode := {
3713 len := ?,
3714 reserved := ?,
3715 dtx_d := ?,
3716 dtx_u := ?,
3717 spd_ind := RSL_SPDI_SPEECH,
3718 ch_rate_type := -,
3719 coding_alg_rate := -
3720 }
3721 }
3722
3723 select (a_elem.codecType) {
3724 case (GSM_FR) {
3725 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3726 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3727 }
3728 case (GSM_HR) {
3729 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3730 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3731 }
3732 case (GSM_EFR) {
3733 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3734 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3735 }
3736 case (FR_AMR) {
3737 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3738 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3739 }
3740 case (HR_AMR) {
3741 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3742 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3743 }
3744 }
3745 return mode_ie;
3746}
3747
Harald Welte60aa5762018-03-21 19:33:13 +01003748type record CodecListTest {
3749 BSSMAP_IE_SpeechCodecList codec_list,
3750 charstring id
3751}
3752type record of CodecListTest CodecListTests
3753
3754private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003755 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3756 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003757
3758 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003759 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003760 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3761 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3762 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003763 if (isvalue(g_pars.expect_mr_s0_s7)) {
3764 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3765 g_pars.expect_mr_s0_s7;
3766 }
Harald Welte79f3f542018-05-25 20:02:37 +02003767 }
Harald Welte60aa5762018-03-21 19:33:13 +01003768 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3769 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003770 log("expecting ASS COMPL like this: ", exp_compl);
3771
3772 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01003773
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003774 if (not g_pars.expect_channel_mode_modify) {
3775 /* Verify that the RSL-side activation actually matches our expectations */
3776 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01003777
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003778 var RSL_IE_Body mode_ie;
3779 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
3780 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02003781 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003782 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003783 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
3784 if (not match(mode_ie, t_mode_ie)) {
3785 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
3786 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003787 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003788
3789 var RSL_IE_Body mr_conf;
3790 if (g_pars.expect_mr_conf_ie != omit) {
3791 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
3792 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
3793 mtc.stop;
3794 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003795 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003796
3797 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
3798 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
3799 g_pars.expect_mr_conf_ie);
3800 }
3801 } else {
3802 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
3803 log("found RSL MR CONFIG IE: ", mr_conf);
3804 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
3805 mtc.stop;
3806 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003807 }
3808 }
Harald Welte60aa5762018-03-21 19:33:13 +01003809}
3810
Philipp Maierd0e64b02019-03-13 14:15:23 +01003811private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
3812
3813 var PDU_BSSAP ass_cmd := f_gen_ass_req();
3814 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
3815
3816 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003817 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01003818 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3819 }
3820 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3821 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
3822 log("expecting ASS FAIL like this: ", exp_fail);
3823
3824 f_establish_fully(ass_cmd, exp_fail);
3825}
3826
Harald Welte60aa5762018-03-21 19:33:13 +01003827testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003828 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003829 var MSC_ConnHdlr vc_conn;
3830
3831 f_init(1, true);
3832 f_sleep(1.0);
3833
3834 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003835 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003836 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003837 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003838}
3839
3840testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003841 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003842 var MSC_ConnHdlr vc_conn;
3843
3844 f_init(1, true);
3845 f_sleep(1.0);
3846
3847 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003848 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003849 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003850 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003851}
3852
3853testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003854 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003855 var MSC_ConnHdlr vc_conn;
3856
3857 f_init(1, true);
3858 f_sleep(1.0);
3859
3860 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003861 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003862 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003863 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003864}
3865
Philipp Maierd0e64b02019-03-13 14:15:23 +01003866/* Allow 5,90k only (current default config) */
3867private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003868 f_vty_cfg_msc(BSCVTY, 0, {
3869 "amr-config 12_2k forbidden",
3870 "amr-config 10_2k forbidden",
3871 "amr-config 7_95k forbidden",
3872 "amr-config 7_40k forbidden",
3873 "amr-config 6_70k forbidden",
3874 "amr-config 5_90k allowed",
3875 "amr-config 5_15k forbidden",
3876 "amr-config 4_75k forbidden"
3877 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003878}
3879
3880/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
3881 * ("Config-NB-Code = 1") */
3882private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00003883 f_vty_cfg_msc(BSCVTY, 0, {
3884 "amr-config 12_2k allowed",
3885 "amr-config 10_2k forbidden",
3886 "amr-config 7_95k forbidden",
3887 "amr-config 7_40k allowed",
3888 "amr-config 6_70k forbidden",
3889 "amr-config 5_90k allowed",
3890 "amr-config 5_15k forbidden",
3891 "amr-config 4_75k allowed"
3892 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01003893}
3894
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003895private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
3896 var charstring tch;
3897 if (fr) {
3898 tch := "tch-f";
3899 } else {
3900 tch := "tch-h";
3901 }
3902 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
3903}
3904
3905/* Set the AMR start-mode for this TCH back to the default configuration. */
3906private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
3907 f_vty_amr_start_mode_set(fr, "auto");
3908}
3909
Harald Welte60aa5762018-03-21 19:33:13 +01003910testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003911 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003912 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02003913
3914 /* Note: This setups the codec configuration. The parameter payload in
3915 * mr_conf must be consistant with the parameter codecElements in pars
3916 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003917 var RSL_IE_Body mr_conf := {
3918 other := {
3919 len := 2,
3920 payload := '2804'O
3921 }
3922 };
Harald Welte60aa5762018-03-21 19:33:13 +01003923
Philipp Maier7695a0d2018-09-27 17:52:14 +02003924 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01003925 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02003926 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
3927 pars.expect_mr_conf_ie := mr_conf;
3928
Harald Welte60aa5762018-03-21 19:33:13 +01003929 f_init(1, true);
3930 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003931 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01003932
Harald Welte8863fa12018-05-10 20:15:27 +02003933 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003934 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003935
3936 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01003937 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003938}
3939
3940testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003941 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003942 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02003943
3944 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003945 var RSL_IE_Body mr_conf := {
3946 other := {
3947 len := 2,
3948 payload := '2804'O
3949 }
3950 };
Harald Welte60aa5762018-03-21 19:33:13 +01003951
Philipp Maier7695a0d2018-09-27 17:52:14 +02003952 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01003953 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02003954 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
3955 pars.expect_mr_conf_ie := mr_conf;
3956
Harald Welte60aa5762018-03-21 19:33:13 +01003957 f_init(1, true);
3958 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003959 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01003960
Harald Welte8863fa12018-05-10 20:15:27 +02003961 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003962 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00003963
3964 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01003965 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003966}
3967
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003968/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
3969testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
3970 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3971 var MSC_ConnHdlr vc_conn;
3972
3973 f_init(1, true);
3974 f_sleep(1.0);
3975
3976 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
3977 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
3978 * expecting a Channel Mode Modify if the channel type is compatible. */
3979 f_disable_all_sdcch();
3980 f_disable_all_tch_h();
3981
3982 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3983 pars.expect_channel_mode_modify := true;
3984 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
3985 vc_conn.done;
3986
3987 f_enable_all_sdcch();
3988 f_enable_all_tch();
3989 f_shutdown_helper();
3990}
3991
Neels Hofmeyr454d7922020-11-26 02:24:57 +00003992/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
3993testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
3994 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3995 var MSC_ConnHdlr vc_conn;
3996
3997 var RSL_IE_Body mr_conf := {
3998 other := {
3999 len := 2,
4000 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4001 }
4002 };
4003
4004 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4005 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4006 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4007 pars.expect_mr_conf_ie := mr_conf;
4008
4009 f_init(1, true);
4010 f_sleep(1.0);
4011
4012 /* First set nonzero start mode bits */
4013 f_vty_amr_start_mode_set(true, "4");
4014 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4015 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4016 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4017 f_vty_amr_start_mode_set(true, "auto");
4018
4019 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4020 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004021
4022 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4023 f_vty_amr_start_mode_set(true, "1");
4024 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004025 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004026}
4027
Neels Hofmeyr21863562020-11-26 00:34:33 +00004028function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4029 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004030runs on test_CT {
4031
4032 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4033 var MSC_ConnHdlr vc_conn;
4034
4035 /* See note above */
4036 var RSL_IE_Body mr_conf := {
4037 other := {
4038 len := lengthof(mrconf),
4039 payload := mrconf
4040 }
4041 };
4042
4043 if (fr) {
4044 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4045 } else {
4046 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4047 }
4048 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4049 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4050 pars.expect_mr_conf_ie := mr_conf;
4051 pars.expect_mr_s0_s7 := exp_s8_s0;
4052
4053 f_init(1, true);
4054 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004055 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004056 f_sleep(1.0);
4057
4058 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4059 vc_conn.done;
4060 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004061 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004062}
4063
4064function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4065runs on test_CT {
4066
4067 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4068 var MSC_ConnHdlr vc_conn;
4069
4070 if (fr) {
4071 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4072 } else {
4073 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4074 }
4075 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4076 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4077
4078 f_init(1, true);
4079 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004080 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004081 f_sleep(1.0);
4082
4083 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4084 vc_conn.done;
4085 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004086 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004087}
4088
4089
4090/* Set S1, we expect an AMR multirate configuration IE with all four rates
4091 * set. */
4092testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004093 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004094 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004095}
4096
4097/* Set S1, we expect an AMR multirate configuration IE with the lower three
4098 * rates set. */
4099testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004100 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004101 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004102}
4103
4104/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4105 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4106testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004107 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004108 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004109}
4110
4111/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4112 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4113testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004114 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004115 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004116}
4117
4118/* The following block of tests selects more and more rates until all four
4119 * possible rates are in the active set (full rate) */
4120testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004121 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004122 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004123}
4124
4125testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004126 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004127 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004128}
4129
4130testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004131 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004132 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004133}
4134
4135testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004136 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004137 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004138}
4139
4140/* The following block of tests selects more and more rates until all three
4141 * possible rates are in the active set (half rate) */
4142testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004143 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004144 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004145}
4146
4147testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004148 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004149 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004150}
4151
4152testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004153 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004154 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004155}
4156
4157/* The following block tests what happens when the MSC does offer rate
4158 * configurations that are not supported by the BSC. Normally such situations
4159 * should not happen because the MSC gets informed by the BSC in advance via
4160 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4161 * to offer rates that are not applicable anyway. */
4162
4163testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004164 /* Try to include 12,2k in into the active set even though the channel
4165 * is half rate only. The BSC is expected to remove the 12,0k */
4166 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004167 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004168}
4169
4170testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004171 /* See what happens when all rates are selected at once. Since then
4172 * Also S1 is selected, this setting will be prefered and we should
4173 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4174 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004175 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004176}
4177
4178testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004179 /* Same as above, but with S1 missing, the MSC is then expected to
4180 * select the currently supported rates, which are also 12.2k, 7,40k,
4181 * 5,90k, and 4,75k, into the active set. */
4182 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004183 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004184}
4185
4186testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004187 /* Try to select no rates at all */
4188 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004189 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004190}
4191
4192testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004193 /* Try to select only unsupported rates */
4194 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004195 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004196}
4197
4198testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004199 /* Try to select 12,2k for half rate */
4200 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004201 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004202}
4203
Neels Hofmeyr21863562020-11-26 00:34:33 +00004204testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4205 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4206 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004207 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004208}
4209
4210testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4211 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4212 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004213 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004214}
4215
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004216testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004217 /* "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 +00004218 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4219 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004220 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004221}
4222
4223testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004224 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4225 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004226 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004227 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004228}
4229
Philipp Maierac09bfc2019-01-08 13:41:39 +01004230private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004231 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4232 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4233 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4234 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004235}
4236
4237private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004238 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4239 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004240}
4241
4242private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004243 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4244 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4245 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4246 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4247 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4248 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004249}
4250
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004251private function f_disable_all_sdcch() runs on test_CT {
4252 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4253 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4254 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4255 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4256}
4257
4258private function f_enable_all_sdcch() runs on test_CT {
4259 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4260 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4261 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4262 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4263}
4264
Philipp Maierac09bfc2019-01-08 13:41:39 +01004265/* Allow HR only */
4266private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4267 g_pars := f_gen_test_hdlr_pars();
4268 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4269 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4270 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4271 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4272 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4273 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4274 f_establish_fully(ass_cmd, exp_compl);
4275}
4276
4277/* Allow FR only */
4278private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4279 g_pars := f_gen_test_hdlr_pars();
4280 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4281 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4282 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4283 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4284 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4285 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4286 f_establish_fully(ass_cmd, exp_compl);
4287}
4288
4289/* Allow HR only (expect assignment failure) */
4290private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4291 g_pars := f_gen_test_hdlr_pars();
4292 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4293 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4294 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4295 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4296 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4297 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4298 f_establish_fully(ass_cmd, exp_fail);
4299}
4300
4301/* Allow FR only (expect assignment failure) */
4302private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4303 g_pars := f_gen_test_hdlr_pars();
4304 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4305 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4306 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4307 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4308 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4309 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4310 f_establish_fully(ass_cmd, exp_fail);
4311}
4312
4313/* Allow FR and HR, but prefer FR */
4314private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4315 g_pars := f_gen_test_hdlr_pars();
4316 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4317 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4318 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4319 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4320 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4321 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4322 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4323 f_establish_fully(ass_cmd, exp_compl);
4324}
4325
4326/* Allow FR and HR, but prefer HR */
4327private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4328 g_pars := f_gen_test_hdlr_pars();
4329 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4330 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4331 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4332 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4333 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4334 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4335 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4336 f_establish_fully(ass_cmd, exp_compl);
4337}
4338
4339/* Allow FR and HR, but prefer FR */
4340private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4341 g_pars := f_gen_test_hdlr_pars();
4342 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4343 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4344 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4345 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4346 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4347 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4348 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4349 f_establish_fully(ass_cmd, exp_compl);
4350}
4351
4352/* Allow FR and HR, but prefer HR */
4353private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4354 g_pars := f_gen_test_hdlr_pars();
4355 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4356 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4357 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4358 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4359 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4360 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4361 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4362 f_establish_fully(ass_cmd, exp_compl);
4363}
4364
4365/* Request a HR channel while all FR channels are exhausted, this is expected
4366 * to work without conflicts */
4367testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4368 var MSC_ConnHdlr vc_conn;
4369 f_init(1, true);
4370 f_sleep(1.0);
4371 f_enable_all_tch();
4372 f_disable_all_tch_f();
4373 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4374 vc_conn.done;
4375 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004376 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004377}
4378
4379/* Request a FR channel while all FR channels are exhausted, this is expected
4380 * to fail. */
4381testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4382 var MSC_ConnHdlr vc_conn;
4383 f_init(1, true);
4384 f_sleep(1.0);
4385 f_enable_all_tch();
4386 f_disable_all_tch_f();
4387 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4388 vc_conn.done;
4389 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004390 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004391}
4392
4393/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4394 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4395testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4396 var MSC_ConnHdlr vc_conn;
4397 f_init(1, true);
4398 f_sleep(1.0);
4399 f_enable_all_tch();
4400 f_disable_all_tch_f();
4401 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4402 vc_conn.done;
4403 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004404 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004405}
4406
4407/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4408 * are exhausted, this is expected to work without conflicts. */
4409testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4410 var MSC_ConnHdlr vc_conn;
4411 f_init(1, true);
4412 f_sleep(1.0);
4413 f_enable_all_tch();
4414 f_disable_all_tch_f();
4415 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4416 vc_conn.done;
4417 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004418 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004419}
4420
4421/* Request a FR channel while all HR channels are exhausted, this is expected
4422 * to work without conflicts */
4423testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4424 var MSC_ConnHdlr vc_conn;
4425 f_init(1, true);
4426 f_sleep(1.0);
4427 f_enable_all_tch();
4428 f_disable_all_tch_h();
4429 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4430 vc_conn.done;
4431 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004432 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004433}
4434
4435/* Request a HR channel while all HR channels are exhausted, this is expected
4436 * to fail. */
4437testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4438 var MSC_ConnHdlr vc_conn;
4439 f_init(1, true);
4440 f_sleep(1.0);
4441 f_enable_all_tch();
4442 f_disable_all_tch_h();
4443 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4444 vc_conn.done;
4445 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004446 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004447}
4448
4449/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4450 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4451testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4452 var MSC_ConnHdlr vc_conn;
4453 f_init(1, true);
4454 f_sleep(1.0);
4455 f_enable_all_tch();
4456 f_disable_all_tch_h();
4457 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4458 vc_conn.done;
4459 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004460 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004461}
4462
4463/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4464 * are exhausted, this is expected to work without conflicts. */
4465testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4466 var MSC_ConnHdlr vc_conn;
4467 f_init(1, true);
4468 f_sleep(1.0);
4469 f_enable_all_tch();
4470 f_disable_all_tch_h();
4471 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4472 vc_conn.done;
4473 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004474 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004475}
4476
4477/* Allow FR and HR, but prefer HR */
4478private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4479 g_pars := f_gen_test_hdlr_pars();
4480 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4481 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4482 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4483 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4484 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4485 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4486 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4487 f_establish_fully(ass_cmd, exp_compl);
4488}
4489
4490/* Allow FR and HR, but prefer FR */
4491private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4492 g_pars := f_gen_test_hdlr_pars();
4493 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4494 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4495 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4496 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4497 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4498 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4499 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4500 f_establish_fully(ass_cmd, exp_compl);
4501}
4502
4503/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4504 * HR, which is the prefered type, is selected. */
4505testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4506 var MSC_ConnHdlr vc_conn;
4507 f_init(1, true);
4508 f_sleep(1.0);
4509 f_enable_all_tch();
4510 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4511 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004512 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004513}
4514
4515/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4516 * FR, which is the prefered type, is selected. */
4517testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4518 var MSC_ConnHdlr vc_conn;
4519 f_init(1, true);
4520 f_sleep(1.0);
4521 f_enable_all_tch();
4522 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4523 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004524 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004525}
4526
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004527testcase TC_assignment_osmux() runs on test_CT {
4528 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4529 var MSC_ConnHdlr vc_conn;
4530
4531 /* See note above */
4532 var RSL_IE_Body mr_conf := {
4533 other := {
4534 len := 2,
4535 payload := '2804'O
4536 }
4537 };
4538
4539 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4540 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4541 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4542 pars.expect_mr_conf_ie := mr_conf;
4543 pars.use_osmux := true;
4544
4545 f_init(1, true, true);
4546 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004547 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004548
4549 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4550 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004551
4552 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004553 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004554}
4555
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004556/* test the procedure of the MSC requesting a Classmark Update:
4557 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4558 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004559private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004560 g_pars := f_gen_test_hdlr_pars();
4561
Harald Weltea0630032018-03-20 21:09:55 +01004562 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004563 /* we should now have a COMPL_L3 at the MSC */
4564 BSSAP.receive(tr_BSSMAP_ComplL3);
4565
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004566 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4567 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4568
Harald Welte898113b2018-01-31 18:32:21 +01004569 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4570 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4571 setverdict(pass);
4572}
4573testcase TC_classmark() runs on test_CT {
4574 var MSC_ConnHdlr vc_conn;
4575 f_init(1, true);
4576 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004577 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004578 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004579 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004580}
4581
Harald Welteeddf0e92020-06-21 19:42:15 +02004582/* Send a CommonID from the simulated MSC and verify that the information is used to
4583 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4584private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4585 g_pars := f_gen_test_hdlr_pars();
4586 f_MscConnHdlr_init_vty();
4587
4588 f_create_chan_and_exp();
4589 /* we should now have a COMPL_L3 at the MSC */
4590 BSSAP.receive(tr_BSSMAP_ComplL3);
4591
4592 /* Send CommonID */
4593 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4594
4595 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4596 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4597 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4598
4599 setverdict(pass);
4600}
4601testcase TC_common_id() runs on test_CT {
4602 var MSC_ConnHdlr vc_conn;
4603 f_init(1, true);
4604 f_sleep(1.0);
4605 vc_conn := f_start_handler(refers(f_tc_common_id));
4606 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004607 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004608}
4609
Harald Weltee3bd6582018-01-31 22:51:25 +01004610private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004611 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004612 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004613 /* we should now have a COMPL_L3 at the MSC */
4614 BSSAP.receive(tr_BSSMAP_ComplL3);
4615
Harald Weltee3bd6582018-01-31 22:51:25 +01004616 /* send the single message we want to send */
4617 f_rsl_send_l3(l3);
4618}
4619
4620private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4621 timer T := sec;
4622 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004623 T.start;
4624 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004625 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4626 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004627 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004628 }
4629 [] T.timeout {
4630 setverdict(pass);
4631 }
4632 }
4633}
4634
Harald Weltee3bd6582018-01-31 22:51:25 +01004635/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4636private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4637 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4638 f_bssap_expect_nothing();
4639}
Harald Welte898113b2018-01-31 18:32:21 +01004640testcase TC_unsol_ass_fail() runs on test_CT {
4641 var MSC_ConnHdlr vc_conn;
4642 f_init(1, true);
4643 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004644 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004645 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004646 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004647}
Harald Welte552620d2017-12-16 23:21:36 +01004648
Harald Welteea99a002018-01-31 20:46:43 +01004649
4650/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4651private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004652 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4653 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004654}
4655testcase TC_unsol_ass_compl() runs on test_CT {
4656 var MSC_ConnHdlr vc_conn;
4657 f_init(1, true);
4658 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004659 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004660 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004661 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004662}
4663
4664
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004665/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4666private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004667 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4668 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004669}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004670testcase TC_unsol_ho_fail() runs on test_CT {
4671 var MSC_ConnHdlr vc_conn;
4672 f_init(1, true);
4673 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004674 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004675 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004676 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004677}
4678
4679
Harald Weltee3bd6582018-01-31 22:51:25 +01004680/* short message from MS should be ignored */
4681private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004682 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004683 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01004684 /* we should now have a COMPL_L3 at the MSC */
4685 BSSAP.receive(tr_BSSMAP_ComplL3);
4686
4687 /* send short message */
4688 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
4689 f_bssap_expect_nothing();
4690}
4691testcase TC_err_82_short_msg() runs on test_CT {
4692 var MSC_ConnHdlr vc_conn;
4693 f_init(1, true);
4694 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004695 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01004696 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004697 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01004698}
4699
4700
Harald Weltee9e02e42018-01-31 23:36:25 +01004701/* 24.008 8.4 Unknown message must trigger RR STATUS */
4702private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
4703 f_est_single_l3(ts_RRM_UL_REL('00'O));
4704 timer T := 3.0
4705 alt {
4706 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
4707 setverdict(pass);
4708 }
4709 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01004710 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01004711 }
4712}
4713testcase TC_err_84_unknown_msg() runs on test_CT {
4714 var MSC_ConnHdlr vc_conn;
4715 f_init(1, true);
4716 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004717 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01004718 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004719 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01004720}
4721
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004722/***********************************************************************
4723 * Handover
4724 ***********************************************************************/
4725
Harald Welte94e0c342018-04-07 11:33:23 +02004726/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
4727private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
4728runs on test_CT {
4729 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4730 " timeslot "&int2str(ts_nr)&" ";
4731 f_vty_transceive(BSCVTY, cmd & suffix);
4732}
4733
Harald Welte261af4b2018-02-12 21:20:39 +01004734/* 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 +07004735private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
4736 uint8_t bts_nr, uint8_t trx_nr,
4737 in RslChannelNr chan_nr)
4738{
Harald Welte261af4b2018-02-12 21:20:39 +01004739 /* FIXME: resolve those from component-global state */
4740 var integer ts_nr := chan_nr.tn;
4741 var integer ss_nr;
4742 if (ischosen(chan_nr.u.ch0)) {
4743 ss_nr := 0;
4744 } else if (ischosen(chan_nr.u.lm)) {
4745 ss_nr := chan_nr.u.lm.sub_chan;
4746 } else if (ischosen(chan_nr.u.sdcch4)) {
4747 ss_nr := chan_nr.u.sdcch4.sub_chan;
4748 } else if (ischosen(chan_nr.u.sdcch8)) {
4749 ss_nr := chan_nr.u.sdcch8.sub_chan;
4750 } else {
4751 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02004752 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01004753 }
4754
4755 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4756 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004757 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01004758}
4759
Neels Hofmeyr91401012019-07-11 00:42:35 +02004760/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
4761 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
4762 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
4763 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
4764 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004765private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
4766 in RslChannelNr chan_nr, uint8_t new_bts_nr)
4767{
4768 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01004769}
4770
4771/* intra-BSC hand-over between BTS0 and BTS1 */
4772private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02004773 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4774 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01004775
4776 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4777 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4778
Harald Weltea0630032018-03-20 21:09:55 +01004779 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02004780 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01004781
4782 var HandoverState hs := {
4783 rr_ho_cmpl_seen := false,
4784 handover_done := false,
4785 old_chan_nr := -
4786 };
4787 /* issue hand-over command on VTY */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004788 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01004789 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
4790 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004791
4792 /* From the MGW perspective, a handover is is characterized by
4793 * performing one MDCX operation with the MGW. So we expect to see
4794 * one more MDCX during handover. */
4795 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
4796
Harald Welte261af4b2018-02-12 21:20:39 +01004797 alt {
4798 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01004799 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004800
Philipp Maier4dae0652018-11-12 12:03:26 +01004801 /* Since this is an internal handover we expect the BSC to inform the
4802 * MSC about the event */
4803 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
4804
Philipp Maier3e2af5d2018-07-11 17:01:05 +02004805 /* Check the amount of MGCP transactions is still consistant with the
4806 * test expectation */
4807 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02004808
4809 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
4810 * g_chan_nr to the new lchan that was handed over to. It lives in bts 1, so look it up at RSL1_PROC. */
4811 f_verify_encr_info(f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr));
4812
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01004813 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01004814}
4815
4816testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02004817 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01004818 var MSC_ConnHdlr vc_conn;
4819 f_init(2, true);
4820 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004821
4822 f_ctrs_bsc_and_bts_init();
4823
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02004824 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01004825 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00004826
4827 /* from f_establish_fully() */
4828 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4829 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4830 /* from handover */
4831 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4832 f_ctrs_bsc_and_bts_add(0, "handover:completed");
4833 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
4834 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
4835 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004836 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01004837}
Harald Weltee9e02e42018-01-31 23:36:25 +01004838
Oliver Smith7eabd312021-07-12 14:18:56 +02004839function f_tc_ho_int_a5(OCT1 encr_alg, charstring enc_a5 := "0 1 3") runs on test_CT {
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02004840 var MSC_ConnHdlr vc_conn;
4841 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4842 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
4843
4844 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02004845 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02004846 f_sleep(1.0);
4847
4848 f_ctrs_bsc_and_bts_init();
4849
4850 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
4851 vc_conn.done;
4852
4853 /* from f_establish_fully() */
4854 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4855 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4856 /* from handover */
4857 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4858 f_ctrs_bsc_and_bts_add(0, "handover:completed");
4859 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
4860 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
4861 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02004862 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02004863 f_shutdown_helper();
4864}
4865
4866testcase TC_ho_int_a5_0() runs on test_CT {
4867 f_tc_ho_int_a5('01'O);
4868}
4869
4870testcase TC_ho_int_a5_1() runs on test_CT {
4871 f_tc_ho_int_a5('02'O);
4872}
4873
4874testcase TC_ho_int_a5_3() runs on test_CT {
4875 f_tc_ho_int_a5('08'O);
4876}
4877
4878testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02004879 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02004880}
4881
Neels Hofmeyr5f144212020-11-03 15:41:58 +00004882/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
4883private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
4884 g_pars := f_gen_test_hdlr_pars();
4885 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4886 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00004887
4888 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4889 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4890
4891 f_establish_fully(ass_cmd, exp_compl);
4892 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
4893
4894 var HandoverState hs := {
4895 rr_ho_cmpl_seen := false,
4896 handover_done := false,
4897 old_chan_nr := -
4898 };
4899 /* issue hand-over command on VTY */
4900 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
4901 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
4902 f_rslem_suspend(RSL1_PROC);
4903
4904 /* From the MGW perspective, a handover is is characterized by
4905 * performing one MDCX operation with the MGW. So we expect to see
4906 * one more MDCX during handover. */
4907 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
4908
4909 var RSL_Message rsl;
4910 var PDU_ML3_NW_MS l3;
4911 var RslChannelNr new_chan_nr;
4912 var GsmArfcn arfcn;
4913 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
4914 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
4915 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
4916 setverdict(fail, "Expected handoverCommand");
4917 mtc.stop;
4918 }
4919 }
4920 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
4921 new_chan_nr, arfcn);
4922
4923 f_rslem_register(0, new_chan_nr, RSL1_PROC);
4924
4925 /* resume processing of RSL DChan messages, which was temporarily suspended
4926 * before performing a hand-over */
4927 f_rslem_resume(RSL1_PROC);
4928 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
4929
4930 f_sleep(1.0);
4931
4932 /* Handover fails because no HANDO DET appears on the new lchan,
4933 * and the old lchan reports a Radio Link Failure. */
4934 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
4935
4936 var PDU_BSSAP rx_clear_request;
4937 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
4938 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
4939 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
4940
4941 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
4942
4943 var MgcpCommand mgcp;
4944 interleave {
4945 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
4946 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
4947 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
4948 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
4949 }
4950 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
4951 [] RSL1.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
4952 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
4953 }
4954 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
4955 }
4956
4957 f_sleep(0.5);
4958 setverdict(pass);
4959}
4960testcase TC_ho_int_radio_link_failure() runs on test_CT {
4961 var MSC_ConnHdlr vc_conn;
4962 f_init(2, true);
4963 f_sleep(1.0);
4964
4965 f_ctrs_bsc_and_bts_init();
4966
4967 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
4968 vc_conn.done;
4969
4970 /* from f_establish_fully() */
4971 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
4972 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
4973 /* from handover */
4974 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
4975 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
4976 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
4977 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
4978 f_ctrs_bsc_and_bts_verify();
4979 f_shutdown_helper();
4980}
4981
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004982/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02004983private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004984 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02004985 var template MgcpResponse mgcp_resp;
4986 var MGCP_RecvFrom mrf;
4987 var template MgcpMessage msg_resp;
4988 var template MgcpMessage msg_dlcx := {
4989 command := tr_DLCX()
4990 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004991
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02004992 if (g_pars.aoip) {
4993 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004994 log("Got first DLCX: ", mgcp);
4995 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02004996 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004997
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02004998 MGCP.receive(tr_DLCX()) -> value mgcp {
4999 log("Got second DLCX: ", mgcp);
5000 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5001 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005002 } else {
5003 /* For SCCPLite, BSC doesn't handle the MSC-side */
5004 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5005 log("Got first DLCX: ", mrf.msg.command);
5006 msg_resp := {
5007 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5008 }
5009 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5010 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005011 }
5012
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005013 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005014}
5015
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005016private 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 +01005017
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005018 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005019 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5020
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005021 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005022
5023 f_sleep(0.5);
5024 /* The MSC negotiates Handover Request and Handover Request Ack with
5025 * the other BSS and comes back with a BSSMAP Handover Command
5026 * containing an RR Handover Command coming from the target BSS... */
5027
5028 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5029 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5030 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5031 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5032 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5033
5034 /* expect the Handover Command to go out on RR */
5035 var RSL_Message rsl_ho_cmd
5036 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5037 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5038 var RSL_IE_Body rsl_ho_cmd_l3;
5039 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5040 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5041 setverdict(fail);
5042 } else {
5043 log("Found L3 Info: ", rsl_ho_cmd_l3);
5044 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5045 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5046 setverdict(fail);
5047 } else {
5048 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5049 setverdict(pass);
5050 }
5051 }
5052
5053 /* When the other BSS has reported a completed handover, this side is
5054 * torn down. */
5055
5056 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5057 var BssmapCause cause := enum2int(cause_val);
5058 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5059
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005060 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005061
5062 interleave {
5063 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5064 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5065 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
5066 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005067 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005068}
5069
5070private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5071 g_pars := f_gen_test_hdlr_pars();
5072 var PDU_BSSAP ass_req := f_gen_ass_req();
5073 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5074 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5075 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5076 f_establish_fully(ass_req, exp_compl);
5077
5078 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005079}
5080testcase TC_ho_out_of_this_bsc() runs on test_CT {
5081 var MSC_ConnHdlr vc_conn;
5082
5083 f_init(1, true);
5084 f_sleep(1.0);
5085
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005086 f_ctrs_bsc_and_bts_init();
5087
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005088 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5089 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005090
5091 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5092 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5093 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5094 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5095 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5096 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5097 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005098 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005099}
5100
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005101private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5102 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005103 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005104 octetstring l3 := '0123456789'O)
5105runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005106 /* The old lchan and conn should still be active. See that arbitrary L3
5107 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005108 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005109 var template PDU_BSSAP exp_data := {
5110 discriminator := '1'B,
5111 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005112 dlci := dlci,
5113 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005114 pdu := {
5115 dtap := l3
5116 }
5117 };
5118 BSSAP.receive(exp_data);
5119 setverdict(pass);
5120}
5121
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005122private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5123 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005124 template (value) OCT1 dlci := '00'O,
5125 octetstring l3 := '0123456789'O)
5126runs on MSC_ConnHdlr {
5127 BSSAP.send(PDU_BSSAP:{
5128 discriminator := '1'B,
5129 spare := '0000000'B,
5130 dlci := dlci,
5131 lengthIndicator := lengthof(l3),
5132 pdu := {
5133 dtap := l3
5134 }
5135 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005136 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005137 setverdict(pass);
5138}
5139
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005140/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5141 * simply never sends a BSSMAP Handover Command. */
5142private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005143 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005144
5145 var PDU_BSSAP ass_req := f_gen_ass_req();
5146 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5147 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5148 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5149 f_establish_fully(ass_req, exp_compl);
5150
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005151 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005152 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5153
5154 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5155
5156 /* osmo-bsc should time out 10 seconds after the handover started.
5157 * Let's give it a bit extra. */
5158 f_sleep(15.0);
5159
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005160 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005161 f_sleep(1.0);
5162}
5163testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5164 var MSC_ConnHdlr vc_conn;
5165
5166 f_init(1, true);
5167 f_sleep(1.0);
5168
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005169 f_ctrs_bsc_and_bts_init();
5170
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005171 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5172 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005173
5174 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5175 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5176 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5177 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5178 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5179 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5180 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005181 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005182}
5183
5184/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5185 * RR Handover Failure. */
5186private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005187 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005188
5189 var PDU_BSSAP ass_req := f_gen_ass_req();
5190 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5191 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5192 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5193 f_establish_fully(ass_req, exp_compl);
5194
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005195 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005196 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5197
5198 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5199
5200 f_sleep(0.5);
5201 /* The MSC negotiates Handover Request and Handover Request Ack with
5202 * the other BSS and comes back with a BSSMAP Handover Command
5203 * containing an RR Handover Command coming from the target BSS... */
5204
5205 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5206 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5207 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5208 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5209 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5210
5211 /* expect the Handover Command to go out on RR */
5212 var RSL_Message rsl_ho_cmd
5213 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5214 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5215 var RSL_IE_Body rsl_ho_cmd_l3;
5216 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5217 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5218 setverdict(fail);
5219 } else {
5220 log("Found L3 Info: ", rsl_ho_cmd_l3);
5221 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5222 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5223 setverdict(fail);
5224 } else {
5225 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5226 setverdict(pass);
5227 }
5228 }
5229
5230 f_sleep(0.2);
5231 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5232
5233 /* Should tell the MSC about the failure */
5234 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5235
5236 f_sleep(1.0);
5237
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005238 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005239 f_sleep(1.0);
5240
5241 setverdict(pass);
5242 f_sleep(1.0);
5243}
5244testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5245 var MSC_ConnHdlr vc_conn;
5246
5247 f_init(1, true);
5248 f_sleep(1.0);
5249
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005250 f_ctrs_bsc_and_bts_init();
5251
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005252 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5253 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005254
5255 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5256 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5257 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5258 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5259 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5260 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5261 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005262 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005263}
5264
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005265/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5266 * (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 +02005267 * and the lchan is released. */
5268private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005269 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005270
5271 var PDU_BSSAP ass_req := f_gen_ass_req();
5272 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5273 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5274 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5275 f_establish_fully(ass_req, exp_compl);
5276
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005277 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005278 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5279
5280 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5281
5282 f_sleep(0.5);
5283 /* The MSC negotiates Handover Request and Handover Request Ack with
5284 * the other BSS and comes back with a BSSMAP Handover Command
5285 * containing an RR Handover Command coming from the target BSS... */
5286
5287 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5288 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5289 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5290 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5291 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5292
5293 /* expect the Handover Command to go out on RR */
5294 var RSL_Message rsl_ho_cmd
5295 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5296 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5297 var RSL_IE_Body rsl_ho_cmd_l3;
5298 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5299 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5300 setverdict(fail);
5301 } else {
5302 log("Found L3 Info: ", rsl_ho_cmd_l3);
5303 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5304 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5305 setverdict(fail);
5306 } else {
5307 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5308 setverdict(pass);
5309 }
5310 }
5311
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005312 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5313 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5314 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005315
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005316 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005317 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5318 log("Got BSSMAP Clear Request");
5319 /* Instruct BSC to clear channel */
5320 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5321 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5322
5323 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005324 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005325 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5326 log("Got Deact SACCH");
5327 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005328 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005329 log("Got RR Release");
5330 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005331 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
5332 log("Got RF Chan Rel");
5333 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
5334 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005335 }
5336
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005337 f_expect_dlcx_conns();
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005338
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005339 setverdict(pass);
5340 f_sleep(1.0);
5341}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005342testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005343 var MSC_ConnHdlr vc_conn;
5344
5345 f_init(1, true);
5346 f_sleep(1.0);
5347
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005348 f_ctrs_bsc_and_bts_init();
5349
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005350 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005351 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005352
5353 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5354 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5355 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5356 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5357 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5358 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5359 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005360 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005361}
5362
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005363private 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 +01005364 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5365 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5366 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5367 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5368 * before we get started. */
5369 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5370 f_rslem_register(0, new_chan_nr);
5371 g_chan_nr := new_chan_nr;
5372 f_sleep(1.0);
5373
5374 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5375 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5376 activate(as_Media());
5377
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005378 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005379 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005380 oldToNewBSSIEs := oldToNewBSSIEs,
5381 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005382 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005383
5384 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5385
5386 var PDU_BSSAP rx_bssap;
5387 var octetstring ho_command_str;
5388
5389 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005390
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005391 /* we're sure that the channel activation is done now, verify the encryption parameters in it */
5392 f_verify_encr_info(f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr));
5393
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005394 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5395 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5396 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5397 log("L3 Info in HO Request Ack is ", ho_command);
5398
5399 var GsmArfcn arfcn;
5400 var RslChannelNr actual_new_chan_nr;
5401 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5402 actual_new_chan_nr, arfcn);
5403
5404 if (actual_new_chan_nr != new_chan_nr) {
5405 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5406 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5407 setverdict(fail);
5408 return;
5409 }
5410 log("Handover Command chan_nr is", actual_new_chan_nr);
5411
5412 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5413 * tells the MS to handover to the new lchan. Here comes the new MS on
5414 * the new lchan with a Handover RACH: */
5415
5416 /* send handover detect */
5417
5418 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5419
5420 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5421
5422 /* send handover complete over the new channel */
5423
5424 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5425 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5426 enc_PDU_ML3_MS_NW(l3_tx)));
5427
5428 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005429 setverdict(pass);
5430}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005431
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005432private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005433 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005434 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5435 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5436 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005437 }
5438 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005439 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005440 } else {
5441 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005442 }
5443 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005444 f_perform_clear(RSL, exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005445 setverdict(pass);
5446}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005447function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005448 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005449
5450 f_init(1, true);
5451 f_sleep(1.0);
5452
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005453 f_ctrs_bsc_and_bts_init();
5454
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005455 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5456 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005457
5458 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5459 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005460
5461 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5462 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5463 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5464 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5465 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005466}
5467
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005468testcase TC_ho_into_this_bsc() runs on test_CT {
5469 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5470 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005471 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005472}
5473
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005474function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5475 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5476 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5477 f_tc_ho_into_this_bsc_main(pars);
5478 f_shutdown_helper();
5479}
5480
5481testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5482 f_tc_ho_into_this_bsc_a5('01'O);
5483}
5484
5485testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5486 f_tc_ho_into_this_bsc_a5('02'O);
5487}
5488
5489testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5490 f_tc_ho_into_this_bsc_a5('08'O);
5491}
5492
5493testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5494 f_tc_ho_into_this_bsc_a5('10'O);
5495}
5496
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005497testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5498 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5499 pars.host_aoip_tla := "::6";
5500 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005501 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005502}
5503
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005504/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005505 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005506 channel is later released (RR CHannel Release), should trigger inclusion of
5507 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5508 neighbors. */
5509testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5510 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5511 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005512 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005513 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005514
5515 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5516 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5517 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005518 f_shutdown_helper();
5519}
5520
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005521/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5522 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5523 list when the channel is released. */
5524testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5525 f_init_vty();
5526 f_vty_allow_srvcc_fast_return(true, 0)
5527
5528 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5529 pars.last_used_eutran_plmn := '323454'O;
5530 pars.exp_fast_return := false;
5531 f_tc_ho_into_this_bsc_main(pars);
5532 f_vty_allow_srvcc_fast_return(false, 0);
5533 f_shutdown_helper();
5534}
5535
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005536private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5537 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5538 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5539 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5540 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5541 setverdict(pass);
5542}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005543
5544private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5545 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005546 var MSC_ConnHdlr vc_conn;
5547 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5548
5549 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005550 if (disable_fast_return) {
5551 f_vty_allow_srvcc_fast_return(true, 0);
5552 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005553 f_sleep(1.0);
5554
5555 f_ctrs_bsc_and_bts_init();
5556
5557 pars.last_used_eutran_plmn := '323454'O;
5558 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5559 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5560
5561 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5562 vc_conn.done;
5563
5564 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5565 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5566 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5567 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5568 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5569 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005570
5571 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5572 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005573 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005574
5575 if (disable_fast_return) {
5576 f_vty_allow_srvcc_fast_return(false, 0);
5577 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005578 f_shutdown_helper();
5579}
5580
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005581/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5582 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5583 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5584 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5585testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5586 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5587}
5588/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5589 * independently of fast-reture allowed/forbidden in local BTS */
5590testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5591 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5592}
5593
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005594private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5595 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5596 f_rslem_register(0, new_chan_nr);
5597 g_chan_nr := new_chan_nr;
5598 f_sleep(1.0);
5599
5600 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5601 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5602 activate(as_Media());
5603
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005604 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005605 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005606 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005607
5608 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5609
5610 var PDU_BSSAP rx_bssap;
5611 var octetstring ho_command_str;
5612
5613 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5614
5615 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5616 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5617 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5618 log("L3 Info in HO Request Ack is ", ho_command);
5619
5620 var GsmArfcn arfcn;
5621 var RslChannelNr actual_new_chan_nr;
5622 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5623 actual_new_chan_nr, arfcn);
5624
5625 if (actual_new_chan_nr != new_chan_nr) {
5626 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5627 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5628 setverdict(fail);
5629 return;
5630 }
5631 log("Handover Command chan_nr is", actual_new_chan_nr);
5632
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005633 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5634 f_sleep(1.0);
5635
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005636 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5637 * tells the MS to handover to the new lchan. In this case, the MS
5638 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5639 * Handover Failure to the MSC. The procedure according to 3GPP TS
5640 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5641 * BSSMAP Clear Command: */
5642
5643 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5644 var BssmapCause cause := enum2int(cause_val);
5645 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5646
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005647 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005648 setverdict(pass);
5649 f_sleep(1.0);
5650
5651 setverdict(pass);
5652}
5653testcase TC_ho_in_fail_msc_clears() runs on test_CT {
5654 var MSC_ConnHdlr vc_conn;
5655 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5656
5657 f_init(1, true);
5658 f_sleep(1.0);
5659
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005660 f_ctrs_bsc_and_bts_init();
5661
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005662 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5663 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005664
5665 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
5666 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005667
5668 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5669 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5670 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5671 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5672 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005673 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005674}
5675
5676private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
5677 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5678 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5679 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5680 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5681 * before we get started. */
5682 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5683 f_rslem_register(0, new_chan_nr);
5684 g_chan_nr := new_chan_nr;
5685 f_sleep(1.0);
5686
5687 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5688 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5689 activate(as_Media());
5690
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005691 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005692 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005693 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005694
5695 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5696
5697 var PDU_BSSAP rx_bssap;
5698 var octetstring ho_command_str;
5699
5700 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5701
5702 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5703 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5704 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5705 log("L3 Info in HO Request Ack is ", ho_command);
5706
5707 var GsmArfcn arfcn;
5708 var RslChannelNr actual_new_chan_nr;
5709 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5710 actual_new_chan_nr, arfcn);
5711
5712 if (actual_new_chan_nr != new_chan_nr) {
5713 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5714 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5715 setverdict(fail);
5716 return;
5717 }
5718 log("Handover Command chan_nr is", actual_new_chan_nr);
5719
5720 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5721 * tells the MS to handover to the new lchan. Here comes the new MS on
5722 * the new lchan with a Handover RACH: */
5723
5724 /* send handover detect */
5725
5726 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5727
5728 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5729
5730 /* The MSC chooses to clear the connection now, maybe we got the
5731 * Handover RACH on the new cell but the MS still signaled Handover
5732 * Failure to the old BSS? */
5733
5734 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5735 var BssmapCause cause := enum2int(cause_val);
5736 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5737
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005738 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005739 f_sleep(1.0);
5740}
5741testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
5742 var MSC_ConnHdlr vc_conn;
5743 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5744
5745 f_init(1, true);
5746 f_sleep(1.0);
5747
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005748 f_ctrs_bsc_and_bts_init();
5749
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005750 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5751 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005752
5753 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
5754 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005755
5756 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5757 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5758 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5759 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5760 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005761 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005762}
5763
5764/* The new BSS's lchan times out before the MSC decides that handover failed. */
5765private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
5766 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5767 f_rslem_register(0, new_chan_nr);
5768 g_chan_nr := new_chan_nr;
5769 f_sleep(1.0);
5770
5771 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5772 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5773 activate(as_Media());
5774
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005775 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005776 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005777 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005778
5779 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5780
5781 var PDU_BSSAP rx_bssap;
5782 var octetstring ho_command_str;
5783
5784 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5785
5786 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5787 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5788 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5789 log("L3 Info in HO Request Ack is ", ho_command);
5790
5791 var GsmArfcn arfcn;
5792 var RslChannelNr actual_new_chan_nr;
5793 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5794 actual_new_chan_nr, arfcn);
5795
5796 if (actual_new_chan_nr != new_chan_nr) {
5797 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5798 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5799 setverdict(fail);
5800 return;
5801 }
5802 log("Handover Command chan_nr is", actual_new_chan_nr);
5803
5804 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5805 * tells the MS to handover to the new lchan. But the MS never shows up
5806 * on the new lchan. */
5807
5808 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5809
5810 /* Did osmo-bsc also send a Clear Request? */
5811 timer T := 0.5;
5812 T.start;
5813 alt {
5814 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
5815 [] T.timeout { }
5816 }
5817
5818 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
5819 * asked for it, this is a Handover Failure after all). */
5820
5821 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5822 var BssmapCause cause := enum2int(cause_val);
5823 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5824
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005825 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005826 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005827}
5828testcase TC_ho_in_fail_no_detect() runs on test_CT {
5829 var MSC_ConnHdlr vc_conn;
5830 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5831
5832 f_init(1, true);
5833 f_sleep(1.0);
5834
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005835 f_ctrs_bsc_and_bts_init();
5836
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005837 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5838 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005839
5840 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
5841 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005842
5843 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5844 f_ctrs_bsc_and_bts_add(0, "handover:error");
5845 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5846 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
5847 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005848 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005849}
5850
5851/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
5852private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
5853 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5854 f_rslem_register(0, new_chan_nr);
5855 g_chan_nr := new_chan_nr;
5856 f_sleep(1.0);
5857
5858 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5859 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5860 activate(as_Media());
5861
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005862 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005863 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005864 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005865
5866 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5867
5868 var PDU_BSSAP rx_bssap;
5869 var octetstring ho_command_str;
5870
5871 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5872
5873 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5874 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5875 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5876 log("L3 Info in HO Request Ack is ", ho_command);
5877
5878 var GsmArfcn arfcn;
5879 var RslChannelNr actual_new_chan_nr;
5880 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5881 actual_new_chan_nr, arfcn);
5882
5883 if (actual_new_chan_nr != new_chan_nr) {
5884 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5885 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5886 setverdict(fail);
5887 return;
5888 }
5889 log("Handover Command chan_nr is", actual_new_chan_nr);
5890
5891 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5892 * tells the MS to handover to the new lchan. But the MS never shows up
5893 * on the new lchan. */
5894
5895 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5896
5897 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005898 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005899
5900 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005901 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5902 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5903 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005904 f_expect_dlcx_conns();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005905 f_sleep(1.0);
5906}
5907testcase TC_ho_in_fail_no_detect2() runs on test_CT {
5908 var MSC_ConnHdlr vc_conn;
5909 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5910
5911 f_init(1, true);
5912 f_sleep(1.0);
5913
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005914 f_ctrs_bsc_and_bts_init();
5915
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005916 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5917 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005918
5919 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
5920 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005921
5922 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5923 f_ctrs_bsc_and_bts_add(0, "handover:error");
5924 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5925 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
5926 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005927 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005928}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005929
Neels Hofmeyr91401012019-07-11 00:42:35 +02005930type record of charstring Commands;
5931
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005932private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02005933{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005934 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02005935 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005936 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02005937 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005938 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02005939}
5940
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01005941private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
5942{
5943 f_vty_enter_cfg_cs7_inst(pt, 0);
5944 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
5945 f_vty_transceive(pt, cmds[i]);
5946 }
5947 f_vty_transceive(pt, "end");
5948}
5949
Neels Hofmeyr91401012019-07-11 00:42:35 +02005950private function f_probe_for_handover(charstring log_label,
5951 charstring log_descr,
5952 charstring handover_vty_cmd,
5953 boolean expect_handover,
5954 boolean is_inter_bsc_handover := false)
5955runs on MSC_ConnHdlr
5956{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02005957 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
5958 * lchans to be established on bts 1 or bts 2. */
5959 f_rslem_suspend(RSL1_PROC);
5960 f_rslem_suspend(RSL2_PROC);
5961
Neels Hofmeyr91401012019-07-11 00:42:35 +02005962 var RSL_Message rsl;
5963
5964 var charstring log_msg := " (expecting handover)"
5965 if (not expect_handover) {
5966 log_msg := " (expecting NO handover)";
5967 }
5968 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
5969 f_vty_transceive(BSCVTY, handover_vty_cmd);
5970
Neels Hofmeyr91401012019-07-11 00:42:35 +02005971 timer T := 2.0;
5972 T.start;
5973
5974 alt {
5975 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5976 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5977 log("Rx L3 from net: ", l3);
5978 if (ischosen(l3.msgs.rrm.handoverCommand)) {
5979 var RslChannelNr new_chan_nr;
5980 var GsmArfcn arfcn;
5981 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5982 new_chan_nr, arfcn);
5983 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
5984 log(l3.msgs.rrm.handoverCommand);
5985
5986 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
5987 * matter on which BTS it really is, we're not going to follow through an entire handover
5988 * anyway. */
5989 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5990 f_rslem_resume(RSL1_PROC);
5991 f_rslem_register(0, new_chan_nr, RSL2_PROC);
5992 f_rslem_resume(RSL2_PROC);
5993
5994 if (expect_handover and not is_inter_bsc_handover) {
5995 setverdict(pass);
5996 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
5997 } else {
5998 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
5999 & log_label & ": " & log_descr);
6000 }
6001
6002 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6003 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6004 * Handover Failure. */
6005 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6006
6007 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6008 f_sleep(0.5);
6009 RSL1.clear;
6010 RSL2.clear;
6011 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6012 break;
6013 } else {
6014 repeat;
6015 }
6016 }
6017 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6018 if (expect_handover and is_inter_bsc_handover) {
6019 setverdict(pass);
6020 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6021 } else {
6022 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6023 & log_label & ": " & log_descr);
6024 }
6025
6026 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6027
6028 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6029 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6030 * setting a short timeout and waiting is the only way. */
6031 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6032 f_sleep(1.5);
6033 log("f_probe_for_handover(" & log_label & "): ...done");
6034
6035 break;
6036 }
6037 [] T.timeout {
6038 if (expect_handover) {
6039 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6040 & log_label & ": " & log_descr);
6041 } else {
6042 setverdict(pass);
6043 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6044 }
6045 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6046 break;
6047 }
6048 }
6049
6050 f_rslem_resume(RSL1_PROC);
6051 f_rslem_resume(RSL2_PROC);
6052 f_sleep(3.0);
6053 RSL.clear;
6054
6055 log("f_probe_for_handover(" & log_label & "): done clearing");
6056}
6057
6058/* Test the effect of various neighbor configuration scenarios:
6059 *
6060 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6061 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6062 */
6063private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6064 g_pars := f_gen_test_hdlr_pars();
6065 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6066 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006067
6068 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6069 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6070
6071 /* Establish lchan at bts 0 */
6072 f_establish_fully(ass_cmd, exp_compl);
6073
6074 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6075 f_vty_enter_cfg_network(BSCVTY);
6076 f_vty_transceive(BSCVTY, "timer T7 1");
6077 f_vty_transceive(BSCVTY, "end");
6078}
6079
6080private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6081 f_tc_ho_neighbor_config_start();
6082
6083 /*
6084 * bts 0 ARFCN 871 BSIC 10
6085 * bts 1 ARFCN 871 BSIC 11
6086 * bts 2 ARFCN 871 BSIC 12
6087 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6088 */
6089
6090 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006091 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006092 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6093 "handover any to arfcn 871 bsic 11",
6094 true);
6095
6096 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6097 "handover any to arfcn 13 bsic 39",
6098 false);
6099
6100 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6101 "handover any to arfcn 871 bsic 12",
6102 false);
6103
6104 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6105 "handover any to arfcn 871 bsic 11",
6106 true);
6107}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006108testcase TC_ho_neighbor_config_1() runs on test_CT {
6109 var MSC_ConnHdlr vc_conn;
6110 f_init(3, true, guard_timeout := 60.0);
6111 f_sleep(1.0);
6112 f_ctrs_bsc_and_bts_init();
6113 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6114 vc_conn.done;
6115
6116 /* f_tc_ho_neighbor_config_start() */
6117 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6118 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6119
6120 /* 1.a */
6121 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6122 * handover quickly by sending a Handover Failure message. */
6123 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6124 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6125 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6126 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6127
6128 /* 1.b */
6129 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6130 f_ctrs_bsc_and_bts_add(0, "handover:error");
6131
6132 /* 1.c */
6133 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6134 f_ctrs_bsc_and_bts_add(0, "handover:error");
6135
6136 /* 1.d */
6137 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6138 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6139 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6140 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6141
6142 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006143 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006144}
6145
Neels Hofmeyr91401012019-07-11 00:42:35 +02006146private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6147 f_tc_ho_neighbor_config_start();
6148
6149 /*
6150 * bts 0 ARFCN 871 BSIC 10
6151 * bts 1 ARFCN 871 BSIC 11
6152 * bts 2 ARFCN 871 BSIC 12
6153 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6154 */
6155
6156 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006157 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006158 f_sleep(0.5);
6159
6160 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6161 "handover any to arfcn 871 bsic 11",
6162 true);
6163
6164 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6165 "handover any to arfcn 871 bsic 12",
6166 false);
6167}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006168testcase TC_ho_neighbor_config_2() runs on test_CT {
6169 var MSC_ConnHdlr vc_conn;
6170 f_init(3, true, guard_timeout := 50.0);
6171 f_sleep(1.0);
6172 f_ctrs_bsc_and_bts_init();
6173 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6174 vc_conn.done;
6175
6176 /* f_tc_ho_neighbor_config_start() */
6177 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6178 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6179
6180 /* 2.a */
6181 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6182 * handover quickly by sending a Handover Failure message. */
6183 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6184 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6185 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6186 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6187
6188 /* 2.b */
6189 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6190 f_ctrs_bsc_and_bts_add(0, "handover:error");
6191
6192 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006193 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006194}
6195
Neels Hofmeyr91401012019-07-11 00:42:35 +02006196private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6197 f_tc_ho_neighbor_config_start();
6198
6199 /*
6200 * bts 0 ARFCN 871 BSIC 10
6201 * bts 1 ARFCN 871 BSIC 11
6202 * bts 2 ARFCN 871 BSIC 12
6203 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6204 */
6205
6206 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006207 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006208 f_sleep(0.5);
6209
6210 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6211 "handover any to arfcn 871 bsic 11",
6212 false);
6213 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",
6214 "handover any to arfcn 871 bsic 12",
6215 true);
6216}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006217testcase TC_ho_neighbor_config_3() runs on test_CT {
6218 var MSC_ConnHdlr vc_conn;
6219 f_init(3, true, guard_timeout := 50.0);
6220 f_sleep(1.0);
6221 f_ctrs_bsc_and_bts_init();
6222 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6223 vc_conn.done;
6224
6225 /* f_tc_ho_neighbor_config_start() */
6226 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6227 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6228
6229 /* 3.a */
6230 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6231 f_ctrs_bsc_and_bts_add(0, "handover:error");
6232
6233 /* 3.b */
6234 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6235 * handover quickly by sending a Handover Failure message. */
6236 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6237 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6238 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6239 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6240
6241 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006242 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006243}
6244
Neels Hofmeyr91401012019-07-11 00:42:35 +02006245private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6246 f_tc_ho_neighbor_config_start();
6247
6248 /*
6249 * bts 0 ARFCN 871 BSIC 10
6250 * bts 1 ARFCN 871 BSIC 11
6251 * bts 2 ARFCN 871 BSIC 12
6252 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6253 */
6254
6255 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006256 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006257 f_sleep(0.5);
6258
6259 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6260 "handover any to arfcn 871 bsic 11",
6261 false);
6262 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6263 "handover any to arfcn 871 bsic 12",
6264 false);
6265 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6266 "handover any to arfcn 123 bsic 45",
6267 true, true);
6268}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006269testcase TC_ho_neighbor_config_4() runs on test_CT {
6270 var MSC_ConnHdlr vc_conn;
6271 f_init(3, true, guard_timeout := 50.0);
6272 f_sleep(1.0);
6273 f_ctrs_bsc_and_bts_init();
6274 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6275 vc_conn.done;
6276
6277 /* f_tc_ho_neighbor_config_start() */
6278 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6279 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6280
6281 /* 4.a */
6282 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6283 f_ctrs_bsc_and_bts_add(0, "handover:error");
6284
6285 /* 4.b */
6286 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6287 f_ctrs_bsc_and_bts_add(0, "handover:error");
6288
6289 /* 4.c */
6290 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6291 * handover quickly by timing out after the Handover Required message */
6292 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6293 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6294 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6295 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6296
6297 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006298 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006299}
6300
Neels Hofmeyr91401012019-07-11 00:42:35 +02006301private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6302 f_tc_ho_neighbor_config_start();
6303
6304 /*
6305 * bts 0 ARFCN 871 BSIC 10
6306 * bts 1 ARFCN 871 BSIC 11
6307 * bts 2 ARFCN 871 BSIC 12
6308 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6309 */
6310
6311 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 +02006312 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006313 f_sleep(0.5);
6314
6315 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6316 "handover any to arfcn 871 bsic 12",
6317 true, true);
6318}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006319testcase TC_ho_neighbor_config_5() runs on test_CT {
6320 var MSC_ConnHdlr vc_conn;
6321 f_init(3, true);
6322 f_sleep(1.0);
6323 f_ctrs_bsc_and_bts_init();
6324 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6325 vc_conn.done;
6326
6327 /* f_tc_ho_neighbor_config_start() */
6328 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6329 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6330
6331 /* 5 */
6332 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6333 * handover quickly by timing out after the Handover Required message */
6334 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6335 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6336 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6337 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6338
6339 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006340 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006341}
6342
Neels Hofmeyr91401012019-07-11 00:42:35 +02006343private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6344 f_tc_ho_neighbor_config_start();
6345
6346 /*
6347 * bts 0 ARFCN 871 BSIC 10
6348 * bts 1 ARFCN 871 BSIC 11
6349 * bts 2 ARFCN 871 BSIC 12
6350 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6351 */
6352
6353 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6354 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006355 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006356 f_sleep(0.5);
6357
6358 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6359 "handover any to arfcn 871 bsic 12",
6360 false);
6361}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006362testcase TC_ho_neighbor_config_6() runs on test_CT {
6363 var MSC_ConnHdlr vc_conn;
6364 f_init(3, true);
6365 f_sleep(1.0);
6366 f_ctrs_bsc_and_bts_init();
6367 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6368 vc_conn.done;
6369
6370 /* f_tc_ho_neighbor_config_start() */
6371 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6372 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6373
6374 /* 6.a */
6375 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6376 * handover quickly by timing out after the Handover Required message */
6377 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6378 f_ctrs_bsc_and_bts_add(0, "handover:error");
6379
6380 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006381 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006382}
6383
Neels Hofmeyr91401012019-07-11 00:42:35 +02006384private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6385 f_tc_ho_neighbor_config_start();
6386
6387 /*
6388 * bts 0 ARFCN 871 BSIC 10
6389 * bts 1 ARFCN 871 BSIC 11
6390 * bts 2 ARFCN 871 BSIC 12
6391 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6392 */
6393
6394 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6395 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006396 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006397 f_sleep(0.5);
6398
6399 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6400 "handover any to arfcn 871 bsic 12",
6401 true);
6402 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6403 "handover any to arfcn 123 bsic 45",
6404 true, true);
6405}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006406testcase TC_ho_neighbor_config_7() runs on test_CT {
6407 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006408 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006409 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006410 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006411 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6412 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006413
6414 /* f_tc_ho_neighbor_config_start() */
6415 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6416 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6417
6418 /* 7.a */
6419 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6420 * handover quickly by sending a Handover Failure message. */
6421 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6422 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6423 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6424 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6425
6426 /* 7.b */
6427 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6428 * handover quickly by timing out after the Handover Required message */
6429 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6430 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6431 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6432 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6433
6434 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006435 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006436}
6437
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006438/* OS#3041: Open and close N connections in a normal fashion, and expect no
6439 * BSSMAP Reset just because of that. */
6440testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6441 var default d;
6442 var integer i;
6443 var DchanTuple dt;
6444
6445 f_init();
6446
6447 /* Wait for initial BSSMAP Reset to pass */
6448 f_sleep(4.0);
6449
6450 d := activate(no_bssmap_reset());
6451
6452 /* Setup up a number of connections and RLSD them again from the MSC
6453 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6454 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006455 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006456 /* Since we're doing a lot of runs, give each one a fresh
6457 * T_guard from the top. */
6458 T_guard.start;
6459
6460 /* Setup a BSSAP connection and clear it right away. This is
6461 * the MSC telling the BSC about a planned release, it's not an
6462 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006463 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006464
6465 /* MSC disconnects (RLSD). */
6466 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6467 }
6468
6469 /* In the buggy behavior, a timeout of 2 seconds happens between above
6470 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6471 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6472 f_sleep(4.0);
6473
6474 deactivate(d);
6475 f_shutdown_helper();
6476}
Harald Welte552620d2017-12-16 23:21:36 +01006477
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006478/* OS#3041: Open and close N connections in a normal fashion, and expect no
6479 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6480 * the MSC. */
6481testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6482 var default d;
6483 var integer i;
6484 var DchanTuple dt;
6485 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006486 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6487 var BssmapCause cause := enum2int(cause_val);
6488
6489 f_init();
6490
6491 /* Wait for initial BSSMAP Reset to pass */
6492 f_sleep(4.0);
6493
6494 d := activate(no_bssmap_reset());
6495
6496 /* Setup up a number of connections and RLSD them again from the MSC
6497 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6498 * Let's do it some more times for good measure. */
6499 for (i := 0; i < 8; i := i+1) {
6500 /* Since we're doing a lot of runs, give each one a fresh
6501 * T_guard from the top. */
6502 T_guard.start;
6503
6504 /* Setup a BSSAP connection and clear it right away. This is
6505 * the MSC telling the BSC about a planned release, it's not an
6506 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006507 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006508
6509 /* Instruct BSC to clear channel */
6510 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6511
6512 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006513 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006514 }
6515
6516 /* In the buggy behavior, a timeout of 2 seconds happens between above
6517 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6518 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6519 f_sleep(4.0);
6520
6521 deactivate(d);
6522 f_shutdown_helper();
6523}
6524
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006525/* OS#3041: Open and close N connections in a normal fashion, and expect no
6526 * BSSMAP Reset just because of that. Close connections from the MS side with a
6527 * Release Ind on RSL. */
6528testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6529 var default d;
6530 var integer i;
6531 var DchanTuple dt;
6532 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006533 var integer j;
6534
6535 f_init();
6536
6537 /* Wait for initial BSSMAP Reset to pass */
6538 f_sleep(4.0);
6539
6540 d := activate(no_bssmap_reset());
6541
6542 /* Setup up a number of connections and RLSD them again from the MSC
6543 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6544 * Let's do it some more times for good measure. */
6545 for (i := 0; i < 8; i := i+1) {
6546 /* Since we're doing a lot of runs, give each one a fresh
6547 * T_guard from the top. */
6548 T_guard.start;
6549
6550 /* Setup a BSSAP connection and clear it right away. This is
6551 * the MSC telling the BSC about a planned release, it's not an
6552 * erratic loss of a connection. */
6553 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6554
6555 /* simulate RLL REL IND */
6556 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6557
6558 /* expect Clear Request on MSC side */
6559 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6560
6561 /* Instruct BSC to clear channel */
6562 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6563 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6564
6565 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006566 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006567 }
6568
6569 /* In the buggy behavior, a timeout of 2 seconds happens between above
6570 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6571 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6572 f_sleep(4.0);
6573
6574 deactivate(d);
6575 f_shutdown_helper();
6576}
6577
Harald Welte94e0c342018-04-07 11:33:23 +02006578/***********************************************************************
6579 * IPA style dynamic PDCH
6580 ***********************************************************************/
6581
6582private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6583 template (omit) RSL_Cause nack := omit)
6584runs on test_CT {
6585 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6586 var RSL_Message rsl_unused;
6587 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6588 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6589 /* expect the BSC to issue the related RSL command */
6590 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6591 if (istemplatekind(nack, "omit")) {
6592 /* respond with a related acknowledgement */
6593 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6594 } else {
6595 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6596 }
6597}
6598
6599private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6600 template (omit) RSL_Cause nack := omit)
6601runs on test_CT {
6602 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6603 var RSL_Message rsl_unused;
6604 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6605 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6606 /* expect the BSC to issue the related RSL command */
6607 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6608 if (istemplatekind(nack, "omit")) {
6609 /* respond with a related acknowledgement */
6610 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6611 } else {
6612 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6613 }
6614}
6615
6616private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6617runs on test_CT return charstring {
6618 var charstring cmd, resp;
6619 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006620 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006621}
6622
6623private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6624 template charstring exp)
6625runs on test_CT {
6626 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
6627 if (not match(mode, exp)) {
6628 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02006629 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02006630 }
6631}
6632
6633private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
6634runs on test_CT {
6635 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
6636 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
6637 f_vty_transceive(BSCVTY, "end");
6638}
6639
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02006640
6641private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
6642 var integer i;
6643 for (i := 0; i < 8; i := i + 1) {
6644 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
6645 }
6646}
6647
Harald Welte94e0c342018-04-07 11:33:23 +02006648private const charstring TCHF_MODE := "TCH/F mode";
6649private const charstring TCHH_MODE := "TCH/H mode";
6650private const charstring PDCH_MODE := "PDCH mode";
6651private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02006652private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02006653
6654/* Test IPA PDCH activation / deactivation triggered by VTY */
6655testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
6656 var RSL_Message rsl_unused;
6657
6658 /* change Timeslot 6 before f_init() starts RSL */
6659 f_init_vty();
6660 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6661 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6662
6663 f_init(1, false);
6664 f_sleep(1.0);
6665
6666 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6667
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006668 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006669 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6670 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6671 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6672 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6673 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006674 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006675 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6676
6677 /* De-activate it via VTY */
6678 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6679 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006680 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006681 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6682
6683 /* re-activate it via VTY */
6684 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
6685 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006686 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006687 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6688
6689 /* and finally de-activate it again */
6690 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6691 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006692 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006693 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6694
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006695 /* clean up config */
6696 f_ts_set_chcomb(0, 0, 6, "PDCH");
6697
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006698 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006699}
6700
6701/* Test IPA PDCH activation NACK */
6702testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
6703 var RSL_Message rsl_unused;
6704
6705 /* change Timeslot 6 before f_init() starts RSL */
6706 f_init_vty();
6707 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6708 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6709
6710 f_init(1, false);
6711 f_sleep(1.0);
6712
6713 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6714
6715 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6716 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6717 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6718 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6719 f_sleep(1.0);
6720 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6721
6722 /* De-activate it via VTY */
6723 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6724 f_sleep(1.0);
6725 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6726
6727 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
6728 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
6729 f_sleep(1.0);
6730 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6731
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006732 /* clean up config */
6733 f_ts_set_chcomb(0, 0, 6, "PDCH");
6734
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006735 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006736}
6737
6738
6739/***********************************************************************
6740 * Osmocom style dynamic PDCH
6741 ***********************************************************************/
6742
6743private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6744 template (omit) RSL_Cause nack := omit)
6745runs on test_CT {
6746 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6747 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02006748 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02006749 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6750 /* expect the BSC to issue the related RSL command */
6751 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
6752 if (istemplatekind(nack, "omit")) {
6753 /* respond with a related acknowledgement */
6754 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
6755 } else {
6756 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
6757 }
6758}
6759
6760private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6761 template (omit) RSL_Cause nack := omit)
6762runs on test_CT {
6763 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
6764 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02006765 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02006766 /* FIXME: no VTY command to activate Osmocom PDCH !! */
6767 /* expect the BSC to issue the related RSL command */
6768 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
6769 if (istemplatekind(nack, "omit")) {
6770 /* respond with a related acknowledgement */
6771 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
6772 } else {
6773 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
6774 }
6775}
6776
6777/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
6778testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
6779 var RSL_Message rsl_unused;
6780
6781 /* change Timeslot 6 before f_init() starts RSL */
6782 f_init_vty();
6783 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
6784 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6785
6786 f_init(1, false);
6787 f_sleep(1.0);
6788
6789 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
6790
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006791 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006792 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6793 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6794 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
6795
6796 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
6797 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006798 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 +02006799 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6800
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006801 /* clean up config */
6802 f_ts_set_chcomb(0, 0, 6, "PDCH");
6803
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006804 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006805}
6806
6807/* Test Osmocom dyn PDCH activation NACK behavior */
6808testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
6809 var RSL_Message rsl_unused;
6810
6811 /* change Timeslot 6 before f_init() starts RSL */
6812 f_init_vty();
6813 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
6814 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6815
6816 f_init(1, false);
6817 f_sleep(1.0);
6818
6819 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
6820
6821 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6822 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6823 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
6824
6825 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
6826 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
6827 f_sleep(1.0);
6828 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
6829
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006830 /* clean up config */
6831 f_ts_set_chcomb(0, 0, 6, "PDCH");
6832
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006833 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006834}
6835
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02006836/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
6837testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
6838 var RSL_Message rsl_unused, rsl_msg;
6839 var DchanTuple dt;
6840 var BSSAP_N_CONNECT_ind rx_c_ind;
6841
6842 /* change Timeslot 6 before f_init() starts RSL */
6843 f_init_vty();
6844 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
6845 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6846
6847 f_init(1, false);
6848 f_sleep(1.0);
6849
6850 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
6851
6852 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
6853 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
6854 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6855 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
6856
6857 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
6858 f_sleep(1.0);
6859 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
6860 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
6861
6862 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
6863 * on CCCH+SDCCH4+CBCH) */
6864 var integer i;
6865 for (i := 0; i < 3; i := i + 1) {
6866 dt := f_est_dchan('23'O, i, '00010203040506'O);
6867 }
6868
6869 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
6870 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
6871 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
6872 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
6873
6874 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
6875 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
6876
6877 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
6878 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
6879 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
6880 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
6881
6882 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
6883 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
6884 dt.sccp_conn_id := rx_c_ind.connectionId;
6885 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
6886
6887 /* Instruct BSC to clear channel */
6888 var BssmapCause cause := 0;
6889 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6890 f_exp_chan_rel_and_clear(dt, 0);
6891
6892 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
6893 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
6894 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
6895 f_sleep(1.0);
6896 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
6897
6898 /* clean up config */
6899 f_ts_set_chcomb(0, 0, 6, "PDCH");
6900
6901 f_shutdown_helper();
6902}
6903
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02006904/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
6905 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
6906 it as TCH directly instead. SYS#5309. */
6907testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
6908 var RSL_Message rsl_unused, rsl_msg;
6909 var DchanTuple dt;
6910 var BSSAP_N_CONNECT_ind rx_c_ind;
6911 var integer i;
6912
6913 /* change Timeslot 6 before f_init() starts RSL */
6914 f_init_vty();
6915 for (i := 1; i < 8; i := i + 1) {
6916 if (i == 6) {
6917 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
6918 } else {
6919 f_ts_set_chcomb(0, 0, i, "PDCH");
6920 }
6921 }
6922 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6923
6924 f_init(1, false);
6925 f_sleep(1.0);
6926
6927 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
6928
6929 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
6930 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
6931 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6932 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
6933
6934 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
6935 f_sleep(1.0);
6936 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
6937 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
6938
6939 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
6940 * on CCCH+SDCCH4+CBCH) */
6941 for (i := 0; i < 3; i := i + 1) {
6942 dt := f_est_dchan('23'O, i, '00010203040506'O);
6943 }
6944
6945 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
6946 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
6947 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
6948 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
6949
6950 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
6951 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
6952
6953 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
6954 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
6955 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
6956 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
6957
6958 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
6959 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
6960 dt.sccp_conn_id := rx_c_ind.connectionId;
6961 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
6962
6963 /* Instruct BSC to clear channel */
6964 var BssmapCause cause := 0;
6965 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6966 f_exp_chan_rel_and_clear(dt, 0);
6967
6968 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
6969 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
6970 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
6971 f_sleep(1.0);
6972 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
6973
6974 /* clean up config */
6975 f_ts_reset_chcomb(0);
6976 /* TODO: clean up other channels? */
6977
6978 f_shutdown_helper();
6979}
6980
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02006981/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
6982testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
6983 var RSL_Message rsl_unused, rsl_msg;
6984 var DchanTuple dt;
6985 var BSSAP_N_CONNECT_ind rx_c_ind;
6986 var GsmRrMessage rr;
6987
6988 /* change Timeslot 6 before f_init() starts RSL */
6989 f_init_vty();
6990 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
6991 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6992
6993 f_init(1, false);
6994 f_sleep(1.0);
6995
6996 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
6997
6998 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
6999 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7000 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7001 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7002
7003 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7004 f_sleep(1.0);
7005 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7006 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7007
7008 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7009 * on CCCH+SDCCH4+CBCH) */
7010 var integer i;
7011 for (i := 0; i < 3; i := i + 1) {
7012 dt := f_est_dchan('23'O, i, '00010203040506'O);
7013 }
7014
7015 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7016 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7017 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7018 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7019
7020 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7021 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7022
7023 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7024 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7025 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7026 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7027 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7028 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7029 }
7030
7031 /* FIXME? Currently the TS stays in state BORKEN: */
7032
7033 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7034 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7035 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7036 * f_sleep(1.0);
7037 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7038 */
7039
7040 /* clean up config */
7041 f_ts_set_chcomb(0, 0, 6, "PDCH");
7042
7043 f_shutdown_helper();
7044}
7045
Stefan Sperling0796a822018-10-05 13:01:39 +02007046testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007047 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007048 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7049 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7050 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007051 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007052}
7053
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007054testcase TC_chopped_ipa_payload() runs on test_CT {
7055 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7056 /* TODO: mp_bsc_ctrl_port does not work yet */};
7057 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7058 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7059 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007060 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007061}
7062
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007063/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7064 the BTS does autonomous MS power control loop */
7065testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7066 var MSC_ConnHdlr vc_conn;
7067 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7068 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7069 pars.exp_ms_power_params := true;
7070
7071 f_init(1, true);
7072 f_sleep(1.0);
7073 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7074 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007075 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007076}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007077
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007078/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7079testcase TC_c0_power_red_mode() runs on test_CT {
7080 f_init(1);
7081
7082 for (var integer red := 6; red >= 0; red := red - 2) {
7083 /* Configure BCCH carrier power reduction mode via the VTY */
7084 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7085
7086 /* Expect Osmocom specific BS Power Control message on the RSL */
7087 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7088 chan_nr := t_RslChanNr_BCCH(0),
7089 bs_power := tr_RSL_IE_BS_Power(red / 2));
7090 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7091 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7092
7093 /* Additionally verify the applied value over the CTRL interface */
7094 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7095 if (cred != int2str(red)) {
7096 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7097 cred, " (expected ", red, ")");
7098 }
7099 }
7100
7101 f_shutdown_helper();
7102}
7103
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007104/***********************************************************************
7105 * MSC Pooling
7106 ***********************************************************************/
7107
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007108template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007109 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 +02007110
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007111private function f_expect_lchan_rel(RSL_DCHAN_PT rsl, template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
7112runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007113 interleave {
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007114 [] rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007115 f_logp(BSCVTY, "Got RSL RR Release");
7116 }
7117 [] rsl.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
7118 f_logp(BSCVTY, "Got RSL Deact SACCH");
7119 }
7120 [] rsl.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
7121 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
7122 rsl.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7123 break;
7124 }
7125 }
7126}
7127
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02007128friend function f_perform_clear(RSL_DCHAN_PT rsl, template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007129runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007130 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007131 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7132 interleave {
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007133 [] rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007134 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007135 }
7136 [] rsl.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007137 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007138 }
7139 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007140 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007141 /* Also drop the SCCP connection */
7142 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7143 }
7144 [] rsl.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007145 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007146 rsl.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7147 }
7148 }
7149}
7150
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007151private 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 +02007152runs on MSC_ConnHdlr {
7153 timer T := 10.0;
7154 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7155
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007156 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007157 f_create_bssmap_exp(l3_enc);
7158
7159 /* RSL_Emulation.f_chan_est() on rsl:
7160 * This is basically code dup with s/RSL/rsl from:
7161 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7162 */
7163 var RSL_Message rx_rsl;
7164 var GsmRrMessage rr;
7165
7166 /* request a channel to be established */
7167 rsl.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
7168 /* expect immediate assignment.
7169 * Code dup with s/RSL/rsl from:
7170 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7171 */
7172 timer Tt := 10.0;
7173
7174 /* request a channel to be established */
7175 Tt.start;
7176 alt {
7177 [] rsl.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
7178 Tt.stop;
7179 }
7180 [] rsl.receive {
7181 setverdict(fail, "Unexpected RSL message on DCHAN");
7182 mtc.stop;
7183 }
7184 [] Tt.timeout {
7185 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7186 mtc.stop;
7187 }
7188 }
7189 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7190 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
7191 rsl.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
7192
7193
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007194 if (expect_bssmap_l3) {
7195 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7196 var template PDU_BSSAP exp_l3_compl;
7197 exp_l3_compl := tr_BSSMAP_ComplL3()
7198 if (g_pars.aoip == false) {
7199 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7200 } else {
7201 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7202 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007203
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007204 var PDU_BSSAP bssap;
7205 T.start;
7206 alt {
7207 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7208 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7209 log("rx exp_l3_compl = ", bssap);
7210 }
7211 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7212 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7213 }
7214 [] T.timeout {
7215 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7216 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007217 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007218
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007219 /* start ciphering, if requested */
7220 if (ispresent(g_pars.encr)) {
7221 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02007222 f_cipher_mode(g_pars.encr);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007223 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007224 }
7225
7226 if (do_clear) {
7227 f_perform_clear(rsl);
7228 }
7229 setverdict(pass);
7230 f_sleep(1.0);
7231}
7232
7233private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7234 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7235 if (g_pars.mscpool.rsl_idx == 0) {
7236 f_perform_compl_l3(RSL, g_pars.mscpool.l3_info);
7237 } else if (g_pars.mscpool.rsl_idx == 1) {
7238 f_perform_compl_l3(RSL1, g_pars.mscpool.l3_info);
7239 } else if (g_pars.mscpool.rsl_idx == 2) {
7240 f_perform_compl_l3(RSL2, g_pars.mscpool.l3_info);
7241 }
7242}
7243
7244/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7245private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7246 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7247 f_perform_compl_l3(RSL, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7248 f_perform_compl_l3(RSL, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7249 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7250 f_perform_compl_l3(RSL, ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_IMSI_LV('001010000000004'H))) );
7251}
7252testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7253
7254 f_init(1, true);
7255 f_sleep(1.0);
7256 var MSC_ConnHdlr vc_conn;
7257 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007258
7259 f_ctrs_msc_init();
7260
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007261 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7262 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007263
7264 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007265 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007266}
7267
7268/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7269/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7270 * just as well using only RSL. */
7271testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7272
7273 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7274 f_sleep(1.0);
7275
7276 /* Control which MSC gets chosen next by the round-robin, otherwise
7277 * would be randomly affected by which other tests ran before this. */
7278 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7279
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007280 f_ctrs_msc_init();
7281
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007282 var MSC_ConnHdlr vc_conn1;
7283 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7284 pars1.mscpool.rsl_idx := 0;
7285 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7286 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7287 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007288 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007289
7290 var MSC_ConnHdlr vc_conn2;
7291 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7292 pars2.mscpool.rsl_idx := 1;
7293 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7294 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7295 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007296 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007297
7298 /* Test round-robin wrap to the first MSC */
7299 var MSC_ConnHdlr vc_conn3;
7300 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7301 pars3.mscpool.rsl_idx := 2;
7302 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7303 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7304 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007305 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007306 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007307}
7308
7309/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7310 * (configured in osmo-bsc.cfg). */
7311/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7312 * just as well using only RSL. */
7313testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7314
7315 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7316 f_sleep(1.0);
7317
7318 /* Control which MSC gets chosen next by the round-robin, otherwise
7319 * would be randomly affected by which other tests ran before this. */
7320 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7321
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007322 f_ctrs_msc_init();
7323
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007324 var MSC_ConnHdlr vc_conn1;
7325 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7326 pars1.mscpool.rsl_idx := 0;
7327 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7328 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7329 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007330 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007331
7332 var MSC_ConnHdlr vc_conn2;
7333 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7334 pars2.mscpool.rsl_idx := 1;
7335 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7336 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7337 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007338 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007339
7340 /* Test round-robin wrap to the first MSC */
7341 var MSC_ConnHdlr vc_conn3;
7342 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7343 pars3.mscpool.rsl_idx := 2;
7344 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7345 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7346 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007347 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007348 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007349}
7350
7351/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7352 * (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
7353 * NULL-NRI setting is stronger than that. */
7354/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7355 * just as well using only RSL. */
7356testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7357
7358 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7359 f_sleep(1.0);
7360
7361 /* Control which MSC gets chosen next by the round-robin, otherwise
7362 * would be randomly affected by which other tests ran before this. */
7363 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7364
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007365 f_ctrs_msc_init();
7366
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007367 var MSC_ConnHdlr vc_conn1;
7368 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7369 pars1.mscpool.rsl_idx := 0;
7370 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7371 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7372 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007373 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007374
7375 var MSC_ConnHdlr vc_conn2;
7376 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7377 pars2.mscpool.rsl_idx := 1;
7378 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7379 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7380 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007381 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007382
7383 /* Test round-robin wrap to the first MSC */
7384 var MSC_ConnHdlr vc_conn3;
7385 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7386 pars3.mscpool.rsl_idx := 2;
7387 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7388 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7389 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007390 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007391 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007392}
7393
7394/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7395 * assigned to any MSC (configured in osmo-bsc.cfg). */
7396/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7397 * just as well using only RSL. */
7398testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7399
7400 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7401 f_sleep(1.0);
7402
7403 /* Control which MSC gets chosen next by the round-robin, otherwise
7404 * would be randomly affected by which other tests ran before this. */
7405 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7406
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007407 f_ctrs_msc_init();
7408
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007409 var MSC_ConnHdlr vc_conn1;
7410 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7411 pars1.mscpool.rsl_idx := 0;
7412 /* An NRI that is not assigned to any MSC */
7413 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7414 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7415 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007416 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007417
7418 var MSC_ConnHdlr vc_conn2;
7419 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7420 pars2.mscpool.rsl_idx := 1;
7421 /* An NRI that is not assigned to any MSC */
7422 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7423 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7424 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007425 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007426
7427 /* Test round-robin wrap to the first MSC */
7428 var MSC_ConnHdlr vc_conn3;
7429 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7430 pars3.mscpool.rsl_idx := 2;
7431 /* An NRI that is not assigned to any MSC */
7432 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7433 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7434 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007435 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007436 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007437}
7438
7439/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7440 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7441/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7442 * just as well using only RSL. */
7443testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7444
7445 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7446 f_sleep(1.0);
7447
7448 /* Control which MSC gets chosen next by the round-robin, otherwise
7449 * would be randomly affected by which other tests ran before this. */
7450 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7451
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007452 f_ctrs_msc_init();
7453
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007454 var MSC_ConnHdlr vc_conn1;
7455 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7456 pars1.mscpool.rsl_idx := 0;
7457 /* An NRI that is assigned to an unconnected MSC */
7458 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7459 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7460 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007461 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7462 f_ctrs_msc_add(0, "mscpool:subscr:new");
7463 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007464
7465 var MSC_ConnHdlr vc_conn2;
7466 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7467 pars2.mscpool.rsl_idx := 1;
7468 /* An NRI that is assigned to an unconnected MSC */
7469 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7470 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7471 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007472 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7473 f_ctrs_msc_add(1, "mscpool:subscr:new");
7474 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007475
7476 /* Test round-robin wrap to the first MSC */
7477 var MSC_ConnHdlr vc_conn3;
7478 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7479 pars3.mscpool.rsl_idx := 2;
7480 /* An NRI that is assigned to an unconnected MSC */
7481 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7482 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7483 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007484 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7485 f_ctrs_msc_add(0, "mscpool:subscr:new");
7486 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007487 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007488}
7489
7490/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7491 * osmo-bsc.cfg). */
7492/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7493 * just as well using only RSL. */
7494testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7495
7496 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7497 f_sleep(1.0);
7498
7499 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7500 * this is not using round-robin. */
7501 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7502
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007503 f_ctrs_msc_init();
7504
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007505 var MSC_ConnHdlr vc_conn1;
7506 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7507 pars1.mscpool.rsl_idx := 0;
7508 /* An NRI of the second MSC's range (256-511) */
7509 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7510 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7511 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007512 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007513
7514 var MSC_ConnHdlr vc_conn2;
7515 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7516 pars2.mscpool.rsl_idx := 1;
7517 /* An NRI of the second MSC's range (256-511) */
7518 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7519 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7520 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007521 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007522
7523 var MSC_ConnHdlr vc_conn3;
7524 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7525 pars3.mscpool.rsl_idx := 2;
7526 /* An NRI of the second MSC's range (256-511) */
7527 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7528 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7529 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007530 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007531 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007532}
7533
7534/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7535 * while a round-robin remains unaffected by that. */
7536/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7537 * just as well using only RSL. */
7538testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7539
7540 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7541 f_sleep(1.0);
7542
7543 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7544 * this is not using round-robin. */
7545 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7546
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007547 f_ctrs_msc_init();
7548
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007549 var MSC_ConnHdlr vc_conn1;
7550 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7551 pars1.mscpool.rsl_idx := 0;
7552 /* An NRI of the third MSC's range (512-767) */
7553 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7554 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7555 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007556 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007557
7558 var MSC_ConnHdlr vc_conn2;
7559 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7560 pars2.mscpool.rsl_idx := 1;
7561 /* An NRI of the third MSC's range (512-767) */
7562 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7563 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7564 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007565 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007566
7567 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7568 var MSC_ConnHdlr vc_conn3;
7569 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7570 pars3.mscpool.rsl_idx := 2;
7571 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7572 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7573 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007574 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007575 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007576}
7577
7578/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
7579/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7580 * just as well using only RSL. */
7581testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
7582
7583 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7584 f_sleep(1.0);
7585
7586 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
7587 * instead, and hits msc 0. */
7588 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7589
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007590 f_ctrs_msc_init();
7591
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007592 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
7593 var MSC_ConnHdlr vc_conn1;
7594 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7595 pars1.mscpool.rsl_idx := 0;
7596 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
7597 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7598 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007599 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007600
7601 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
7602 var MSC_ConnHdlr vc_conn2;
7603 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7604 pars2.mscpool.rsl_idx := 1;
7605 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
7606 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7607 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007608 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007609 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007610}
7611
7612/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
7613 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7614private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
7615 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7616 //cid_list := { cIl_allInBSS := ''O };
7617 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7618 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7619 var BSSAP_N_UNITDATA_req paging;
7620 var hexstring imsi := '001010000000123'H;
7621
7622 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7623
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007624 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007625 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
7626 BSSAP.send(paging);
7627
7628 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7629 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7630 * channel number is picked here. */
7631 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7632 f_rslem_register(0, new_chan_nr);
7633 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
7634 f_rslem_unregister(0, new_chan_nr);
7635
7636 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
7637 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
7638 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007639 f_sleep(1.0);
7640}
7641testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
7642 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7643 f_sleep(1.0);
7644
7645 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7646 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7647 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7648
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007649 f_ctrs_msc_init();
7650
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007651 var MSC_ConnHdlr vc_conn1;
7652 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7653 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007654 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7655 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007656 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
7657 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007658 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007659 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007660}
7661
7662/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
7663 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7664private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
7665 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7666 //cid_list := { cIl_allInBSS := ''O };
7667 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7668 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7669 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01007670 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007671 var BSSAP_N_UNITDATA_req paging;
7672
7673 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7674
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007675 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007676 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
7677 BSSAP.send(paging);
7678
7679 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7680 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7681 * channel number is picked here. */
7682 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7683 f_rslem_register(0, new_chan_nr);
7684 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
7685 f_rslem_unregister(0, new_chan_nr);
7686
7687 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
7688 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
7689 * the first MSC (bssap_idx := 0). */
7690 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(nri_v))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007691 f_sleep(1.0);
7692}
7693testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
7694 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7695 f_sleep(1.0);
7696
7697 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7698 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7699 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
7700
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007701 f_ctrs_msc_init();
7702
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007703 var MSC_ConnHdlr vc_conn1;
7704 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7705 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007706 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7707 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007708 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
7709 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007710 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007711 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007712}
7713
7714/* For round-robin, skip an MSC that has 'no allow-attach' set. */
7715/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7716 * just as well using only RSL. */
7717testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
7718
7719 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7720 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007721 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7722 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007723
7724 /* Control which MSC gets chosen next by the round-robin, otherwise
7725 * would be randomly affected by which other tests ran before this. */
7726 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7727
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007728 f_ctrs_msc_init();
7729
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007730 var MSC_ConnHdlr vc_conn1;
7731 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7732 pars1.mscpool.rsl_idx := 0;
7733 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7734 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7735 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007736 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007737
7738 var MSC_ConnHdlr vc_conn2;
7739 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7740 pars2.mscpool.rsl_idx := 1;
7741 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7742 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7743 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007744 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007745
7746 var MSC_ConnHdlr vc_conn3;
7747 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7748 pars3.mscpool.rsl_idx := 2;
7749 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7750 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7751 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007752 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007753 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007754}
7755
7756/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
7757 * TMSI NRI. */
7758testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
7759
7760 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7761 f_sleep(1.0);
7762
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007763 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7764 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
7765
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007766 /* Control which MSC gets chosen next by the round-robin, otherwise
7767 * would be randomly affected by which other tests ran before this. */
7768 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7769
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007770 f_ctrs_msc_init();
7771
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007772 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
7773 var MSC_ConnHdlr vc_conn1;
7774 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7775 pars1.mscpool.rsl_idx := 0;
7776 /* An NRI of the second MSC's range (256-511) */
7777 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
7778 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7779 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007780 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007781
7782 var MSC_ConnHdlr vc_conn2;
7783 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
7784 pars2.mscpool.rsl_idx := 1;
7785 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7786 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7787 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007788 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007789
7790 var MSC_ConnHdlr vc_conn3;
7791 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
7792 pars3.mscpool.rsl_idx := 2;
7793 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
7794 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7795 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007796 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007797 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007798}
7799
Philipp Maier783681c2020-07-16 16:47:06 +02007800/* Allow/Deny emergency calls globally via VTY */
7801private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
7802 f_vty_enter_cfg_msc(BSCVTY, 0);
7803 if (allow) {
7804 f_vty_transceive(BSCVTY, "allow-emergency allow");
7805 } else {
7806 f_vty_transceive(BSCVTY, "allow-emergency deny");
7807 }
7808 f_vty_transceive(BSCVTY, "exit");
7809 f_vty_transceive(BSCVTY, "exit");
7810}
7811
7812/* Allow/Deny emergency calls per BTS via VTY */
7813private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
7814 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
7815 if (allow) {
7816 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
7817 } else {
7818 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
7819 }
7820 f_vty_transceive(BSCVTY, "exit");
7821 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00007822 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02007823}
7824
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02007825/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
7826private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
7827 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
7828 if (allow) {
7829 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
7830 } else {
7831 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
7832 }
7833 f_vty_transceive(BSCVTY, "exit");
7834 f_vty_transceive(BSCVTY, "exit");
7835 f_vty_transceive(BSCVTY, "exit");
7836}
7837
Philipp Maier783681c2020-07-16 16:47:06 +02007838/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
7839private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
7840 var PDU_ML3_MS_NW emerg_setup;
7841 var octetstring emerg_setup_enc;
7842 var RSL_Message emerg_setup_data_ind;
7843
7844 f_establish_fully(omit, omit);
7845
7846 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
7847 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
7848 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
7849
7850 RSL.send(emerg_setup_data_ind);
7851}
7852
7853/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
7854 * CALLS are permitted by the BSC config. */
7855private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
7856 var PDU_BSSAP emerg_setup_data_ind_bssap;
7857 var PDU_ML3_MS_NW emerg_setup;
7858 timer T := 3.0;
7859
7860 f_assignment_emerg_setup()
7861
7862 T.start;
7863 alt {
7864 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
7865 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
7866 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
7867 setverdict(fail, "no emergency setup");
7868 }
7869 }
7870 [] BSSAP.receive {
7871 setverdict(fail, "unexpected BSSAP message!");
7872 }
7873 [] T.timeout {
7874 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
7875 }
7876 }
7877
7878 setverdict(pass);
7879}
7880
7881/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
7882 * forbidden by the BSC config. */
7883private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
7884 var PDU_BSSAP emerg_setup_data_ind_bssap;
7885 timer T := 3.0;
7886
7887 f_assignment_emerg_setup()
7888
7889 T.start;
7890 alt {
7891 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
7892 setverdict(pass);
7893 }
7894 [] RSL.receive {
7895 setverdict(fail, "unexpected RSL message!");
7896 }
7897 [] T.timeout {
7898 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
7899 }
7900 }
7901}
7902
7903/* EMERGENCY CALL situation #1, allowed globally and by BTS */
7904testcase TC_assignment_emerg_setup_allow() runs on test_CT {
7905 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7906 var MSC_ConnHdlr vc_conn;
7907
7908 f_init(1, true);
7909 f_sleep(1.0);
7910
7911 f_vty_allow_emerg_msc(true);
7912 f_vty_allow_emerg_bts(true, 0);
7913 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
7914 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007915 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02007916}
7917
7918/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
7919testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
7920 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7921 var MSC_ConnHdlr vc_conn;
7922
7923 f_init(1, true);
7924 f_sleep(1.0);
7925
7926 f_vty_allow_emerg_msc(false);
7927 f_vty_allow_emerg_bts(true, 0);
7928 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
7929 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007930 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02007931}
7932
7933/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
7934testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
7935 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7936 var MSC_ConnHdlr vc_conn;
7937
7938 /* Note: This simulates a spec violation by the MS, correct MS
7939 * implementations would not try to establish an emergency call because
7940 * the system information tells in advance that emergency calls are
7941 * not forbidden */
7942
7943 f_init(1, true);
7944 f_sleep(1.0);
7945
7946 f_vty_allow_emerg_msc(true);
7947 f_vty_allow_emerg_bts(false, 0);
7948 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
7949 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007950 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02007951}
7952
Philipp Maier82812002020-08-13 18:48:27 +02007953/* Test what happens when an emergency call arrives while all TCH channels are
7954 * busy, the BSC is expected to terminate one call in favor of the incoming
7955 * emergency call */
7956testcase TC_emerg_premption() runs on test_CT {
7957 var ASP_RSL_Unitdata rsl_ud;
7958 var integer i;
7959 var integer chreq_total, chreq_nochan;
7960 var RSL_Message rx_rsl;
7961 var RslChannelNr chan_nr;
7962
7963 f_init(1);
7964 f_sleep(1.0);
7965
7966 f_vty_allow_emerg_msc(true);
7967 f_vty_allow_emerg_bts(true, 0);
7968
7969 /* Fill up all channels on the BTS */
7970 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
7971 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
7972 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
7973 chan_nr := f_chreq_act_ack('33'O, i);
7974 }
7975 IPA_RSL[0].clear;
7976 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
7977 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
7978
7979 /* Send Channel request for emegergency call */
7980 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
7981
7982 /* Expect the BSC to release one (the first) TCH/F on the BTS */
7983 chan_nr := valueof(t_RslChanNr_Bm(1));
7984 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
7985
7986 /* Expect the BSC to send activate/assign the a channel for the emergency call */
7987 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7988 chan_nr := rx_rsl.ies[0].body.chan_nr;
7989 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
7990 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02007991
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007992 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007993}
7994
7995/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07007996private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07007997private type record FHParamsTs {
7998 boolean enabled,
7999 uint6_t hsn,
8000 uint6_t maio,
8001 ArfcnList ma
8002};
8003
8004/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008005private type record FHParamsTrx {
8006 GsmArfcn arfcn,
8007 FHParamsTs ts[8]
8008};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008009
8010/* Randomly generate the hopping parameters for the given timeslot numbers */
8011private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8012runs on test_CT return FHParamsTrx {
8013 var FHParamsTrx fhp;
8014
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008015 /* Generate a random ARFCN, including ARFCN 0 */
8016 fhp.arfcn := f_rnd_int(3);
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008017
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008018 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8019 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008020 fhp.ts[tn].enabled := false;
8021 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008022 continue;
8023 }
8024
8025 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008026 fhp.ts[tn].hsn := f_rnd_int(64);
8027 fhp.ts[tn].maio := f_rnd_int(64);
8028 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008029
8030 /* Random Mobile Allocation (hopping channels) */
8031 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8032 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8033 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008034 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008035 }
8036
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008037 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008038 }
8039
8040 log("f_TC_fh_params_gen(): ", fhp);
8041 return fhp;
8042}
8043
8044/* Make sure that the given Channel Description IE matches the hopping configuration */
8045private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8046{
8047 var template (present) ChannelDescription tr_cd;
8048 var template (present) MaioHsn tr_maio_hsn;
8049 var uint3_t tn := cd.chan_nr.tn;
8050
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008051 if (fhp.ts[tn].enabled) {
8052 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008053 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8054 } else {
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008055 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008056 }
8057
8058 if (not match(cd, tr_cd)) {
8059 setverdict(fail, "Channel Description IE does not match: ",
8060 cd, " vs expected ", tr_cd);
8061 }
8062}
8063
8064/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8065private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8066 in MobileAllocationLV ma)
8067{
8068 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8069
8070 if (not match(ma, tr_ma)) {
8071 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8072 tn, "): ", ma, " vs expected: ", tr_ma);
8073 } else {
8074 setverdict(pass);
8075 }
8076}
8077
8078private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8079 in MobileAllocationLV ma)
8080return template MobileAllocationLV {
8081 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008082 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008083 return { len := 0, ma := ''B };
8084 }
8085
8086 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8087 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8088 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008089
8090 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008091 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8092 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8093 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008094 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008095 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008096 }
8097 }
8098
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008099 /* Take ARFCN of the TRX itself into account */
8100 full_mask[fhp.arfcn] := '1'B;
8101
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008102 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008103 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8104 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008105 }
8106
8107 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008108 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008109 if (full_mask[i] != '1'B)
8110 { continue; }
8111
8112 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8113 if (slot_mask[i] == '1'B) {
8114 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008115 } else {
8116 ma_mask := ma_mask & '0'B;
8117 }
8118 }
8119
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008120 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8121 if (full_mask[0] == '1'B) {
8122 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8123 if (slot_mask[0] == '1'B) {
8124 ma_mask := ma_mask & '1'B;
8125 } else {
8126 ma_mask := ma_mask & '0'B;
8127 }
8128 }
8129
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008130 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008131 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008132 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8133
8134 return { len := ma_mask_len, ma := ma_mask };
8135}
8136
8137/* Configure the hopping parameters in accordance with the given record */
8138private function f_TC_fh_params_set(in FHParamsTrx fhp,
8139 uint8_t bts_nr := 0,
8140 uint8_t trx_nr := 0)
8141runs on test_CT {
8142 /* Enter the configuration node for the given BTS/TRX numbers */
8143 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8144
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008145 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn));
8146
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008147 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008148 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8149
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008150 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008151 f_vty_transceive(BSCVTY, "hopping enabled 0");
8152 f_vty_transceive(BSCVTY, "exit"); /* go back */
8153 continue;
8154 }
8155
8156 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008157 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8158 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008159
8160 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008161 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8162 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008163 }
8164
8165 f_vty_transceive(BSCVTY, "hopping enabled 1");
8166 f_vty_transceive(BSCVTY, "exit"); /* go back */
8167 }
8168
8169 f_vty_transceive(BSCVTY, "end");
8170}
8171
8172/* Disable frequency hopping on all timeslots */
8173private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8174 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008175 uint8_t trx_nr := 0,
8176 GsmArfcn arfcn := 871)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008177runs on test_CT {
8178 /* Enter the configuration node for the given BTS/TRX numbers */
8179 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8180
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008181 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn));
8182
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008183 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008184 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8185
8186 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008187 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8188 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008189 }
8190
8191 f_vty_transceive(BSCVTY, "hopping enabled 0");
8192 f_vty_transceive(BSCVTY, "exit"); /* go back */
8193 }
8194
8195 f_vty_transceive(BSCVTY, "end");
8196 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8197}
8198
8199/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8200 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8201testcase TC_fh_params_chan_activ() runs on test_CT {
8202 var FHParamsTrx fhp := f_TC_fh_params_gen();
8203 var RSL_Message rsl_msg;
8204 var RSL_IE_Body ie;
8205
8206 f_init_vty();
8207
8208 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8209 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8210
8211 f_init(1);
8212
8213 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8214 for (var integer i := 0; i < 9; i := i + 1) {
8215 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8216 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8217
8218 /* Make sure that Channel Identification IE is present */
8219 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8220 setverdict(fail, "RSL Channel Identification IE is absent");
8221 continue;
8222 }
8223
8224 /* Make sure that hopping parameters (HSN/MAIO) match */
8225 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8226
8227 /* "Mobile Allocation shall be included but empty" - let's check this */
8228 if (ie.chan_ident.ma.v.len != 0) {
8229 setverdict(fail, "Mobile Allocation IE is not empty: ",
8230 ie.chan_ident.ma, ", despite it shall be");
8231 continue;
8232 }
8233 }
8234
8235 /* Disable frequency hopping */
8236 f_TC_fh_params_unset(fhp);
8237
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008238 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008239}
8240
8241/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8242testcase TC_fh_params_imm_ass() runs on test_CT {
8243 var FHParamsTrx fhp := f_TC_fh_params_gen();
8244 var RSL_Message rsl_msg;
8245 var RSL_IE_Body ie;
8246
8247 f_init_vty();
8248
8249 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8250 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8251
8252 f_init(1);
8253
8254 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8255 for (var integer i := 0; i < 9; i := i + 1) {
8256 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8257 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8258
8259 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8260 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8261
8262 /* Make sure that Full Immediate Assign Info IE is present */
8263 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8264 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8265 continue;
8266 }
8267
8268 /* Decode the actual Immediate Assignment message */
8269 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8270 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8271 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8272 continue;
8273 }
8274
8275 /* Make sure that hopping parameters (HSN/MAIO) match */
8276 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8277
8278 /* Make sure that the Mobile Allocation IE matches */
8279 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8280 rr_msg.payload.imm_ass.mobile_allocation);
8281 }
8282
8283 /* Disable frequency hopping */
8284 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008285
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008286 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008287}
8288
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008289/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8290testcase TC_fh_params_assignment_cmd() runs on test_CT {
8291 var FHParamsTrx fhp := f_TC_fh_params_gen();
8292 var RSL_Message rsl_msg;
8293 var RSL_IE_Body ie;
8294
8295 f_init_vty();
8296
8297 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8298 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8299
8300 f_init(1);
8301
8302 /* HACK: work around "Couldn't find Expect for CRCX" */
8303 vc_MGCP.stop;
8304
8305 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8306 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8307
8308 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8309 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8310 for (var integer i := 0; i < 3; i := i + 1) {
8311 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8312 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8313
8314 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8315 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8316 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8317
8318 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8319 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8320 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8321
8322 /* Make sure that L3 Information IE is present */
8323 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8324 setverdict(fail, "RSL L3 Information IE is absent");
8325 continue;
8326 }
8327
8328 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8329 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8330 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8331 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8332 continue;
8333 }
8334
8335 /* Make sure that hopping parameters (HSN/MAIO) match */
8336 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8337 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8338
8339 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8340 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008341 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008342 continue;
8343 }
8344
8345 /* Make sure that the Mobile Allocation IE matches (if present) */
8346 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8347 if (chan_desc.h and ma_present) {
8348 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8349 l3_msg.payload.ass_cmd.mobile_allocation.v);
8350 } else if (chan_desc.h and not ma_present) {
8351 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8352 continue;
8353 } else if (not chan_desc.h and ma_present) {
8354 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8355 continue;
8356 }
8357 }
8358
8359 /* Give the IUT some time to release all channels */
8360 f_sleep(3.0);
8361
8362 /* Disable frequency hopping */
8363 f_TC_fh_params_unset(fhp);
8364
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008365 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008366}
8367
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008368/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8369private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8370runs on test_CT {
8371 var RSL_Message rsl_msg;
8372 var RSL_IE_Body ie;
8373 var DchanTuple dt;
8374
8375 /* Establish a dedicated channel, so we can trigger handover */
8376 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8377
8378 /* Trigger handover from BTS0 to BTS1 */
8379 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8380 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8381
8382 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8383 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8384
8385 /* ACKnowledge channel activation and expect (RR) Handover Command */
8386 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8387 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8388
8389 /* Make sure that L3 Information IE is present */
8390 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8391 setverdict(fail, "RSL L3 Information IE is absent");
8392 return;
8393 }
8394
8395 /* Decode the L3 message and make sure it is (RR) Handover Command */
8396 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8397 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8398 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8399 return;
8400 }
8401
8402 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8403 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8404 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8405 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8406 return;
8407 }
8408
8409 /* Make sure that hopping parameters (HSN/MAIO) match */
8410 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8411
8412 /* Make sure that Cell Channel Description IE is present */
8413 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8414 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8415 return;
8416 }
8417
8418 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8419 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8420 if (ma_present) {
8421 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8422 l3_msg.payload.ho_cmd.mobile_allocation.v);
8423 } else {
8424 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8425 return;
8426 }
8427}
8428testcase TC_fh_params_handover_cmd() runs on test_CT {
8429 var FHParamsTrx fhp := f_TC_fh_params_gen();
8430
8431 f_init_vty();
8432
8433 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8434 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8435
8436 f_vty_transceive(BSCVTY, "timeslot 0");
8437 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8438 f_vty_transceive(BSCVTY, "exit"); /* go back */
8439
8440 f_vty_transceive(BSCVTY, "timeslot 1");
8441 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8442 f_vty_transceive(BSCVTY, "end"); /* we're done */
8443
8444 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8445 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8446
8447 f_init(2);
8448
8449 f_TC_fh_params_handover_cmd(fhp);
8450
8451 /* Disable frequency hopping on BTS1 */
8452 f_TC_fh_params_unset(fhp, 1);
8453
8454 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8455 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8456
8457 f_vty_transceive(BSCVTY, "timeslot 0");
8458 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8459 f_vty_transceive(BSCVTY, "exit"); /* go back */
8460
8461 f_vty_transceive(BSCVTY, "timeslot 1");
8462 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8463 f_vty_transceive(BSCVTY, "end"); /* we're done */
8464
8465 f_shutdown_helper();
8466}
8467
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008468/* Verify the hopping parameters in System Information Type 4 */
8469testcase TC_fh_params_si4_cbch() runs on test_CT {
8470 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8471 var ASP_RSL_Unitdata rx_rsl_ud;
8472 timer T := 5.0;
8473
8474 f_init_vty();
8475
8476 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
8477 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8478
8479 f_vty_transceive(BSCVTY, "timeslot 0");
8480 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8481 f_vty_transceive(BSCVTY, "exit"); /* go back */
8482
8483 f_vty_transceive(BSCVTY, "timeslot 1");
8484 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
8485 f_vty_transceive(BSCVTY, "end"); /* we're done */
8486
8487 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8488 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8489
8490 f_init(1);
8491
8492 T.start;
8493 alt {
8494 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
8495 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
8496 var SystemInformation si := dec_SystemInformation(ie.other.payload);
8497
8498 /* Make sure that what we decoded is System Information Type 4 */
8499 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
8500 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
8501 repeat;
8502 }
8503
8504 /* Make sure that CBCH Channel Description IE is present */
8505 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
8506 setverdict(fail, "CBCH Channel Description IE is absent");
8507 break;
8508 }
8509
8510 /* Finally, check the hopping parameters (HSN, MAIO) */
8511 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
8512 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8513
8514 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
8515 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
8516 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
8517 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8518 break;
8519 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
8520 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8521 si.payload.si4.cbch_mobile_alloc.v);
8522 }
8523 }
8524 [] IPA_RSL[0].receive { repeat; }
8525 [] T.timeout {
8526 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
8527 }
8528 }
8529
8530 /* Disable frequency hopping */
8531 f_TC_fh_params_unset(fhp);
8532
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008533 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008534 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8535
8536 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008537 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008538 f_vty_transceive(BSCVTY, "exit"); /* go back */
8539
8540 f_vty_transceive(BSCVTY, "timeslot 1");
8541 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8542 f_vty_transceive(BSCVTY, "end"); /* we're done */
8543
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008544 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008545}
8546
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008547template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
8548 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
8549
8550private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
8551 template (present) BSSLAP_PDU expect_bsslap)
8552{
8553 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
8554 if (not match(bsslap, expect_bsslap)) {
8555 log("EXPECTING BSSLAP: ", expect_bsslap);
8556 log("GOT BSSLAP: ", bsslap);
8557 setverdict(fail, "BSSLAP is not as expected");
8558 mtc.stop;
8559 }
8560 setverdict(pass);
8561}
8562
8563/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
8564const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
8565
8566private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
8567 var PDU_BSSAP_LE rx_bsslap;
8568 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
8569 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
8570}
8571
8572/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8573 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
8574private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
8575 f_sleep(1.0);
8576
8577 f_establish_fully(omit, omit);
8578 f_bssap_le_register_imsi(g_pars.imsi, omit);
8579
8580 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8581 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8582
8583 var PDU_BSSAP_LE plr;
8584 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8585
8586 if (not do_ta_request) {
8587 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
8588 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
8589 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
8590 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
8591 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
8592 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
8593 mtc.stop;
8594 }
8595 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
8596 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
8597 if (not match(bsslap, expect_ta_layer3)) {
8598 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
8599 log("GOT BSSLAP: ", bsslap);
8600 setverdict(fail, "BSSLAP is not as expected");
8601 mtc.stop;
8602 }
8603 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
8604 * has no need to request the TA from the BSC and directly responds. */
8605 } else {
8606 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8607 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8608 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8609 }
8610
8611 /* SMLC got the TA from the BSC, now responds with geo information data. */
8612 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8613 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8614 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8615
8616 /* The LCS was using an active A-interface conn. It should still remain active after this. */
8617 f_mo_l3_transceive();
8618
8619 f_perform_clear(RSL);
8620
8621 f_sleep(2.0);
8622 setverdict(pass);
8623}
8624
8625/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8626 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
8627private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
8628 f_lcs_loc_req_for_active_ms(false);
8629}
8630testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
8631 var MSC_ConnHdlr vc_conn;
8632 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8633
8634 f_init(1, true);
8635 f_sleep(1.0);
8636 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
8637 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008638 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008639}
8640
8641/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8642 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
8643private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
8644 f_lcs_loc_req_for_active_ms(true);
8645}
8646testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
8647 var MSC_ConnHdlr vc_conn;
8648 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8649
8650 f_init(1, true);
8651 f_sleep(1.0);
8652 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
8653 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008654 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008655}
8656
8657/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
8658 * conn without an active lchan. */
8659private function f_clear_A_conn() runs on MSC_ConnHdlr
8660{
8661 var BssmapCause cause := 0;
8662 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
8663 BSSAP.receive(tr_BSSMAP_ClearComplete);
8664 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8665
8666 timer no_more_bssap := 5.0;
8667 no_more_bssap.start;
8668 alt {
8669 [] no_more_bssap.timeout { break; }
8670 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
8671 setverdict(fail, "Expected no more BSSAP after Clear Complete");
8672 mtc.stop;
8673 }
8674 }
8675 setverdict(pass);
8676}
8677
8678/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
8679 * for LCS, for cases where there is only an A conn without an active lchan. */
8680private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
8681{
8682 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
8683
8684 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
8685 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
8686 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
8687 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8688 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8689 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
8690
8691 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
8692 f_clear_A_conn();
8693 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
8694 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8695}
8696
8697/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8698 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
8699 */
8700private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
8701 f_sleep(1.0);
8702
8703 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8704 f_bssap_le_register_imsi(g_pars.imsi, omit);
8705
8706 /* Register to receive the Paging Command */
8707 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8708 g_chan_nr := new_chan_nr;
8709 f_rslem_register(0, g_chan_nr);
8710
8711 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8712 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8713 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8714 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8715
8716 var PDU_BSSAP_LE plr;
8717 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8718
8719 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8720 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8721
8722 /* OsmoBSC needs to Page */
8723 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
8724 f_logp(BSCVTY, "got Paging Command");
8725
8726 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
8727 * the MSC, and releases the lchan directly. */
8728 f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(g_pars.imsi))), do_clear := false, expect_bssmap_l3 := false);
8729 f_expect_lchan_rel(RSL);
8730
8731 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
8732
8733 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8734
8735 /* SMLC got the TA from the BSC, now responds with geo information data. */
8736 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8737 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8738
8739 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8740
8741 /* The lchan is gone, the A-interface conn was created for the LCS only.
8742 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
8743 f_verify_active_A_conn_and_clear();
8744
8745 f_sleep(2.0);
8746 setverdict(pass);
8747}
8748testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
8749 var MSC_ConnHdlr vc_conn;
8750 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8751
8752 f_init(1, true);
8753 f_sleep(1.0);
8754
8755 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8756 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8757
8758 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
8759 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008760 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008761}
8762
8763/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
8764 */
8765private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
8766 f_sleep(1.0);
8767
8768 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8769 f_bssap_le_register_imsi(g_pars.imsi, omit);
8770
8771 /* provoke an abort by omitting both IMSI and IMEI */
8772 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8773 valueof(ts_BSSMAP_Perform_Location_Request(omit,
8774 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
8775 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8776
8777 /* BSC tells MSC about failure */
8778 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
8779 locationEstimate := omit, positioningData := omit,
8780 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
8781
8782 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
8783 f_verify_active_A_conn_and_clear();
8784
8785 f_sleep(2.0);
8786 setverdict(pass);
8787}
8788testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
8789 var MSC_ConnHdlr vc_conn;
8790 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8791
8792 f_init(1, true);
8793 f_sleep(1.0);
8794
8795 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8796 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8797
8798 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
8799 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008800 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008801}
8802
8803/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
8804 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
8805private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
8806 f_sleep(1.0);
8807
8808 f_establish_fully(omit, omit);
8809 f_bssap_le_register_imsi(g_pars.imsi, omit);
8810
8811 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8812 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8813
8814 var PDU_BSSAP_LE plr;
8815 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8816
8817 if (do_ta) {
8818 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8819 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8820 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8821 }
8822
8823 /* SMLC fails to respond, BSC runs into timeout */
8824 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
8825 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8826
8827 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
8828 locationEstimate := omit, positioningData := omit,
8829 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
8830
8831 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
8832 f_verify_active_A_conn_and_clear();
8833
8834 f_sleep(2.0);
8835 setverdict(pass);
8836}
8837
8838/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
8839 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
8840private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
8841 f_lcs_loc_req_for_active_ms_le_timeout(false);
8842}
8843
8844testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
8845 var MSC_ConnHdlr vc_conn;
8846 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8847
8848 f_init(1, true);
8849 f_sleep(1.0);
8850 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
8851 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008852 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008853}
8854
8855/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
8856 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
8857private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
8858 f_lcs_loc_req_for_active_ms_le_timeout(true);
8859}
8860
8861testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
8862 var MSC_ConnHdlr vc_conn;
8863 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8864
8865 f_init(1, true);
8866 f_sleep(1.0);
8867 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
8868 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008869 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008870}
8871
8872/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
8873private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
8874 f_sleep(1.0);
8875
8876 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8877 f_bssap_le_register_imsi(g_pars.imsi, omit);
8878
8879 /* Register to receive the Paging Command */
8880 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8881 g_chan_nr := new_chan_nr;
8882 f_rslem_register(0, g_chan_nr);
8883
8884 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8885 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8886 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8887 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8888
8889 var PDU_BSSAP_LE plr;
8890 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8891
8892 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8893 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8894
8895 /* OsmoBSC needs to Page */
8896 var PDU_BSSAP_LE rx_bsslap;
8897 alt {
8898 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
8899 f_logp(BSCVTY, "got Paging Command");
8900 repeat;
8901 }
8902 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
8903 /* MS does not respond to Paging, TA Req runs into timeout. */
8904 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
8905 }
8906 }
8907
8908 /* SMLC responds with failure */
8909 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
8910 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8911
8912 /* BSC tells MSC about failure */
8913 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
8914 locationEstimate := omit, positioningData := omit,
8915 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
8916
8917 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
8918 f_verify_active_A_conn_and_clear();
8919
8920 f_sleep(2.0);
8921 setverdict(pass);
8922}
8923testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
8924 var MSC_ConnHdlr vc_conn;
8925 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8926
8927 f_init(1, true);
8928 f_sleep(1.0);
8929
8930 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8931 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8932
8933 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
8934 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008935 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008936}
8937
8938/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
8939 * over. */
8940private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
8941 f_sleep(1.0);
8942
8943 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8944 f_bssap_le_register_imsi(g_pars.imsi, omit);
8945
8946 /* Register to receive the Paging Command */
8947 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8948 g_chan_nr := new_chan_nr;
8949 f_rslem_register(0, g_chan_nr);
8950
8951 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
8952 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8953 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
8954 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
8955
8956 var PDU_BSSAP_LE plr;
8957 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8958
8959 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
8960 * and establish Layer 3. It should use the existing A-interface conn. */
8961 f_perform_compl_l3(RSL, valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV(g_pars.imsi)))),
8962 do_clear := false, expect_bssmap_l3 := true);
8963
8964 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8965 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8966
8967 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
8968 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8969
8970 /* SMLC got the TA from the BSC, now responds with geo information data. */
8971 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8972 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8973 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8974
8975 /* The lchan should still exist, it was from a CM Service Request. */
8976 f_mo_l3_transceive();
8977
8978 f_perform_clear(RSL);
8979
8980 f_sleep(2.0);
8981 setverdict(pass);
8982}
8983testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
8984 var MSC_ConnHdlr vc_conn;
8985 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8986
8987 f_init(1, true);
8988 f_sleep(1.0);
8989
8990 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
8991 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
8992
8993 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
8994 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008995 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008996}
8997
8998/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
8999 * the new lchan after handover. */
9000private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9001 f_sleep(1.0);
9002
9003 f_establish_fully(omit, omit);
9004 f_bssap_le_register_imsi(g_pars.imsi, omit);
9005
9006 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9007 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9008
9009 var PDU_BSSAP_LE plr;
9010 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9011
9012 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9013 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9014
9015 var HandoverState hs := {
9016 rr_ho_cmpl_seen := false,
9017 handover_done := false,
9018 old_chan_nr := -
9019 };
9020 /* issue hand-over command on VTY */
9021 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9022 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9023 f_rslem_suspend(RSL1_PROC);
9024
9025 /* From the MGW perspective, a handover is is characterized by
9026 * performing one MDCX operation with the MGW. So we expect to see
9027 * one more MDCX during handover. */
9028 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9029
9030 alt {
9031 [] as_handover(hs);
9032 }
9033
9034 var PDU_BSSAP_LE rx_bsslap;
9035
9036 interleave {
9037 /* Expect the BSC to inform the MSC about the handover */
9038 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9039
9040 /* Expect the BSC to inform the SMLC about the handover */
9041 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9042 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9043 }
9044 }
9045
9046 /* SMLC now responds with geo information data. */
9047 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9048 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9049 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9050
9051 /* lchan still active */
9052 f_mo_l3_transceive(RSL1);
9053
9054 /* MSC decides it is done now. */
9055 f_perform_clear(RSL1);
9056
9057 f_sleep(2.0);
9058 setverdict(pass);
9059}
9060testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9061 var MSC_ConnHdlr vc_conn;
9062 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9063
9064 f_init(2, true);
9065 f_sleep(1.0);
9066 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9067 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009068 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009069}
9070
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009071/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9072private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9073 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9074
9075 /* Also disable attach for the single connected MSC */
9076 f_vty_msc_allow_attach(BSCVTY, { false });
9077
9078 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) ));
9079 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9080
9081 /* No MSC is found, expecting a proper release on RSL */
9082 interleave {
9083 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9084 f_logp(BSCVTY, "Got RSL RR Release");
9085 }
9086 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9087 f_logp(BSCVTY, "Got RSL Deact SACCH");
9088 }
9089 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
9090 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9091 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
9092 }
9093 }
9094 setverdict(pass);
9095}
9096testcase TC_no_msc() runs on test_CT {
9097
9098 f_init(1, true);
9099 f_sleep(1.0);
9100 var MSC_ConnHdlr vc_conn;
9101 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9102
9103 f_ctrs_bsc_init(counternames_bsc_mscpool);
9104
9105 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9106 vc_conn.done;
9107
9108 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9109 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009110 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009111}
9112
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009113/* Dyn PDCH todo:
9114 * activate OSMO as TCH/F
9115 * activate OSMO as TCH/H
9116 * does the BSC-located PCU socket get the updated INFO?
9117 * what if no PCU is connected at the time?
9118 * is the info correct on delayed PCU (re)connect?
9119 */
Harald Welte94e0c342018-04-07 11:33:23 +02009120
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009121private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9122 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9123 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9124
9125 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9126 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9127 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9128 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9129 g_pars.ass_codec_list.codecElements[0];
9130 if (isvalue(g_pars.expect_mr_s0_s7)) {
9131 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9132 g_pars.expect_mr_s0_s7;
9133 }
9134 }
9135 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9136 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9137 log("expecting ASS COMPL like this: ", exp_compl);
9138
9139 f_establish_fully(ass_cmd, exp_compl);
9140
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009141 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 +00009142
9143 var RSL_Message rsl;
9144
9145 timer T := 5.0;
9146 T.start;
9147 alt {
9148 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9149 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9150 log("Rx L3 from net: ", l3);
9151 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9152 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9153 mtc.stop;
9154 }
9155 }
9156 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9157 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9158 mtc.stop;
9159 }
9160 [] T.timeout {
9161 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9162 setverdict(pass);
9163 }
9164 }
9165 T.stop;
9166}
9167
9168/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9169 * osmo-bsc. */
9170testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9171 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9172 var MSC_ConnHdlr vc_conn;
9173
9174 f_init(1, true);
9175 f_sleep(1.0);
9176
9177 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9178 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9179 vc_conn.done;
9180 f_shutdown_helper();
9181}
9182
9183/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9184 */
9185testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9186 f_init_vty();
9187
9188 f_init(1, false);
9189 f_sleep(1.0);
9190
9191 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9192
9193 var ASP_RSL_Unitdata rx_rsl_ud;
9194 timer T := 5.0;
9195
9196 T.start;
9197 alt {
9198 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9199 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9200 T.stop;
9201 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9202 mtc.stop;
9203 }
9204 repeat;
9205 }
9206 [] T.timeout {
9207 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9208 setverdict(pass);
9209 }
9210 }
9211}
9212
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009213private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9214 /* First fully set up a speech lchan */
9215 f_TC_assignment_codec(id);
9216
9217 /* Trigger re-assignment to another lchan */
9218 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9219
9220 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9221 * one MDCX on MGCP. */
9222 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9223
9224 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9225 * as the old lchan used. */
9226 g_media.bts.ipa_crcx_seen := false;
9227 g_media.bts.ipa_mdcx_seen := false;
9228
9229 /* Send different BTS side RTP port number for the new lchan */
9230 g_media.bts.bts.port_nr := 4223;
9231
9232 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9233
9234 /* Trigger re-assignment. */
9235 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9236
9237 timer T := 5.0;
9238 T.start;
9239 alt {
9240 [] as_assignment(assignment_st);
9241 [] as_Media();
9242 [] T.timeout {
9243 break;
9244 }
9245 }
9246
9247 if (not assignment_st.assignment_done) {
9248 setverdict(fail, "Assignment did not complete");
9249 mtc.stop;
9250 }
9251
9252 f_check_mgcp_expectations()
9253 setverdict(pass);
9254
9255 f_sleep(2.0);
9256 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9257
9258 /* Instruct BSC to clear channel */
9259 var BssmapCause cause := 0;
9260 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9261 interleave {
9262 [] MGCP.receive(tr_DLCX) {}
9263 [] MGCP.receive(tr_DLCX) {}
9264 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9265 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
9266 [] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
9267 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
9268 }
9269 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9270 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9271 }
9272 }
9273
9274 f_sleep(0.5);
9275}
9276
9277testcase TC_reassignment_fr() runs on test_CT {
9278 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9279 var MSC_ConnHdlr vc_conn;
9280
9281 f_init(1, true);
9282 f_sleep(1.0);
9283
9284 f_ctrs_bsc_and_bts_init();
9285
9286 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9287 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9288 vc_conn.done;
9289
9290 /* from f_establish_fully() */
9291 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9292 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9293 /* from re-assignment */
9294 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9295 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9296 f_ctrs_bsc_and_bts_verify();
9297 f_shutdown_helper();
9298}
9299
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009300
Harald Welte28d943e2017-11-25 15:00:50 +01009301control {
Harald Welte898113b2018-01-31 18:32:21 +01009302 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +01009303 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01009304 execute( TC_ctrl_msc0_connection_status() );
Harald Welte96c94412017-12-09 03:12:45 +01009305 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +02009306 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02009307 execute( TC_ctrl_location() );
9308 }
Harald Welte898113b2018-01-31 18:32:21 +01009309
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02009310 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02009311 execute( TC_si2quater_2_earfcns() );
9312 execute( TC_si2quater_3_earfcns() );
9313 execute( TC_si2quater_4_earfcns() );
9314 execute( TC_si2quater_5_earfcns() );
9315 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +02009316 execute( TC_si2quater_12_earfcns() );
9317 execute( TC_si2quater_23_earfcns() );
9318 execute( TC_si2quater_32_earfcns() );
9319 execute( TC_si2quater_33_earfcns() );
9320 execute( TC_si2quater_42_earfcns() );
9321 execute( TC_si2quater_48_earfcns() );
9322 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02009323 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +02009324 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02009325
Harald Welte898113b2018-01-31 18:32:21 +01009326 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +01009327 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +01009328 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +01009329 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +02009330 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +02009331 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +01009332 execute( TC_chan_act_ack_est_ind_noreply() );
9333 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +01009334 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +01009335 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07009336 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +01009337 execute( TC_chan_rel_rll_rel_ind() );
9338 execute( TC_chan_rel_conn_fail() );
9339 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02009340 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
9341 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +01009342 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +01009343 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +02009344 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +01009345 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01009346 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02009347 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +01009348
Harald Weltecfe2c962017-12-15 12:09:32 +01009349 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +01009350
9351 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +01009352 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +01009353 execute( TC_assignment_csd() );
9354 execute( TC_assignment_ctm() );
9355 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +02009356 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9357 execute( TC_assignment_aoip_tla_v6() );
9358 }
Harald Welte235ebf12017-12-15 14:18:16 +01009359 execute( TC_assignment_fr_a5_0() );
9360 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +02009361 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +02009362 execute( TC_assignment_fr_a5_1_codec_missing() );
9363 }
Harald Welte235ebf12017-12-15 14:18:16 +01009364 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02009365 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02009366 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02009367 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +02009368 execute( TC_ciph_mode_a5_0() );
9369 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +02009370 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +02009371 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +02009372 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02009373 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +01009374
Harald Welte60aa5762018-03-21 19:33:13 +01009375 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02009376 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +01009377 execute( TC_assignment_codec_hr() );
9378 execute( TC_assignment_codec_efr() );
9379 execute( TC_assignment_codec_amr_f() );
9380 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +01009381
Neels Hofmeyrf246a922020-05-13 02:27:10 +02009382 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +01009383 execute( TC_assignment_codec_amr_f_S1() );
9384 execute( TC_assignment_codec_amr_h_S1() );
9385 execute( TC_assignment_codec_amr_f_S124() );
9386 execute( TC_assignment_codec_amr_h_S124() );
9387 execute( TC_assignment_codec_amr_f_S0() );
9388 execute( TC_assignment_codec_amr_f_S02() );
9389 execute( TC_assignment_codec_amr_f_S024() );
9390 execute( TC_assignment_codec_amr_f_S0247() );
9391 execute( TC_assignment_codec_amr_h_S0() );
9392 execute( TC_assignment_codec_amr_h_S02() );
9393 execute( TC_assignment_codec_amr_h_S024() );
9394 execute( TC_assignment_codec_amr_h_S0247() );
9395 execute( TC_assignment_codec_amr_f_S01234567() );
9396 execute( TC_assignment_codec_amr_f_S0234567() );
9397 execute( TC_assignment_codec_amr_f_zero() );
9398 execute( TC_assignment_codec_amr_f_unsupp() );
9399 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +00009400 execute( TC_assignment_codec_amr_f_start_mode_auto() );
9401 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00009402 execute( TC_assignment_codec_amr_f_start_mode_4() );
9403 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +00009404 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +01009405 }
Harald Welte60aa5762018-03-21 19:33:13 +01009406
Philipp Maierac09bfc2019-01-08 13:41:39 +01009407 execute( TC_assignment_codec_fr_exhausted_req_hr() );
9408 execute( TC_assignment_codec_fr_exhausted_req_fr() );
9409 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
9410 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
9411 execute( TC_assignment_codec_hr_exhausted_req_fr() );
9412 execute( TC_assignment_codec_hr_exhausted_req_hr() );
9413 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
9414 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
9415 execute( TC_assignment_codec_req_hr_fr() );
9416 execute( TC_assignment_codec_req_fr_hr() );
9417
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +02009418 if (mp_enable_osmux_test) {
9419 execute( TC_assignment_osmux() );
9420 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02009421
Harald Welte898113b2018-01-31 18:32:21 +01009422 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +01009423 execute( TC_rll_est_ind_inact_lchan() );
9424 execute( TC_rll_est_ind_inval_sapi1() );
9425 execute( TC_rll_est_ind_inval_sapi3() );
9426 execute( TC_rll_est_ind_inval_sacch() );
9427
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07009428 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
9429 execute( TC_tch_dlci_link_id_sapi() );
9430
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07009431 /* SAPI N Reject triggered by RLL establishment failures */
9432 execute( TC_rll_rel_ind_sapi_n_reject() );
9433 execute( TC_rll_err_ind_sapi_n_reject() );
9434 execute( TC_rll_timeout_sapi_n_reject() );
9435
Harald Welte898113b2018-01-31 18:32:21 +01009436 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +01009437 execute( TC_paging_imsi_nochan() );
9438 execute( TC_paging_tmsi_nochan() );
9439 execute( TC_paging_tmsi_any() );
9440 execute( TC_paging_tmsi_sdcch() );
9441 execute( TC_paging_tmsi_tch_f() );
9442 execute( TC_paging_tmsi_tch_hf() );
9443 execute( TC_paging_imsi_nochan_cgi() );
9444 execute( TC_paging_imsi_nochan_lac_ci() );
9445 execute( TC_paging_imsi_nochan_ci() );
9446 execute( TC_paging_imsi_nochan_lai() );
9447 execute( TC_paging_imsi_nochan_lac() );
9448 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +01009449 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
9450 execute( TC_paging_imsi_nochan_rnc() );
9451 execute( TC_paging_imsi_nochan_lac_rnc() );
9452 execute( TC_paging_imsi_nochan_lacs() );
9453 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +01009454 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +01009455 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +01009456 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +01009457 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01009458 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +01009459
9460 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +01009461 execute( TC_rsl_unknown_unit_id() );
9462
9463 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +01009464
9465 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +02009466 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +01009467 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +01009468 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +01009469 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +01009470 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +01009471 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01009472
Harald Welte261af4b2018-02-12 21:20:39 +01009473 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02009474 execute( TC_ho_int_a5_0() );
9475 execute( TC_ho_int_a5_1() );
9476 execute( TC_ho_int_a5_3() );
9477 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +00009478 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01009479
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01009480 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02009481 execute( TC_ho_out_fail_no_msc_response() );
9482 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02009483 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01009484
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01009485 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02009486 execute( TC_ho_into_this_bsc_a5_0() );
9487 execute( TC_ho_into_this_bsc_a5_1() );
9488 execute( TC_ho_into_this_bsc_a5_3() );
9489 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +02009490 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9491 execute( TC_ho_into_this_bsc_tla_v6() );
9492 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02009493 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02009494 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02009495 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
9496 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01009497 execute( TC_ho_in_fail_msc_clears() );
9498 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
9499 execute( TC_ho_in_fail_no_detect() );
9500 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01009501
Neels Hofmeyr91401012019-07-11 00:42:35 +02009502 execute( TC_ho_neighbor_config_1() );
9503 execute( TC_ho_neighbor_config_2() );
9504 execute( TC_ho_neighbor_config_3() );
9505 execute( TC_ho_neighbor_config_4() );
9506 execute( TC_ho_neighbor_config_5() );
9507 execute( TC_ho_neighbor_config_6() );
9508 execute( TC_ho_neighbor_config_7() );
9509
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01009510 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01009511 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01009512 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +02009513
9514 execute( TC_dyn_pdch_ipa_act_deact() );
9515 execute( TC_dyn_pdch_ipa_act_nack() );
9516 execute( TC_dyn_pdch_osmo_act_deact() );
9517 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +02009518 if (mp_enable_dyn_sdcch8_test) {
9519 execute( TC_dyn_ts_sdcch8_act_deact() );
9520 execute (TC_dyn_ts_sdcch8_tch_call_act_deact() );
9521 execute( TC_dyn_ts_sdcch8_act_nack() );
9522 }
Harald Welte99f3ca02018-06-14 13:40:29 +02009523
Stefan Sperling0796a822018-10-05 13:01:39 +02009524 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02009525 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +02009526
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01009527 /* Power control related */
9528 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02009529 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02009530
9531 /* MSC pooling */
9532 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
9533 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
9534 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
9535 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
9536 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9537 execute( TC_mscpool_L3Compl_on_1_msc() );
9538 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
9539 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
9540 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
9541 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
9542 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
9543 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
9544 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
9545 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
9546 execute( TC_mscpool_paging_and_response_imsi() );
9547 execute( TC_mscpool_paging_and_response_tmsi() );
9548 execute( TC_mscpool_no_allow_attach_round_robin() );
9549 execute( TC_mscpool_no_allow_attach_valid_nri() );
9550 }
9551
Harald Welte99f3ca02018-06-14 13:40:29 +02009552 /* at bottom as they might crash OsmoBSC before OS#3182 is fixed */
9553 execute( TC_early_conn_fail() );
9554 execute( TC_late_conn_fail() );
9555
Philipp Maier783681c2020-07-16 16:47:06 +02009556 /* Emergency call handling (deny / allow) */
9557 execute( TC_assignment_emerg_setup_allow() );
9558 execute( TC_assignment_emerg_setup_deny_msc() );
9559 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +02009560 execute( TC_emerg_premption() );
9561
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009562 /* Frequency hopping parameters handling */
9563 execute( TC_fh_params_chan_activ() );
9564 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009565 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009566 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009567 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009568
9569 if (mp_enable_lcs_tests) {
9570 execute( TC_lcs_loc_req_for_active_ms() );
9571 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
9572 execute( TC_lcs_loc_req_for_idle_ms() );
9573 execute( TC_lcs_loc_req_no_subscriber() );
9574 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
9575 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
9576 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
9577 execute( TC_cm_service_during_lcs_loc_req() );
9578 execute( TC_ho_during_lcs_loc_req() );
9579 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009580
9581 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009582
9583 execute( TC_refuse_chan_act_to_vamos() );
9584 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009585
9586 execute( TC_reassignment_fr() );
Harald Welte28d943e2017-11-25 15:00:50 +01009587}
9588
9589}